文章內(nèi)容:
??? STM32 HAL庫通過串口發(fā)送AT指令完成與ESP8266的控制實(shí)現(xiàn)接入華為云物聯(lián)網(wǎng)平臺(tái),并完成基本通信與控制,包括設(shè)備屬性上報(bào)和命令下發(fā)解析與響應(yīng)。
????文末獲取“STM32 HAL庫+ESP8266+華為云物聯(lián)網(wǎng)平臺(tái)keil工程”下載的鏈接。
一、華為云物聯(lián)網(wǎng)平臺(tái)創(chuàng)建產(chǎn)品與設(shè)備
華為云物聯(lián)網(wǎng)平臺(tái)創(chuàng)建產(chǎn)品與設(shè)備(含MQTT.fx測(cè)試)
二、STM32 HAL庫+ESP8266+華為云物聯(lián)網(wǎng)平臺(tái)
1. esp8266 MQTT固件燒錄與AT指令接入華為云測(cè)試
(5條消息) ESP8266通過AT指令接入華為云物聯(lián)網(wǎng)平臺(tái)_FUNIOT的博客-CSDN博客
三、STM32 HAL庫+ESP8266+華為云物聯(lián)網(wǎng)平臺(tái)
1. 打開STM32CubeMX創(chuàng)建工程
(1)配置串口與LED的GPIO(LED用于華為云命令下發(fā)控制)
(2)打開串口并使能串口中斷
2. 打開工程,編譯,下載,檢查無誤
3. 串口收發(fā)
1) 添加頭文件:
#include <stdio.h>
#include <string.h>
2) printf重定向
//支持printf函數(shù)串口發(fā)送
#if 1
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)//避免半主機(jī)模式
{
x=x;
}
int fputc(int ch,FILE *f)
{
while((USART1->SR&0X40)==0);//循環(huán)發(fā)送,直到發(fā)送完畢
USART1->DR=(uint8_t)ch;
return ch;
}
#endif
4. 發(fā)送測(cè)試
while (1)//主函數(shù)中插入
{
/* USER CODE END WHILE */
printf("Hello esp8266\r\n");
delay(4000);
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
?
void delay(int t)
???????{
int i,j=0;
for(i=0;i<5000;i++)
for(j=0;j<t;j++);
}
5. 接收測(cè)試
(1)main.c中添加下列聲明
char R_data[1024]; //定義結(jié)束數(shù)據(jù)的緩沖區(qū)
uint8_t R_length=0; //定義結(jié)束數(shù)據(jù)的長(zhǎng)度
uint8_t R_i=0; //由于遍歷緩沖區(qū)數(shù)據(jù)
(2)重寫串口接收中斷回調(diào)函數(shù)
//重寫串口接收中斷回調(diào)函數(shù)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
char analysis_Str[256];
if(huart->Instance == USART1)
{
HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1);
// save char from uart receive
if(aRxBuffer1!='\n')
R_data[R_length++]=aRxBuffer1;
else
for(R_i=0;R_i<R_length;R_i++)
printf("%c",R_data[R_i]);
}
}
(3)在串口初始化后使能串口中斷
HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1); //使能串口接收中斷
(4)運(yùn)行測(cè)試:
6. ?完善主要接入華為云物聯(lián)網(wǎng)平臺(tái)的相關(guān)代碼
(1)接入華為云初始化
void HuaweiIot_init(void)
{
uint8_t i=0;
for(i=0;i<10;i++)
{
if(at_start_flag==1)
{
AT_write("AT\r\n");
printf("AT+RST\r\n");
delay(1000);
AT_write("AT\r\n");
AT_write("AT+CWMODE=1\r\n");
AT_write("AT+CWJAP=\"wifi名稱\",\"wifi密碼\"\r\n");
AT_write("AT+MQTTUSERCFG=0,1,\"NULL\",\"三元組之Username\",\"三元組之password\",0,0,\"\"\r\n");
AT_write("AT+MQTTCLIENTID=0,\"三元組之ClientID\"\r\n");
AT_write("AT+MQTTCONN=0,\"MQTT接入地址\",1883,1\r\n");
AT_write("AT+MQTTSUB=0,\"$oc/devices/設(shè)備ID/sys/properties/report\",1\r\n");
AT_write("AT+MQTTSUB=0,\"$oc/devices/設(shè)備ID/sys/commands/#\",1\r\n");
AT_write("AT+MQTTSUB=0,\"$oc/devices/設(shè)備ID/sys/commands/response/#\",1\r\n");
break;
}
else
{
printf("等待模塊就緒...\r\n");
delay(1000);
}
}
}
?(2) AT命令發(fā)送
void AT_write(char atstring[1024])//阻塞等待OK
{
printf("%s",atstring);
while(1)
{
if(R_data[0]=='O'&&R_data[1]=='K') break;
else if(R_data[0]=='b'&&R_data[1]=='u'&&R_data[2]=='s'&&R_data[3]=='y')
{
}
else delay(50);
}
R_data[0]=R_data[1]=0;
delay(50);
}
(3) 屬性上報(bào)
void HuaweiIot_publish(void)
{
char pubtemp[256];
if(at_start_flag==1)
{
sprintf(pubtemp,"AT+MQTTPUB=0,\"$oc/devices/設(shè)備ID/sys/properties/report\",\"{\\\"services\\\":[{\\\"service_id\\\":\\\"服務(wù)ID\\\"\\,\\\"properties\\\":{\\\"屬性\\\": %d}}]}\",0,0\r\n",hometemp++);
AT_write(pubtemp);
}
}
(4)串口接收中斷回調(diào)
//重寫串口接收中斷回調(diào)函數(shù)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
char analysis_Str[256];
if(huart->Instance == USART1)
{
HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1);
// save char from uart receive
if(aRxBuffer1!='\n')
R_data[R_length++]=aRxBuffer1;
else
{
if(R_length>=5)
{
if(R_data[0]=='r'&&R_data[1]=='e'&&R_data[2]=='a'&&R_data[3]=='d'&&R_data[4]=='y')
{
at_start_flag=1;
printf("檢測(cè)到ready\r\n");
memset(R_data,0,sizeof(R_data));//清空緩存區(qū)
}
}
//我的接收數(shù)據(jù)長(zhǎng)度為201,下面采用JSON字符串硬解析的方式,具體下標(biāo)請(qǐng)根據(jù)自己實(shí)際接收的參數(shù)處理
//+MQTTSUBRECV:0,"$oc/devices/61fb2d7fde9933029be5ff9e_esp8266_test01/sys/commands/request_id=4152fb5d-e5ae-4b89-b39d-283ba59cf033",68,{"paras":{"led":1},"service_id":"Dev_data","command_name":"Control"}
if(R_length>200)
{
strncpy(analysis_Str, R_data, 12);//提取出“+MQTTSUBRECV”
if(strcmp(analysis_Str,"+MQTTSUBRECV")==0)
{
memset(analysis_Str,0,sizeof(analysis_Str));//清空緩存區(qū)
//printf("MQTT命令接收頭正確\r\n");
strncpy(request_id, R_data+92, 36); //提取出request_id
//printf("request_id=%s\r\n",request_id);
strncpy(analysis_Str, R_data+135, 5); //提取出"paras"
//printf("paras=%s\r\n",analysis_Str);
if(strcmp(analysis_Str,"paras")==0) //有效參數(shù)體
{
memset(analysis_Str,0,sizeof(analysis_Str));//清空緩存區(qū)
strncpy(analysis_Str, R_data+144,3); //提取出"led"
//printf("att is %s\r\n",analysis_Str);
if(strcmp(analysis_Str,"led")==0)
{
//printf("led set %c",R_data[149]);
memset(analysis_Str,0,sizeof(analysis_Str));//清空緩存區(qū)
if(R_data[149]=='0')
{
//printf("關(guān)燈\r\n");
printf("AT+MQTTPUB=0,\"$oc/devices/設(shè)備ID/sys/commands/response/request_id=%s\",\"\",0,0\r\n",request_id);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
memset(analysis_Str,0,sizeof(analysis_Str));//清空緩存區(qū)
}
else if(R_data[149]=='1')
{
//printf("開燈\r\n");
printf("AT+MQTTPUB=0,\"$oc/devices/設(shè)備ID/sys/commands/response/request_id=%s\",\"\",0,0\r\n",request_id);
memset(analysis_Str,0,sizeof(analysis_Str));//清空緩存區(qū)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
}
}
}
}
else
{
//printf("MQTT命令接收頭異常:%s\r\n",analysis_Str);
memset(analysis_Str,0,sizeof(analysis_Str));//清空緩存區(qū)
}
}
//else printf("MQTT命令長(zhǎng)度異常,長(zhǎng)度:%d",R_length);
R_length=0;
}
}
}
最終效果:
公眾號(hào)搜索”IOT趣制作“回復(fù)關(guān)鍵字“8266at”或者“0327”獲取相關(guān)下載鏈接:
文章來源:http://www.zghlxwxcb.cn/news/detail-619851.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-619851.html
到了這里,關(guān)于STM32 HAL庫+ESP8266+華為云物聯(lián)網(wǎng)平臺(tái)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!