文章内容:
STM32 HAL库通过串口发送AT指令完成与ESP8266的控制实现接入华为云物联网平台,并完成基本通信与控制,包括设备属性上报和命令下发解析与响应。
文末获取“STM32 HAL库+ESP8266+华为云物联网平台keil工程”下载的链接。
一、华为云物联网平台创建产品与设备
华为云物联网平台创建产品与设备(含MQTT.fx测试)
二、STM32 HAL库+ESP8266+华为云物联网平台
1. esp8266 MQTT固件烧录与AT指令接入华为云测试
(5条消息) ESP8266通过AT指令接入华为云物联网平台_FUNIOT的博客-CSDN博客
三、STM32 HAL库+ESP8266+华为云物联网平台
1. 打开STM32CubeMX创建工程
(1)配置串口与LED的GPIO(LED用于华为云命令下发控制)
(2)打开串口并使能串口中断
2. 打开工程,编译,下载,检查无误
3. 串口收发
1) 添加头文件:
#include <stdio.h>
#include <string.h>
2) printf重定向
//支持printf函数串口发送
#if 1
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)//避免半主机模式
{
x=x;
}
int fputc(int ch,FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR=(uint8_t)ch;
return ch;
}
#endif
4. 发送测试
while (1)//主函数中插入
{
/* 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. 接收测试
(1)main.c中添加下列声明
char R_data[1024]; //定义结束数据的缓冲区
uint8_t R_length=0; //定义结束数据的长度
uint8_t R_i=0; //由于遍历缓冲区数据
(2)重写串口接收中断回调函数
//重写串口接收中断回调函数
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)运行测试:
6. 完善主要接入华为云物联网平台的相关代码
(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/设备ID/sys/properties/report\",1\r\n");
AT_write("AT+MQTTSUB=0,\"$oc/devices/设备ID/sys/commands/#\",1\r\n");
AT_write("AT+MQTTSUB=0,\"$oc/devices/设备ID/sys/commands/response/#\",1\r\n");
break;
}
else
{
printf("等待模块就绪...\r\n");
delay(1000);
}
}
}
(2) AT命令发送
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) 属性上报
void HuaweiIot_publish(void)
{
char pubtemp[256];
if(at_start_flag==1)
{
sprintf(pubtemp,"AT+MQTTPUB=0,\"$oc/devices/设备ID/sys/properties/report\",\"{\\\"services\\\":[{\\\"service_id\\\":\\\"服务ID\\\"\\,\\\"properties\\\":{\\\"属性\\\": %d}}]}\",0,0\r\n",hometemp++);
AT_write(pubtemp);
}
}
(4)串口接收中断回调
//重写串口接收中断回调函数
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("检测到ready\r\n");
memset(R_data,0,sizeof(R_data));//清空缓存区
}
}
//我的接收数据长度为201,下面采用JSON字符串硬解析的方式,具体下标请根据自己实际接收的参数处理
//+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));//清空缓存区
//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) //有效参数体
{
memset(analysis_Str,0,sizeof(analysis_Str));//清空缓存区
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));//清空缓存区
if(R_data[149]=='0')
{
//printf("关灯\r\n");
printf("AT+MQTTPUB=0,\"$oc/devices/设备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));//清空缓存区
}
else if(R_data[149]=='1')
{
//printf("开灯\r\n");
printf("AT+MQTTPUB=0,\"$oc/devices/设备ID/sys/commands/response/request_id=%s\",\"\",0,0\r\n",request_id);
memset(analysis_Str,0,sizeof(analysis_Str));//清空缓存区
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));//清空缓存区
}
}
//else printf("MQTT命令长度异常,长度:%d",R_length);
R_length=0;
}
}
}
最终效果:
公众号搜索”IOT趣制作“回复关键字“8266at”或者“0327”获取相关下载链接:
文章来源:https://www.toymoban.com/news/detail-619851.html
文章来源地址https://www.toymoban.com/news/detail-619851.html
到了这里,关于STM32 HAL库+ESP8266+华为云物联网平台的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!