目录
链接快速定位
前沿
1 准备工作
2 硬件环境介绍
3 软件环境介绍
3.1 串口初始化及配置
3.2 编写AT MQTT指令代码
3.2.1 ESP8266_Cmd函数介绍
3.2.2 wifi连接函数介绍
3.2.3 云端连接语句介绍
3.2.4 环回消息测试语句介绍
3.2.5 属性上报语句介绍
3.2.6 设置属性语句介绍
4 实验现象
4.1 代码运行现象
4.2 属性上报现象
4.3 设置属性现象
链接快速定位
ESP8266 -- 烧录AT固件(一)
ESP8266 -- 搭建阿里云物联网与MQTT.fx通信的平台(二)
ESP8266 -- 串口助手 AT MQTT 指令与阿里云物联网平台建立通信(三)
演示代码在文章顶部可以下载,也可以通过评论留下邮箱进行发送
前沿
前面讲解了固件的烧录,搭建阿里云物联网平台和esp8266利用串口助手与阿里云物联网平台建立通信,本小节主要讲解利用STM32与esp8266模块进行通信。
1 准备工作
在进行本小节内容的时候,需要做如下的准备工作:
- 烧录AT MQTT固件,见链接:ESP8266 -- 烧录AT固件(一)
- 阿里物联网平台的搭建,见链接:ESP8266 -- 搭建阿里云物联网与MQTT.fx通信的平台(二)
如果对AT指令不是很熟悉,建议参考:ESP8266 -- 串口助手 AT MQTT 指令与阿里云物联网平台建立通信(三),简单的掌握一下AT指令。
2 硬件环境介绍
硬件选择安信可的ESP01S模块与STM32单片机相连接,具体连接方式这里不展开讲解,网上也有很多资料,原理就是串口间的通信。
3 软件环境介绍
软件环境使用keil5,编译下载stm32f103标准库程序进行演示。演示代码在文章顶部可以下载,也可以通过评论留下邮箱进行发送。下面重点讲解软件代码。
3.1 串口初始化及配置
主要实现了串口的初始化配置,并且使能了接收完成中断。
static void ESP8266_USART_Config ( void ) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* config USART clock */ macESP8266_USART_APBxClock_FUN ( macESP8266_USART_CLK, ENABLE ); macESP8266_USART_GPIO_APBxClock_FUN ( macESP8266_USART_GPIO_CLK, ENABLE ); /* USART GPIO config */ /* Configure USART Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = macESP8266_USART_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(macESP8266_USART_TX_PORT, &GPIO_InitStructure); /* Configure USART Rx as input floating */ GPIO_InitStructure.GPIO_Pin = macESP8266_USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(macESP8266_USART_RX_PORT, &GPIO_InitStructure); /* USART mode config */ USART_InitStructure.USART_BaudRate = macESP8266_USART_BAUD_RATE; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(macESP8266_USARTx, &USART_InitStructure); /* 中断配置 */ USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断 ESP8266_USART_NVIC_Configuration (); USART_Cmd(macESP8266_USARTx, ENABLE); }
void macESP8266_USART_INT_FUN ( void ) { uint8_t ucCh; if ( USART_GetITStatus ( macESP8266_USARTx, USART_IT_RXNE ) != RESET ) { ucCh = USART_ReceiveData( macESP8266_USARTx ); if ( strEsp8266_Fram_Record .InfBit .FramLength
3.2 编写AT MQTT指令代码
以下就是AT MQTT实现的主要函数,此函数主要实现了以下功能:
- wifi连接
- 云端连接
- 环回消息的测试
- 属性上报
- 设置属性
void ESP8266_Test(void) { char cCmd [254]; //最多一次发送256字节,除去两个字节的换行符 printf ( "正在配置 ESP8266 ......\r\n" ); macESP8266_CH_ENABLE(); ESP8266_AT_Test (); ESP8266_Net_Mode_Choose (STA); while ( ! ESP8266_JoinAP (ESP8266_APSSId, ESP8266_APPWD) ); printf("wifi已连接\r\n"); /* 单连接模式 */ ESP8266_Enable_MultipleId ( DISABLE ); /* 配置云端参数 */ sprintf (cCmd, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"", BROKER_CLIENT_ID, BROKER_USERNAME,BROKER_USERNAME_PWD); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); /* 连接云端 */ sprintf (cCmd, "AT+MQTTCONN=0,\"%s\",%s,0", BROKER_HOST_IP, BROKER_HOST_PORT); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); /* 订阅环回消息 */ sprintf (cCmd, "AT+MQTTSUB=0,\"%s\",0", LOOP_PUB_SUB_TOPIC); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); /* 发送环回消息 */ sprintf (cCmd, "AT+MQTTPUB=0,\"%s\",\"%s\",0,0", LOOP_PUB_SUB_TOPIC, testdata); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); /* 属性上报--订阅消息 */ sprintf (cCmd, "AT+MQTTSUB=0,\"%s\",0", POST_REPLY_TOPIC); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); /* 属性上报--发布消息 */ sprintf (cCmd, "AT+MQTTPUB=0,\"%s\",\"%s\",0,0", POST_TOPIC, postdata); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); while (1) { /* 设置属性--订阅消息 */ sprintf (cCmd, "AT+MQTTSUB=0,\"%s\",0", SET_PROPERTY_TOPIC); ESP8266_Cmd ( cCmd, "OK", NULL, 2000 ); } }
3.2.1 ESP8266_Cmd函数介绍
此函数主要实现了向esp8266模块发送AT指令,并且在串口助手打印收到的AT回复,形参reply1和reply2为返回字符串的子集,如果返回字符串存在reply1和reply2这两个参数,那么返回成功。
bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime ) { strEsp8266_Fram_Record .InfBit .FramLength = 0; //从新开始接收新的数据包 macESP8266_Usart ( "%s\r\n", cmd ); if ( ( reply1 == 0 ) && ( reply2 == 0 ) ) //不需要接收数据 return true; Delay_ms ( waittime ); //延时 strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF ); if ( ( reply1 != 0 ) && ( reply2 != 0 ) ) return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) || ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); else if ( reply1 != 0 ) return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) ); else return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); }
3.2.2 wifi连接函数介绍
连接wifi主要通过指令进行wifi的连接,这里做了简单的处理,既是已经连上wifi下次不必重复连接。
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord ) { char cCmd [120]; sprintf ( cCmd, "AT+CWJAP?"); /* 如果已经连接wifi,那么不需要重复链接 */ if (ESP8266_Cmd ( cCmd, "+CWJAP:", NULL, 5000 ) == true) { return true; } printf("正在连接wifi\r\n"); sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord ); return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 ); }
3.2.3 云端连接语句介绍
云端的连接主要分为两部分: 详情请参见ESP8266 -- 串口助手 AT MQTT 指令与阿里云物联网平台建立通信(三)
一是配置云端参数:配置云端参数主要是指令实现。
二是连接云端:通过 指令实现。
#define BROKER_HOST_IP "iot-06z12ga2pdtk6xu.mqtt.iothub.aliyuncs.com" //要连接的服务器的 IP #define BROKER_HOST_PORT "1883" //要连接的服务器的端口 /* 对于BROKER_CLIENT_ID定义字符串的解释: 原本字符串:"izi37b1wleB.TestDevice|securemode=2,signmethod=hmacsha256,timestamp=1701570366200|" esp8266支持的字符串:"izi37b1wleB.TestDevice|securemode=2\,signmethod=hmacsha256\,timestamp=1701570366200|" 需在','前加'\' C语言基于esp8266支持的字符串:"izi37b1wleB.TestDevice|securemode=2\\,signmethod=hmacsha256\\,timestamp=1701570366200|" 需在'\'前再加一个'\' 最终通过串口发出去的字符串:"izi37b1wleB.TestDevice|securemode=2\,signmethod=hmacsha256\,timestamp=1701570366200|" */ #define BROKER_CLIENT_ID "izi37b1wleB.TestDevice|securemode=2\\,signmethod=hmacsha256\\,timestamp=1701570366200|" #define BROKER_USERNAME "TestDevice&izi37b1wleB" #define BROKER_USERNAME_PWD "77517177642f88688ac2d6286f30699cff7d699daad8394d837608dc5db5935b" /* 配置云端参数 */ sprintf (cCmd, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"", BROKER_CLIENT_ID, BROKER_USERNAME,BROKER_USERNAME_PWD); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); /* 连接云端 */ sprintf (cCmd, "AT+MQTTCONN=0,\"%s\",%s,0", BROKER_HOST_IP, BROKER_HOST_PORT); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 );
3.2.4 环回消息测试语句介绍
环回消息主要是依赖自定义的发布和接收Topic,首先使用命令订阅消息,再通过指令回读发送的消息。
const char testdata[] = "This is a MQTT loop test"; #define LOOP_PUB_SUB_TOPIC "/izi37b1wleB/TestDevice/user/LoopTopic" //环回测试主题 /* 订阅环回消息 */ sprintf (cCmd, "AT+MQTTSUB=0,\"%s\",0", LOOP_PUB_SUB_TOPIC); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); /* 发送环回消息 */ sprintf (cCmd, "AT+MQTTPUB=0,\"%s\",\"%s\",0,0", LOOP_PUB_SUB_TOPIC, testdata); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 );
3.2.5 属性上报语句介绍
属性上报和环回消息类似,只是订阅的主题不一样,环回测试主题是自定义的收发Topic,属性上报则是物模型的属性上报Topic。
/* 对于postdata定义字符串的解释: 原本字符串: "{ (JSON格式) "id":1701504913858, "params": { "TestTSL":888 }, "version":"1.0", "method":"thing.event.property.post" }" esp8266支持的字符串: "{ (也就是在'"'前面增加'\' \"id\":1701504913858\, 在','前面增加'\') \"params\": { \"TestTSL\":888 }\, \"version\":\"1.0\"\, \"method\":\"thing.event.property.post\" }" C语言基于esp8266支持的字符串: "{ (如果是','需在'\'前再加1个'\', \\\"id\\\":1701504913858\\, 如果是'"'需在'\'前再加2个'\' \\\"params\\\": { \\\"TestTSL\\\":888 }\\, \\\"version\\\":\\\"1.0\\\"\\, \\\"method\\\":\\\"thing.event.property.post\\\" }" 最终通过串口发出去的字符串: "{ \"id\":1701504913858\, \"params\": { \"TestTSL\":888 }\, \"version\":\"1.0\"\, \"method\":\"thing.event.property.post\" }" */ const char postdata[] = "{\\\"id\\\":1701504913858\\,\\\"params\\\":{\\\"TestTSL\\\":888}\\,\\\"version\\\":\\\"1.0\\\"\\,\\\"method\\\":\\\"thing.event.property.post\\\"}"; #define POST_TOPIC "/sys/izi37b1wleB/TestDevice/thing/event/property/post" //发布 #define POST_REPLY_TOPIC "/sys/izi37b1wleB/TestDevice/thing/event/property/post_reply" //订阅 /* 属性上报--订阅消息 */ sprintf (cCmd, "AT+MQTTSUB=0,\"%s\",0", POST_REPLY_TOPIC); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 ); /* 属性上报--发布消息 */ sprintf (cCmd, "AT+MQTTPUB=0,\"%s\",\"%s\",0,0", POST_TOPIC, postdata); ESP8266_Cmd ( cCmd, "OK", NULL, 1000 );
3.2.6 设置属性语句介绍
设置属性就是实时订阅云端的消息,这里2s订阅一次消息。
#define SET_PROPERTY_TOPIC "/sys/izi37b1wleB/TestDevice/thing/service/property/set" //订阅 while (1) { /* 设置属性--订阅消息 */ sprintf (cCmd, "AT+MQTTSUB=0,\"%s\",0", SET_PROPERTY_TOPIC); ESP8266_Cmd ( cCmd, "OK", NULL, 2000 ); }
4 实验现象
4.1 代码运行现象
4.2 属性上报现象
这里属性上报的TestTSL=888,我们打开云端,查看到TestTSL的值确实是888。
4.3 设置属性现象
通过阿里云物联网平台,设置TestTSL=123,查看到串口助手显示的值也为123。
注意:此代码不能直接和云端进行通信,需要自己搭建云平台,并修改相对应的云端IP、client_id及密码,云端的搭建可以参考:ESP8266 -- 搭建阿里云物联网与MQTT.fx通信的平台(二)
接下来讲解利用物联网平台读取和控制STM32板载资源,敬请期待。。。