赞
踩
目录
ESP32是一块完整的开发板,据我目前所知,它本身自带蓝牙和WIFI,可用arduino和MicroPython单独对其完成开发,以前我用arduino已经试过了。参考我之前的
ESP32(基于Arduino)连接EMQX的Mqtt服务器上传信息与命令控制_昊月光华的博客-CSDN博客_arduino esp32 mqtt
既然ESP32本身在通信方面上就已经做得足够完美了(最高主频可以达到240MHZ),而且以arduino库开发的方式又极其简单和轻松。奈何让esp32订阅和发布都是相当于另外写一套代码(尽管也很简单,但避免不了新的需求又要增加新的代码),其中包括串口通信的代码(保证不会有信息丢失),还要包括断网自动重连WIFI和与mqtt服务器断开自动重连等辅助代码。试想在这种情况下,需要判断从stm32发过来的信息中是发给那个主题的,不得不继续修改代码增加判断。( (除非单独指定某个串口接受某个主题的数据,然后esp32收到就直接发送对应主题。)
本次实现第二种:让esp32烧录MQTT 的AT 固件 然后 stm32以发AT 指令的方式完成所有功能。详细见步骤:
这个官方文档上有。
接线
esp32的固件链接
https://docs.ai-thinker.com/_media/esp32/esp32-s_at2.2-sdk4.0.1-uart0.rar
Flash烧录工具的下载链接:工具 | 乐鑫科技
下载解压后图示
打开烧录工具
选择后(如下配置只有被勾选的那一行是有效的)
在烧录之前,把esp32设置成自动下载模式,先按EN,同时按下IO0
串口打印出
- rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
- waiting for download
说明进入了下载模式
start后,开始下载
完成后复位测试AT指令。(需要注意的是AT指令格式必须是严格的,比如以下带AT的指令,AT前不能有空格,后面也不能有空格,另外串口调试助手发送还必须带回车符。)
在进行以下AT指令测试之前,本地EMQX的mqtt服务器要安装后并在bin路径下
emqx start
启动。
进行AT指令测试。(附上官网文档上的指令)
更多关于WIFI 的AT指令和MQTT 的AT指令集参考乐鑫官网
AT 命令集 - ESP32 - — ESP-AT 用户指南 latest 文档 (espressif.com)
发送AT指令的顺序:
AT #测试AT功能
AT+CWMODE=1 #设置模组进入STA模式
AT+CWJAP="ssid","password" #连接wifi
AT+MQTTUSERCFG=0,1,"用户ID","账号","密码",0,0,""
# 设置MQTT连接所需要的的参数,包括用户ID(不为空)、
# 账号(admin)以及密码(public)
AT+MQTTCONN=0,"本地IP",1883,0
AT+MQTTPUB=0,"对应主题","发布主题对应信息",0,0 //发布对应主题信息
AT+MQTTSUB=0,"订阅的主题名",0 //订阅对应的主题
串口助手下AT 指令测试
若连接mqtt服务器返回 ERROR
先调用 MQTT+CLEAN=0 清除MQTT的连接信息。再重新连接。
AT+MQTTCONN=0,"192.168.1.13",1883,0(以连接本地为例,0改成1即可,经过测试,手动断开服务器连接后能自动重连)
AT+CWAUTOCONN=<enable> 0:上电不自动连接 1:上电自动连接
AT+CWRECONNCFG=1,0 //断开后每隔1s自动重连,始终尝试自动重连
到这,把esp32断网自动重连WIFI和mqtt服务器都设置完毕。
让stm32以串口的形式发送给ESP32代替串口调试助手与ESP32进行交互。需要注意的是在连接时适当的延时保证ESP32处理完数据。(若不延时,我测试时有可能会连接失败)
其中STM32是F103C8T6最小系统开发板。
stm32的串口2连接ESP32的串口1。stm32的串口2以DMA加空闲中断接受数据。
esp32收到stm32发过来的AT指令订阅"hello"主题,用paho客户端或EMQX下的websocket发布主题信息,以json格式发送,esp32收到后发送到stm32,stm32解析出对应数据信息。
我的代码中难免有败笔,只考虑了正常情况,敬请指出。
mqtt.c
-
-
-
- #include "mqtt.h"
-
-
-
-
-
-
- u16 MAXCONNECT_TIME=0;
-
- u8 Rx2_Buf[180]={0}; //接受ESP32模块信息
- u8 Rx2_sBuf[180]={0}; //发送缓存数组 以DMA方式
- u8 Rx2_Cnt=0;
-
- __IO u8 mqttstate=0;
- char wifi_uid[]="rookie";
- char wifi_pwd[]="yy061457";
-
-
-
- //连接WIFI ESP32可以设置为自动重连
- void ConnectWifi(void){
-
- sprintf((char *)Rx2_sBuf,CONNECTWIFI,wifi_uid,wifi_pwd);
-
- HAL_UART_Transmit(&huart2,Rx2_sBuf,strlen((const char *)Rx2_sBuf),10);
-
-
- }
-
-
- //清除MQTT连接
- void CleanMqttInfo(void){
-
- HAL_UART_Transmit(&huart2,(uint8_t *)CLEANMQTTINFO,sizeof(CLEANMQTTINFO),10);
- printf("%s\r\n",CLEANMQTTINFO);
-
-
- }
-
- //登录认证
- void ConnectMQTTServer(void){
-
- //清除先前遗留连接信息
- CleanMqttInfo();
-
- HAL_Delay(500);
- //登录认证
- HAL_UART_Transmit(&huart2,(u8*)LOGINMQTT,sizeof(LOGINMQTT),20);
- printf("%s\r\n",LOGINMQTT);
- HAL_Delay(500);
-
-
- //连接mqtt服务器
- HAL_UART_Transmit(&huart2,(u8*)CONNECTMQTT,sizeof(CONNECTMQTT),20);
- printf("%s\r\n",CONNECTMQTT);
- HAL_Delay(1000);
-
- }
-
-
- //连接WIFI与MQTT服务器
- void MQTT_Init(void){
-
-
-
- ConnectWifi(); //可设置上电自动连接wifi
- HAL_Delay(5000);
- mqttstate=1;
- ConnectMQTTServer();
- while(mqttstate!=2){
-
- ConnectMQTTServer();
- HAL_Delay(1000);
- }
- printf("Connect mqtt success\r\n");
-
- SubAssignTopic("hello"); //订阅相关主题
-
- HAL_Delay(1000);
-
- }
-
- ///订阅指定主题
- void SubAssignTopic(char * subtopic){
-
- sprintf(Rx2_sBuf,SUBTOPIC,subtopic);
- printf("%s\r\n",Rx2_sBuf);
- HAL_UART_Transmit(&huart2,Rx2_sBuf,sizeof(Rx2_sBuf),10);
-
- }
-
-
-
-
- //获取对应主题和对应信息(JSON格式),以及json数据报长度
- void GetTopicAndMsg(char * p,char * src,char* topic, char* cnt,int len,char * msg) {
-
- while (*p != '"' && p != &src[len - 1])p++; //匹配第一个引号
-
-
- if (*p++ == '"') {
- char start = 0;
- while (*p != '"' && p != &src[len - 1]) {
- topic[start++] = *p++;
- }
-
- if (*p++ == '"') { //匹配第二个引号
- topic[start] = '\0';
- printf("[topic]:%s\r\n", topic); //主题获取完毕
-
- }
- if (*p == ',' && p!= &src[len-1]) { //匹配第一个逗号
- p++;
- char temp[3] = { 0 };
- char j = 0;
- while (*p!=',' && p != &src[len-1])
- {
- temp[j++] = *p++;
- }
- *cnt = atoi(temp);//得到长度
- printf("[CNT]:%d\r\n", *cnt);
- if (*p++ == ',') {//匹配描述消息体长度的最后一个逗号
- j = 0;
- while (p != &src[len]) {
- msg[j++] = *p++;
- }
- msg[j] = '\0';
- printf("[msg]:%s\r\n", msg);
-
- }
- }
-
- }
-
- }
-
-
- void Test(void){
-
- char topic[30]={0};
- char msg[160]={0};
- char* p = strstr((const char *)Rx2_Buf, "MQTTSUBRECV");
- if(p){
- u8 len =strlen((const char *)Rx2_Buf);
- char cnt=0;
- //获取主题与json数据报
- GetTopicAndMsg(p ,Rx2_Buf, topic,&cnt, len, msg);
-
-
- json_error_t error;
- json_t *root;
- root = json_loads((const char*)msg, 0, &error);
- if(json_is_object(root)) //是json格式数据
- {
- //解析json数据
- if(strcmp(topic,"hello") == 0){
- char *name=(char *)json_string_value(json_object_get(root, "name"));
- int val1=json_integer_value(json_object_get(root, "val1"));
- int val2=json_integer_value(json_object_get(root, "val2"));
- int val3=json_integer_value(json_object_get(root, "val3"));
- //测试解析后的数据
- printf("parse name:%s-val1:%d-val2:%d-val3:%d\r\n",name,val1,val2,val3);
-
- }
-
- //释放内存
- json_decref(root);
-
- }
- else //非json格式数据
- {
- printf("format error:%d-%s\r\n", error.line, error.text);
-
- }
-
-
-
-
-
-
- }
-
-
-
-
- }
-
-
- //发布信息到指定主题
- void PubMsgByTopic(char * topic,char * msg){
-
- sprintf(Rx2_sBuf,topic,msg);
- HAL_UART_Transmit(&huart2,Rx2_sBuf,sizeof(Rx2_sBuf),10);
-
- }
-
-
-
-
-
-
-
-
-
mqtt.h
-
-
- #ifndef __MQTT_H_
- #define __MQTT_H_
-
-
-
-
- #include "template.h"
-
- void ConnectWifi(void);
- void ConnectMQTTServer(void);
-
-
-
- extern u8 Rx2_Buf[180];
- extern u8 Rx2_sBuf[180];
-
-
- extern __IO u8 mqttstate;
-
-
- //订阅主题格式
- #define SUBTOPIC "AT+MQTTSUB=0,\"%s\",0\r\n"
-
- //发布对应主题对应信息格式
- #define PUBTOPIC "AT+MQTTPUB=0,\"%s\",\"%s\",0,0\r\n"
-
- //连接对应WIFI 账号 密码
- #define CONNECTWIFI "AT+CWJAP=\
- \"%s\",\
- \"%s\"\r\n"
-
- //清除MQTT连接信息
- #define CLEANMQTTINFO "AT+MQTTCLEAN=0\r\n"
-
-
-
- //连接EMQX服务器的本地登录账号和密码
- #define LOGINMQTT "AT+MQTTUSERCFG=0,1,\
- \"ESP\",\
- \"admin\",\
- \"061457\",\
- 0,0,""\
- \r\n"
-
- //连接本地EMQX 下的mqtt服务器地址 设置断开自动重连
- #define CONNECTMQTT "AT+MQTTCONN=0,\"192.168.1.13\",1883,1\r\n"
-
-
-
-
-
-
-
- extern u16 MAXCONNECT_TIME;
- void SubAssignTopic(char * subtopic);
- void PubMsgByTopic(char * topic,char * msg);
- void MQTT_Init(void);
-
-
- void Test(void);
- #endif
-
-
发布hello主题
json 数据如下
{
"name":"yzh",
"val1":1,
"val2":2,
"val3":3
}
结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。