STM32 MQTT协议 连接中国移动OneNet服务器 上传接收数据(三)STM32部分
关于单片机部分主要使用ESP8266 WIFI模块进行联网,单片机采用STM32ZET6
ESP8266部分
ESP8266是一款使用非常广泛的WIFI模块,这里我们通过单片机的AT指令来控制它
这里有8266的AT指令手册:/sites/default/files/documentation/2a-esp8266-sdk_getting_started_guide_cn.pdf
在进行程序测试之前,推荐使用串口调试助手直接连接8266测试AT指令,和检查模块是否可用
关于ESP8266的具体细节可以查看官网接下来来讲解STM32程序部分
STM32程序
因为MQTT的协议建立在TCP的连接之上,所以我们要用8266建立一个TCP连接,我们对照手册进行设置
我们首先把8266初始化
UsartPrintf(USART_DEBUG, "1. AT\r\n");//检查AT指令是否可用while(ESP8266_SendCmd("AT\r\n", "OK"))DelayXms(500);UsartPrintf(USART_DEBUG, "2. CWMODE\r\n");//将8266设置为STA模式while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))DelayXms(500);UsartPrintf(USART_DEBUG, "3. AT+CWDHCP\r\n");//开启DHCPwhile(ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK"))DelayXms(500);UsartPrintf(USART_DEBUG, "4. CWJAP\r\n");//设置要连接的WIFID的SSID和密码//ESP8266_WIFI_INFO"AT+CWJAP=\"Lord AC\",\"19981220\"\r\n"while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "OK"))DelayXms(500);UsartPrintf(USART_DEBUG, "5. CIPSTART\r\n");//设置为TCP连接,并设定IP和端口号//ESP8266_ONENET_INFO"AT+CIPSTART=\"TCP\",\"183.230.40.39\",6002\r\n"while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))DelayXms(500);UsartPrintf(USART_DEBUG, "6. ESP8266 Init OK\r\n");//初始化完成
完成以上步骤TCP连接就成功建立了,将产品ID等写成宏定义,通过函数封装连接平台(具体的封装函数不做详解,都是C语言的知识,之后会将整个工程放到Github)
#define PROID"367119"#define AUTH_INFO"test"#define DEVID"619588959"if(MQTT_PacketConnect(PROID, AUTH_INFO, DEVID, 256, 0, MQTT_QOS_LEVEL0, NULL, NULL, 0, &mqttPacket) == 0){ESP8266_SendData(mqttPacket._data, mqttPacket._len);//上传平台dataPtr = ESP8266_GetIPD(250);//等待平台响应if(dataPtr != NULL){if(MQTT_UnPacketRecv(dataPtr) == MQTT_PKT_CONNACK){switch(MQTT_UnPacketConnectAck(dataPtr)){case 0:UsartPrintf(USART_DEBUG, "Tips:连接成功\r\n");status = 0;break;case 1:UsartPrintf(USART_DEBUG, "WARN:连接失败:协议错误\r\n");break;case 2:UsartPrintf(USART_DEBUG, "WARN:连接失败:非法的clientid\r\n");break;case 3:UsartPrintf(USART_DEBUG, "WARN:连接失败:服务器失败\r\n");break;case 4:UsartPrintf(USART_DEBUG, "WARN:连接失败:用户名或密码错误\r\n");break;case 5:UsartPrintf(USART_DEBUG, "WARN:连接失败:非法链接(比如token非法)\r\n");break;default:UsartPrintf(USART_DEBUG, "ERR:连接失败:未知错误\r\n");break;}}}MQTT_DeleteBuffer(&mqttPacket);//删包}
串口1会打印调试信息,我们可以看到已经成功连接,并且我们打开OneNET后台,也可以看到设备上线
发送数据
采用JSON格式将数据封成包,然后上传
unsigned char OneNet_FillBuf(char *buf){char text[48];memset(text, 0, sizeof(text));strcpy(buf, "{");memset(text, 0, sizeof(text));sprintf(text, "\"test\":%d,",666); strcat(buf, text);memset(text, 0, sizeof(text));sprintf(text, "\"test2\":%d",888); strcat(buf, text);strcat(buf, "}");return strlen(buf);}void OneNet_SendData(void){MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};//协议包char buf[128];short body_len = 0, i = 0;UsartPrintf(USART_DEBUG, "Tips:OneNet_SendData-MQTT\r\n");memset(buf, 0, sizeof(buf));body_len = OneNet_FillBuf(buf);//获取当前需要发送的数据流的总长度if(body_len){if(MQTT_PacketSaveData(DEVID, body_len, NULL, 3, &mqttPacket) == 0)//封包{for(; i < body_len; i++)mqttPacket._data[mqttPacket._len++] = buf[i];ESP8266_SendData(mqttPacket._data, mqttPacket._len);//上传数据到平台UsartPrintf(USART_DEBUG, "Send %d Bytes\r\n", mqttPacket._len);MQTT_DeleteBuffer(&mqttPacket);//删包}elseUsartPrintf(USART_DEBUG, "WARN:EDP_NewBuffer Failed\r\n");}}
同时我们可以在后台查看到刚刚上传的数据
至此我们成功完成上传数据
项目文件地址
附上整个项目的github地址/DevilAC/MQTT-STM32-ESP8266/tree/master