概述
涂鴉智能 (NYSE:TUYA) 是一家致力于讓生活更智能的領(lǐng)先技術(shù)公司,涂鴉提供能夠智連萬(wàn)物的云平臺(tái),打造互聯(lián)互通的開(kāi)發(fā)標(biāo)準(zhǔn),連接品牌、OEM 廠商、開(kāi)發(fā)者、零售商和各行業(yè)的智能化需求,涂鴉的解決方案賦能并提升合作伙伴和客戶(hù)的產(chǎn)品價(jià)值,同時(shí)通過(guò)技術(shù)應(yīng)用使消費(fèi)者的生活更加便利,涂鴉智能的智慧商業(yè) SaaS 為豐富的垂直行業(yè)提供智能解決方案。涂鴉智能領(lǐng)先業(yè)界的技術(shù),符合嚴(yán)格的數(shù)據(jù)保護(hù)標(biāo)準(zhǔn)和安全性。
壓力傳感器是工業(yè)實(shí)踐中最為常用的一種傳感器,其廣泛應(yīng)用于各種工業(yè)自控環(huán)境,涉及水利水電、鐵路交通、智能建筑、生產(chǎn)自控、航空航天、軍工、石化、油井、電力、船舶、機(jī)床、管道等眾多行業(yè)。
同時(shí)壓力傳感器可以應(yīng)用于電子稱(chēng)重系統(tǒng)或者久坐系統(tǒng),實(shí)現(xiàn)了稱(chēng)重顯示、超限報(bào)警、校準(zhǔn)、適應(yīng)各種工作環(huán)境、遠(yuǎn)程實(shí)時(shí)監(jiān)控等多種功能,可以廣泛應(yīng)用于各種稱(chēng)重場(chǎng)景。
本章主要是配置涂鴉模組進(jìn)行數(shù)據(jù)通信。
? 進(jìn)入IoT商機(jī)孵化營(yíng),獲取開(kāi)發(fā)資料及相關(guān)硬件物料。 ? ? ? ? ? ? ? ? ? ?
? IoT商機(jī)孵化營(yíng): ? ? ??
? https://t.tuya.com/AY1D3R9jFf ? ? ? ? ? ? ? ? ? ? ? ? ??
涂鴉調(diào)試文件下載
在涂鴉平臺(tái)下載資料。
?

涂鴉模塊(BT3L Bluetooth 模組)與串口模塊接線方式。
涂鴉模塊BT3L Bluetooth 模組) | 串口模塊 |
VCC | VCC |
RX | TX |
TX | RX |
GND | GND |
打開(kāi)下載的涂鴉模組調(diào)試助手,進(jìn)行串口調(diào)試。

在這可以查看到通訊協(xié)議(基礎(chǔ)協(xié)議)指令收發(fā)。
?

STM32CUBEMX配置讀取模塊信息
配置串口3讀取涂鴉模塊的數(shù)據(jù)。,由于涂鴉模塊使用的是9600的波特率,故配置為9600。
?

配置DMA進(jìn)行數(shù)據(jù)接收。

開(kāi)啟中斷。

stm32f103與涂鴉接線方式。
開(kāi)發(fā)板 | 涂鴉模塊 |
VCC | VCC |
PB10(TX) | RX |
PB11(RX) | TX |
GND | GND |
讀取代碼配置
/* USER CODE BEGIN PV */
#define BUFFERSIZE 255 //可以接收的最大字符個(gè)數(shù)
uint8_t ReceiveBuff[BUFFERSIZE]; //接收緩沖區(qū)
uint8_t recv_end_flag = 0,Rx_len;//接收完成中斷標(biāo)志,接收到字符長(zhǎng)度
/* USER CODE END PV */
開(kāi)啟串口IDLE中斷。
/* USER CODE BEGIN 2 */
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);//使能串口3 IDLE中斷
HAL_UART_Receive_DMA(&huart3,ReceiveBuff,BUFFERSIZE);//開(kāi)啟DMA接收
/* USER CODE END 2 */
定義接受函數(shù)。
/* USER CODE BEGIN PFP */
void uart3_data(void);
/* USER CODE END PFP */
串口DMA接收數(shù)據(jù),然后通過(guò)串口1進(jìn)行打印數(shù)據(jù)。
/* USER CODE BEGIN 4 */
void uart3_data(void)
{
if(recv_end_flag ==1)//接收完成標(biāo)志
{
HAL_UART_Transmit(&huart1,(uint8_t*)ReceiveBuff,Rx_len,0xFFFF);
for(int i = 0; i < Rx_len ; i++) //清空接收緩存區(qū)
ReceiveBuff[i]=0;//置0
Rx_len=0;//接收數(shù)據(jù)長(zhǎng)度清零
recv_end_flag=0;//接收標(biāo)志位清零
//開(kāi)啟下一次接收
HAL_UART_Receive_DMA(&huart3,(uint8_t*)ReceiveBuff,BUFFERSIZE);
}
}
/* USER CODE END 4 */
#include "stm32f1xx_it.c"文件中斷外部變量引用。
/* USER CODE BEGIN 0 */
#define BUFFERSIZE 255 //可接收的最大數(shù)據(jù)量
extern uint8_t recv_end_flag,Rx_len,bootfirst;
/* USER CODE END 0 */
串口3中斷函數(shù)。
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */
uint32_t temp;
if(USART3 == huart3.Instance)//判斷是否為串口3中斷
{
if(RESET != __HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE))//如果為串口3
{
__HAL_UART_CLEAR_IDLEFLAG(&huart3);//清除中斷標(biāo)志
HAL_UART_DMAStop(&huart3);//停止DMA接收
temp = __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);//獲取DMA當(dāng)前還有多少未填充
Rx_len = BUFFERSIZE - temp; //計(jì)算串口接收到的數(shù)據(jù)個(gè)數(shù)
recv_end_flag = 1;
}
}
/* USER CODE END USART3_IRQn 1 */
}
串口打印數(shù)據(jù)實(shí)例

匹配心跳檢測(cè)通信協(xié)議
以心跳檢測(cè)為例子,當(dāng)涂鴉模塊發(fā)送心跳檢測(cè)給MCU時(shí)候,需要MCU上報(bào)信息給涂鴉模塊,同時(shí)心跳檢測(cè)數(shù)據(jù)第一次發(fā)送0x00,第二次發(fā)送0x01。

由于心跳檢測(cè)發(fā)送的數(shù)據(jù)是固定的,故需要定義2個(gè)數(shù)組用來(lái)存放。
/* USER CODE BEGIN PV */
uint8_t wifi_first =0;//第一次開(kāi)啟 發(fā)送00 第二次發(fā)送01
const uint8_t Buff1[8]={0x55,0xAA,0x00,0x00,0x00,0x01,0x00,0x00};//心跳檢測(cè),第1次 0x55 aa 00 00 00 01 00 03
const uint8_t Buff2[8]={0x55,0xAA,0x00,0x00,0x00,0x01,0x01,0x01};//心跳檢測(cè),第2次 0x55 aa 00 00 00 01 01 04
/* USER CODE END PV */
在之前的uart3_data()函數(shù)中添加檢測(cè)代碼,通過(guò)判斷接收的數(shù)據(jù)來(lái)判斷模塊發(fā)送過(guò)來(lái)的指令。
void uart3_data(void)
{
if(recv_end_flag ==1)//接收完成標(biāo)志
{
HAL_UART_Transmit(&huart1,(uint8_t*)ReceiveBuff,Rx_len,0xFFFF);//向串口發(fā)送接收到的數(shù)據(jù)
if(ReceiveBuff[0]==0x55&&ReceiveBuff[1]==0xAA)//判斷幀頭和版本
{
if(ReceiveBuff[3]==0x00)//判斷是否為心跳檢測(cè)
{
if(wifi_first==0)//第一次發(fā)送心跳數(shù)據(jù)
{
wifi_first=1;
HAL_UART_Transmit(&huart3,(uint8_t*)Buff1,8,0xFFFF); //心跳檢測(cè),向涂鴉模塊發(fā)送
HAL_UART_Transmit(&huart1,(uint8_t*)Buff1,8,0xFFFF); //心跳檢測(cè),向串口發(fā)送,方便查看數(shù)據(jù)
}
else
{
HAL_UART_Transmit(&huart3,(uint8_t*)Buff2,8,0xFFFF); //心跳檢測(cè),向涂鴉模塊發(fā)送
HAL_UART_Transmit(&huart1,(uint8_t*)Buff2,8,0xFFFF); //心跳檢測(cè),向串口發(fā)送,方便查看數(shù)據(jù)
}
}
}
for(int i = 0; i < Rx_len ; i++) //清空接收緩存區(qū)
ReceiveBuff[i]=0;//置0
Rx_len=0;//接收數(shù)據(jù)長(zhǎng)度清零
recv_end_flag=0;//接收標(biāo)志位清零
//開(kāi)啟下一次接收
HAL_UART_Receive_DMA(&huart3,(uint8_t*)ReceiveBuff,BUFFERSIZE);
}
}
查看串口接收到的數(shù)據(jù),可以看到心跳數(shù)據(jù)已經(jīng)正常接收。

匹配查詢(xún)MCU的版本號(hào)通信協(xié)議
同時(shí)可以看到,接收的數(shù)據(jù)中,夾著一個(gè)55 AA 00 E8 00 00 E7的數(shù)據(jù)。
通過(guò)查詢(xún)文檔,可以知道該指令是查詢(xún)MCU的版本號(hào)。
?
在涂鴉模塊調(diào)試助手中可以查看到該指令的通信協(xié)議。

由于MCU版本號(hào)為1.0.2和硬件版本號(hào)1.0.3,故需用2個(gè)數(shù)組進(jìn)行存放該版本號(hào),同時(shí)定義一個(gè)接收模塊發(fā)送的查詢(xún)MCU版本信息請(qǐng)求數(shù)組。
/* USER CODE BEGIN PV */
uint8_t mcu_version[3]={1,0,2};
uint8_t hardware_version[3]={1,0,3};
uint8_t Buff3[13]={0x55,0xAA,0x00,0xE8,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//接收模塊發(fā)送的查詢(xún)MCU版本信息請(qǐng)求
/* USER CODE END PV */
在之前的uart3_data()函數(shù)中添加檢測(cè)代碼,通過(guò)判斷接收的數(shù)據(jù)來(lái)判斷模塊發(fā)送過(guò)來(lái)的指令。
void uart3_data(void)
{
if(recv_end_flag ==1)//接收完成標(biāo)志
{
HAL_UART_Transmit(&huart1,(uint8_t*)ReceiveBuff,Rx_len,0xFFFF);//向串口發(fā)送接收到的數(shù)據(jù)
if(ReceiveBuff[0]==0x55&&ReceiveBuff[1]==0xAA)//判斷幀頭和版本
{
if(ReceiveBuff[3]==0x00)//判斷是否為心跳檢測(cè)
{
if(wifi_first==0)//第一次發(fā)送心跳數(shù)據(jù)
{
wifi_first=1;
HAL_UART_Transmit(&huart3,(uint8_t*)Buff1,8,0xFFFF); //心跳檢測(cè),向涂鴉模塊發(fā)送
HAL_UART_Transmit(&huart1,(uint8_t*)Buff1,8,0xFFFF); //心跳檢測(cè),向串口發(fā)送,方便查看數(shù)據(jù)
}
else
{
HAL_UART_Transmit(&huart3,(uint8_t*)Buff2,8,0xFFFF); //心跳檢測(cè),向涂鴉模塊發(fā)送
HAL_UART_Transmit(&huart1,(uint8_t*)Buff2,8,0xFFFF); //心跳檢測(cè),向串口發(fā)送,方便查看數(shù)據(jù)
}
}
else if(ReceiveBuff[3]==0xE8)//判斷是否為接收模塊發(fā)送的查詢(xún)MCU版本信息請(qǐng)求
{
for(int i=0;i<3;i++)
{
Buff3[6+i]=mcu_version[i];//將mcu版本放入數(shù)組中
Buff3[9+i]=hardware_version[i];//將硬件版本放入數(shù)組中
}
Buff3[12]=0;
for(int i=0;i<12;i++)//計(jì)算校驗(yàn)和
{
Buff3[12]=Buff3[12]+Buff3[i];
}
HAL_UART_Transmit(&huart3,(uint8_t*)Buff3,13,0xFFFF); //接收模塊發(fā)送的查詢(xún)MCU版本信息請(qǐng)求,向涂鴉模塊發(fā)送
HAL_UART_Transmit(&huart1,(uint8_t*)Buff3,13,0xFFFF); //接收模塊發(fā)送的查詢(xún)MCU版本信息請(qǐng)求,向串口發(fā)送,方便查看數(shù)據(jù)
}
}
for(int i = 0; i < Rx_len ; i++) //清空接收緩存區(qū)
ReceiveBuff[i]=0;//置0
Rx_len=0;//接收數(shù)據(jù)長(zhǎng)度清零
recv_end_flag=0;//接收標(biāo)志位清零
//開(kāi)啟下一次接收
HAL_UART_Receive_DMA(&huart3,(uint8_t*)ReceiveBuff,BUFFERSIZE);
}
}
查看串口接收到的數(shù)據(jù),可以看到查詢(xún)MCU版本信息請(qǐng)求已經(jīng)發(fā)送完畢。
?

匹配查詢(xún)產(chǎn)品信息請(qǐng)求通信協(xié)議
同時(shí)可以看到,接收的數(shù)據(jù)中,夾著一個(gè)55 AA 00 01 00 00 00 的數(shù)據(jù)。
通過(guò)查詢(xún)文檔,可以知道該指令是查詢(xún)產(chǎn)品信息請(qǐng)求。
?

故需要定義pid和初始化發(fā)送的數(shù)組,后期再將pid和mcu版本號(hào)放入數(shù)組中。
char pid[]="qhaft0y9";
uint8_t mcu_version[3]={1,0,2};
uint8_t Buff4[20]={0x55,0xAA,0x00,0x01,0x00,0x0D,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x2E,0x00,0x2E,0x00,0x00};//接收模塊發(fā)送的查詢(xún)產(chǎn)品信息請(qǐng)求
/* USER CODE END PV */
由于有時(shí)候模塊會(huì)連著發(fā)幾條指令過(guò)來(lái),故需要對(duì)指令進(jìn)行切割,然后逐條返回。
/* USER CODE BEGIN 4 */
void uart3_data(void)
{
if(recv_end_flag ==1)//接收完成標(biāo)志
{
HAL_UART_Transmit(&huart1,(uint8_t*)ReceiveBuff,Rx_len,0xFFFF);//向串口發(fā)送接收到的數(shù)據(jù)
uint8_t Rx_flag=0;//接收數(shù)據(jù)的指令數(shù)
uint8_t RX_BUFF_flag[BUFFERSIZE];
if(Rx_len>=4)
{
for(int i1=0;i11.0.2
Buff4[14]=mcu_version[0]+0x30;
Buff4[16]=mcu_version[1]+0x30;
Buff4[18]=mcu_version[2]+0x30;
Buff4[19]=0;//校驗(yàn)和清理
for(int i=0;i<19;i++)//計(jì)算校驗(yàn)和
{
Buff4[19]=Buff4[19]+Buff4[i];
}
HAL_UART_Transmit(&huart3,(uint8_t*)Buff4,20,0xFFFF); //心跳檢測(cè),向涂鴉模塊發(fā)送
HAL_UART_Transmit(&huart1,(uint8_t*)Buff4,20,0xFFFF); //心跳檢測(cè),向涂鴉模塊發(fā)送
}
else if(RX_BUFF[3]==0xE8)//判斷是否為接收模塊發(fā)送的查詢(xún)MCU版本信息請(qǐng)求
{
for(int i=0;i<3;i++)
{
Buff3[6+i]=mcu_version[i];//將mcu版本放入數(shù)組中
Buff3[9+i]=hardware_version[i];//將硬件版本放入數(shù)組中
}
Buff3[12]=0;
for(int i=0;i<12;i++)//計(jì)算校驗(yàn)和
{
Buff3[12]=Buff3[12]+Buff3[i];
}
HAL_UART_Transmit(&huart3,(uint8_t*)Buff3,13,0xFFFF); //接收模塊發(fā)送的查詢(xún)MCU版本信息請(qǐng)求,向涂鴉模塊發(fā)送
HAL_UART_Transmit(&huart1,(uint8_t*)Buff3,13,0xFFFF); //接收模塊發(fā)送的查詢(xún)MCU版本信息請(qǐng)求,向串口發(fā)送,方便查看數(shù)據(jù)
}
}
memset(RX_BUFF, 0,BUFFERSIZE); //清空數(shù)組
if(Tx_flag
手機(jī)連接涂鴉
在寫(xiě)完涂鴉模塊的通訊協(xié)議(基礎(chǔ)協(xié)議)之后,打開(kāi)手機(jī)中的涂鴉智能,點(diǎn)擊添加設(shè)備,然后APP會(huì)自動(dòng)掃描出設(shè)備。
?

或者在右邊的設(shè)備中尋找到對(duì)應(yīng)的設(shè)備進(jìn)行添加。

點(diǎn)擊進(jìn)入后就可以進(jìn)行設(shè)備添加。

選擇需要添加的設(shè)備。

添加成功后界面如下所示。

添加成功后,就可以進(jìn)入該傳感器的實(shí)際界面。

審核編輯:符乾江
評(píng)論