当前位置:网站首页>Stm32+esp8266+mqtt protocol connects onenet IOT platform
Stm32+esp8266+mqtt protocol connects onenet IOT platform
2022-07-06 18:34:00 【Hua Weiyun】
One 、 Introduction to the environment
Single chip microcomputer adopts : STM32F103C8T6
Internet access : use ESP8266, Other equipment can also be used instead of , Just support TCP Agreement is enough . such as :GSM modular 、 Wired network card, etc .
Development software : keil5
Hardware connection function : ESP8266 Connect to STM32 Serial port 3 On . adopt AT Command and ESP8266 communicate .
Two 、 Function is introduced
2.1 Functional specifications
adopt OneNet The Internet of things server realizes remote uploading of equipment data 、 Send out , Realize data interaction ( Unclear OneNet The function of Internet of things server can enter Baidu's official website to see the introduction ). Previous OneNet The server does not support standard MQTT Protocol login , Now after the official website is updated, it supports standard MQTT agreement , This article introduces the use of STM32+ESP8266 Use standards MQTT Protocol login Onenet The server , Realize data interaction . Implementation steps OneNet The official has provided very detailed documents , You can refer to it .
Document address :OneNET- China Mobile Internet of things open platform
![ Click and drag to move ]
![ Click and drag to move ]
2.2 Hardware resources
On the currently used development board 4 A LED The lamp 、 A buzzer 、4 A button ,ESP8266 Model is ESP-12F,STM32 Model is :STM32F103C8T6.
![ Click and drag to move ]
3、 ... and 、OneNet Supported by MQTT Protocol version
at present OneNet Server support MQTT 3.1.1 edition ,MQTT Protocol official website : http://mqtt.org/?spm=a2c4g.11186623.2.11.19083f86gxhJ7h
Message support : Support connect、subscribe、publish、ping、unsubscribe、disconnect Wait for the message , I won't support it pubrec、pubrel、pubcomp message .
![ Click and drag to move ]
Four 、 Sign in OneNet Servers create Internet of things products
No registered account , You need to log in to the official website in advance to register your account , Then go to the following steps :
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
Fill in here according to your own product .
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
After the product is created successfully , Click on the product name , Jump to the page , Continue adding devices .
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
Next, select the data source of the dashboard , Select according to the data points you created .
![ Click and drag to move ]
Create a text control , Displays the time when the data point was updated , Convenient debugging .
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
OneNte There is a mobile version APP, You can also see this page after logging in .
Download address :https://open.iot.10086.cn/doc/book/device-develop/multpro/sdk-doc-tool/APP.html
![ Click and drag to move ]
![ Click and drag to move ]
Here is the login on your mobile phone APP See the interface effect :
![ Click and drag to move ]
![ Click and drag to move ]
5、 ... and 、OneNet The server MQTT Login address and subscription topic related format introduction
The official website introduces the document address : Device to connect _ Developer documentation _OneNET
![ Click and drag to move ]
5.1 MQTT Server login address
![ Click and drag to move ]
at present MQTT The protocol supports two IP Address and port number , One needs encryption 、 One that doesn't need encryption .
Be careful : Transplanting encryption algorithm on single chip microcomputer is very troublesome , The port that does not need to be encrypted is used here .(IP Address : 183.230.40.96 port : 1883)
![ Click and drag to move ]
5.2 MQTT Logon : equipment ID、 User name 、 password Format parameters
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
The picture above shows ,OneNet Equipment parameters and standards MQTT Corresponding relationship between login parameters of the protocol . OneNet Equipment parameters , On the device page, you can view .
See the following steps for login password generation :
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
Be careful : The tool is in win10 The system may prompt untrusted programs , Click any to run .
Here is the generation MQTT Use example of login key tool .
edit
Be careful : Please refer to the document introduction for the parameter description filled in the tool .
res Format of option parameters : products/{ product ID}/devices/{ Equipment name }
et It's settings token Expiration time : Work out 1970-1-1 To the expiration time you want to set , The unit is seconds , Just fill in .
such as : Timeout set to 2020-07-20 , that , The seconds filled in here are :1970-1-1 To 2020-07-20 Second unit time between .
Linux Next code :
#include <stdio.h>#include <time.h> #include <time.h>int main(){ time_t time_sec; time_sec=time(NULL); // Current second unit time --UTC Time printf(" current time ( second ):%ld\n",time_sec); printf(" Add 30 Time of day ( second ):%ld\n",time_sec+30*24*60*60); return 0;}
key Parameter format of : After the device is created , On the equipment details page key
The result value generated by the tool , Directly as MQTT Login password .
5.3 Topic subscription format
Document address : Protocol specification _ Developer documentation _OneNET
![ Click and drag to move ]
![ Click and drag to move ]
5.4 Equipment life time
![ Click and drag to move ]
![ Click and drag to move ]
5.5 Send data points to the server
![ Click and drag to move ]
![ Click and drag to move ]
![ Click and drag to move ]
6、 ... and 、 Core code
6.1 matt.c Code
#include "mqtt.h"u8 *mqtt_rxbuf;u8 *mqtt_txbuf;u16 mqtt_rxlen;u16 mqtt_txlen;u8 _mqtt_txbuf[256];// Send data buffer u8 _mqtt_rxbuf[256];// Receive data buffer typedef enum{ // name value Message flow direction describe M_RESERVED1 =0 , // prohibit Retain M_CONNECT , // Client to server The client requests to connect to the server M_CONNACK , // Service end to client Connection message confirmation M_PUBLISH , // Both directions allow Release the news M_PUBACK , // Both directions allow QoS 1 Message release received confirmation M_PUBREC , // Both directions allow Release received ( The first step in ensuring delivery ) M_PUBREL , // Both directions allow Release ( Guaranteed delivery step two ) M_PUBCOMP , // Both directions allow QoS 2 Message release complete ( The third step in ensuring interaction ) M_SUBSCRIBE , // Client to server Client subscription request M_SUBACK , // Service end to client Subscription request message confirmation M_UNSUBSCRIBE , // Client to server Client unsubscribe request M_UNSUBACK , // Service end to client Unsubscribe message confirmation M_PINGREQ , // Client to server Heartbeat request M_PINGRESP , // Service end to client Heartbeat response M_DISCONNECT , // Client to server Client disconnected M_RESERVED2 , // prohibit Retain }_typdef_mqtt_message;// The connection was successful and the server responded 20 02 00 00// The client actively disconnects e0 00const u8 parket_connetAck[] = {0x20,0x02,0x00,0x00};const u8 parket_disconnet[] = {0xe0,0x00};const u8 parket_heart[] = {0xc0,0x00};const u8 parket_heart_reply[] = {0xc0,0x00};const u8 parket_subAck[] = {0x90,0x03};void MQTT_Init(void){ // Buffer assignment mqtt_rxbuf = _mqtt_rxbuf; mqtt_rxlen = sizeof(_mqtt_rxbuf); mqtt_txbuf = _mqtt_txbuf; mqtt_txlen = sizeof(_mqtt_txbuf); memset(mqtt_rxbuf,0,mqtt_rxlen); memset(mqtt_txbuf,0,mqtt_txlen); // Unconditional active disconnection first MQTT_Disconnect(); delay_ms(100); MQTT_Disconnect(); delay_ms(100);}/* The functionality : The return value of the login server function : 0 It means success 1 It means failure */u8 MQTT_Connect(char *ClientID,char *Username,char *Password){ u8 i,j; int ClientIDLen = strlen(ClientID); int UsernameLen = strlen(Username); int PasswordLen = strlen(Password); int DataLen; mqtt_txlen=0; // Variable header +Payload Each field contains a length identifier of two bytes DataLen = 10 + (ClientIDLen+2) + (UsernameLen+2) + (PasswordLen+2); // Fixed header // Control message type mqtt_txbuf[mqtt_txlen++] = 0x10; //MQTT Message Type CONNECT // Residual length ( Not including fixed head ) do { u8 encodedByte = DataLen % 128; DataLen = DataLen / 128; // if there are more data to encode, set the top bit of this byte if ( DataLen > 0 ) encodedByte = encodedByte | 128; mqtt_txbuf[mqtt_txlen++] = encodedByte; }while ( DataLen > 0 ); // Variable header // The name of the agreement mqtt_txbuf[mqtt_txlen++] = 0; // Protocol Name Length MSB mqtt_txbuf[mqtt_txlen++] = 4; // Protocol Name Length LSB mqtt_txbuf[mqtt_txlen++] = 'M'; // ASCII Code for M mqtt_txbuf[mqtt_txlen++] = 'Q'; // ASCII Code for Q mqtt_txbuf[mqtt_txlen++] = 'T'; // ASCII Code for T mqtt_txbuf[mqtt_txlen++] = 'T'; // ASCII Code for T // Agreement level mqtt_txbuf[mqtt_txlen++] = 4; // MQTT Protocol version = 4 about 3.1.1 Version of the agreement , The value of the protocol level field is 4(0x04) // Connection sign mqtt_txbuf[mqtt_txlen++] = 0xc2; // conn flags mqtt_txbuf[mqtt_txlen++] = 0; // Keep-alive Time Length MSB mqtt_txbuf[mqtt_txlen++] = 100; // Keep-alive Time Length LSB 100S Heartbeat bag Time to live mqtt_txbuf[mqtt_txlen++] = BYTE1(ClientIDLen);// Client ID length MSB mqtt_txbuf[mqtt_txlen++] = BYTE0(ClientIDLen);// Client ID length LSB memcpy(&mqtt_txbuf[mqtt_txlen],ClientID,ClientIDLen); mqtt_txlen += ClientIDLen; if(UsernameLen > 0) { mqtt_txbuf[mqtt_txlen++] = BYTE1(UsernameLen); //username length MSB mqtt_txbuf[mqtt_txlen++] = BYTE0(UsernameLen); //username length LSB memcpy(&mqtt_txbuf[mqtt_txlen],Username,UsernameLen); mqtt_txlen += UsernameLen; } if(PasswordLen > 0) { mqtt_txbuf[mqtt_txlen++] = BYTE1(PasswordLen); //password length MSB mqtt_txbuf[mqtt_txlen++] = BYTE0(PasswordLen); //password length LSB memcpy(&mqtt_txbuf[mqtt_txlen],Password,PasswordLen); mqtt_txlen += PasswordLen; } memset(mqtt_rxbuf,0,mqtt_rxlen); MQTT_SendBuf(mqtt_txbuf,mqtt_txlen); for(j=0;j<10;j++) { delay_ms(50); if(USART3_RX_FLAG) { memcpy((char *)mqtt_rxbuf,USART3_RX_BUFFER,USART3_RX_CNT); //memcpy for(i=0;i<USART3_RX_CNT;i++)USART1_Printf("%#x ",USART3_RX_BUFFER[i]); USART3_RX_FLAG=0; USART3_RX_CNT=0; } //CONNECT if(mqtt_rxbuf[0]==parket_connetAck[0] && mqtt_rxbuf[1]==parket_connetAck[1]) // Successful connection { return 0;// Successful connection } } return 1;}/* The functionality : MQTT subscribe / Unsubscribe data packaging function parameters : topic The theme qos Message level 0: Distribute at most once 1: Distribute at least once 2: Distribute only once whether subscribe / Unsubscribe request package (1 To subscribe to ,0 Means unsubscribe ) Return value : 0 It means success 1 It means failure */u8 MQTT_SubscribeTopic(char *topic,u8 qos,u8 whether){ u8 i,j; mqtt_txlen=0; int topiclen = strlen(topic); int DataLen = 2 + (topiclen+2) + (whether?1:0);// Variable header length (2 byte ) Plus the length of the payload // Fixed header // Control message type if(whether)mqtt_txbuf[mqtt_txlen++] = 0x82; // Message type and flag subscription else mqtt_txbuf[mqtt_txlen++] = 0xA2; // Unsubscribe // Residual length do { u8 encodedByte = DataLen % 128; DataLen = DataLen / 128; // if there are more data to encode, set the top bit of this byte if ( DataLen > 0 ) encodedByte = encodedByte | 128; mqtt_txbuf[mqtt_txlen++] = encodedByte; }while ( DataLen > 0 ); // Variable header mqtt_txbuf[mqtt_txlen++] = 0; // Message identifier MSB mqtt_txbuf[mqtt_txlen++] = 0x0A; // Message identifier LSB // Payload mqtt_txbuf[mqtt_txlen++] = BYTE1(topiclen);// Theme length MSB mqtt_txbuf[mqtt_txlen++] = BYTE0(topiclen);// Theme length LSB memcpy(&mqtt_txbuf[mqtt_txlen],topic,topiclen); mqtt_txlen += topiclen; if(whether) { mqtt_txbuf[mqtt_txlen++] = qos;//QoS Level } for(i=0;i<10;i++) { memset(mqtt_rxbuf,0,mqtt_rxlen); MQTT_SendBuf(mqtt_txbuf,mqtt_txlen); for(j=0;j<10;j++) { delay_ms(50); if(USART3_RX_FLAG) { memcpy((char *)mqtt_rxbuf,(char*)USART3_RX_BUFFER,USART3_RX_CNT); USART3_RX_FLAG=0; USART3_RX_CNT=0; } if(mqtt_rxbuf[0]==parket_subAck[0] && mqtt_rxbuf[1]==parket_subAck[1]) // Subscription succeeded { return 0;// Subscription succeeded } } } return 1; // Failure }//MQTT Publish data packaging functions //topic The theme //message news //qos Message level u8 MQTT_PublishData(char *topic, char *message, u8 qos){ int topicLength = strlen(topic); int messageLength = strlen(message); static u16 id=0; int DataLen; mqtt_txlen=0; // The length of the payload is calculated like this : Subtract the length of the variable header from the value of the remaining length field in the fixed header //QOS by 0 There is no identifier // Data length topic name Message identifier Payload if(qos) DataLen = (2+topicLength) + 2 + messageLength; else DataLen = (2+topicLength) + messageLength; // Fixed header // Control message type mqtt_txbuf[mqtt_txlen++] = 0x30; // MQTT Message Type PUBLISH // Residual length do { u8 encodedByte = DataLen % 128; DataLen = DataLen / 128; // if there are more data to encode, set the top bit of this byte if ( DataLen > 0 ) encodedByte = encodedByte | 128; mqtt_txbuf[mqtt_txlen++] = encodedByte; }while ( DataLen > 0 ); mqtt_txbuf[mqtt_txlen++] = BYTE1(topicLength);// Theme length MSB mqtt_txbuf[mqtt_txlen++] = BYTE0(topicLength);// Theme length LSB memcpy(&mqtt_txbuf[mqtt_txlen],topic,topicLength);// Copy the theme mqtt_txlen += topicLength; // Message identifier if(qos) { mqtt_txbuf[mqtt_txlen++] = BYTE1(id); mqtt_txbuf[mqtt_txlen++] = BYTE0(id); id++; } memcpy(&mqtt_txbuf[mqtt_txlen],message,messageLength); mqtt_txlen += messageLength; MQTT_SendBuf(mqtt_txbuf,mqtt_txlen); return mqtt_txlen;}void MQTT_SentHeart(void){ MQTT_SendBuf((u8 *)parket_heart,sizeof(parket_heart));}void MQTT_Disconnect(void){ MQTT_SendBuf((u8 *)parket_disconnet,sizeof(parket_disconnet));}void MQTT_SendBuf(u8 *buf,u16 len){ USARTx_DataSend(USART3,buf,len);}
6.2 mqtt.h Code
#ifndef __FY_MQTT_H_#define __FY_MQTT_H_#include "stm32f10x.h"#include "string.h"#include "stdio.h"#include "stdlib.h"#include "stdarg.h"#include "delay.h"#include "usart.h"#define BYTE0(dwTemp) (*( char *)(&dwTemp))#define BYTE1(dwTemp) (*((char *)(&dwTemp) + 1))#define BYTE2(dwTemp) (*((char *)(&dwTemp) + 2))#define BYTE3(dwTemp) (*((char *)(&dwTemp) + 3)) // User name initialization void OneNet_LoginInit(char *ProductKey,char *DeviceName,char *DeviceSecret);//MQTT Protocol related function declaration u8 MQTT_PublishData(char *topic, char *message, u8 qos);u8 MQTT_SubscribeTopic(char *topic,u8 qos,u8 whether);void MQTT_Init(void);u8 MQTT_Connect(char *ClientID,char *Username,char *Password);void MQTT_SentHeart(void);void MQTT_Disconnect(void);void MQTT_SendBuf(u8 *buf,u16 len);#endif
6.3 main.c Main function code
#include "stm32f10x.h"#include "led.h"#include "delay.h"#include "key.h"#include "usart.h"#include <string.h>#include "timer.h"#include "esp8266.h"#include "mqtt.h"/* Serial number Symbol code 1 + %2B2 Space %203 / %2F4 ? %3F5 % %256 # %237 & %268 = %3D*///OneNet Device information of Internet of things server #define MQTT_ClientID "mq2"#define MQTT_UserName "361594"#define MQTT_PassWord "version=2018-10-31&res=products%2F361594%2Fdevices%2Fmq2&et=1597492895&method=sha1&sign=uqvA0KkjXw0FlN01aT6fWrGBLGw%3D"// Topics subscribed and published // Format :$sys/{ product ID}/{ Equipment name }/##define SET_TOPIC "$sys/361594/mq2/#" // Subscribe to all device information // Format : $sys/{ product ID}/{ Equipment name }/dp/post/json#define POST_TOPIC "$sys/361594/mq2/dp/post/json" // Release char mqtt_message[200];// Report data buffer int main(){ u32 time_cnt=0; u32 i; u8 key; LED_Init(); BEEP_Init(); KEY_Init(); USART1_Init(115200); TIMER1_Init(72,20000); // Timeout time 20ms USART3_Init(115200);// A serial port -WIFI TIMER3_Init(72,20000); // Timeout time 20ms USART1_Printf(" Initializing WIFI One moment please .\n"); if(ESP8266_Init()) { USART1_Printf("ESP8266 Hardware detection error .\n"); } else { // Encryption port //USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode("OnePlus5T","1126626497","183.230.40.16",8883,1)); // Unencrypted port USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode("OnePlus5T","1126626497","183.230.40.96",1883,1)); } //2. MQTT Protocol initialization MQTT_Init(); //3. Connect OneNet The server while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord)) { USART1_Printf("OneNet Server connection failed , Retrying ...\n"); delay_ms(500); } USART1_Printf("OneNet Server connection successful .\n"); //3. Subscribe to topics if(MQTT_SubscribeTopic(SET_TOPIC,0,1)) { USART1_Printf(" Topic subscription failed .\n"); } else { USART1_Printf(" Topic subscription succeeded .\n"); } while(1) { key=KEY_Scan(0); if(key==2) { time_cnt=0; sprintf(mqtt_message,"{\"id\":1,\"dp\":{\"mq2\":[{\"v\":50}]}}"); MQTT_PublishData(POST_TOPIC,mqtt_message,0); USART1_Printf(" Send status 1\r\n"); } else if(key==3) { time_cnt=0; sprintf(mqtt_message,"{\"id\":1,\"dp\":{\"mq2\":[{\"v\":80}]}}"); MQTT_PublishData(POST_TOPIC,mqtt_message,0); USART1_Printf(" Send status 0\r\n"); } if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; for(i=0;i<USART3_RX_CNT;i++) { USART1_Printf("%c",USART3_RX_BUFFER[i]); } USART3_RX_CNT=0; USART3_RX_FLAG=0; } // Send heartbeat packets regularly , Keep connected delay_ms(10); time_cnt++; if(time_cnt==500) { MQTT_SentHeart();// Send heartbeat packets time_cnt=0; } }}
7、 ... and 、 Device login operation effect
After successful login , The web page will show the online status .
Press the development button to upload smoke data to the server :
边栏推荐
- POJ 2208 six lengths of tetrahedron are known, and the volume is calculated
- 随着MapReduce job实现去加重,多种输出文件夹
- 30 minutes to understand PCA principal component analysis
- Coco2017 dataset usage (brief introduction)
- Rb157-asemi rectifier bridge RB157
- echart简单组件封装
- Shangsilicon Valley JUC high concurrency programming learning notes (3) multi thread lock
- Will openeuler last long
- 2022暑期项目实训(三)
- 第三季百度网盘AI大赛盛夏来袭,寻找热爱AI的你!
猜你喜欢
2019 Alibaba cluster dataset Usage Summary
[swoole series 2.1] run the swoole first
1700C - Helping the Nature
Compilation principle - top-down analysis and recursive descent analysis construction (notes)
Maixll dock camera usage
Distill knowledge from the interaction model! China University of science and Technology & meituan proposed virt, which combines the efficiency of the two tower model and the performance of the intera
Easy to use PDF to SVG program
【中山大学】考研初试复试资料分享
從交互模型中蒸餾知識!中科大&美團提出VIRT,兼具雙塔模型的效率和交互模型的性能,在文本匹配上實現性能和效率的平衡!...
Xu Xiang's wife Ying Ying responded to the "stock review": she wrote it!
随机推荐
监控界的最强王者,没有之一!
HMS core machine learning service creates a new "sound" state of simultaneous interpreting translation, and AI makes international exchanges smoother
Introduction and case analysis of Prophet model
The third season of Baidu online AI competition is coming in midsummer, looking for you who love AI!
Running the service with systemctl in the container reports an error: failed to get D-Bus connection: operation not permitted (solution)
Take you through ancient Rome, the meta universe bus is coming # Invisible Cities
虚拟机VirtualBox和Vagrant安装
Ms-tct: INRIA & SBU proposed a multi-scale time transformer for motion detection. The effect is SOTA! Open source! (CVPR2022)...
Automatic reservation of air tickets in C language
当保存参数使用结构体时必备的开发技巧方式
重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用
解读云原生技术
2022暑期项目实训(二)
Compilation principle - top-down analysis and recursive descent analysis construction (notes)
D binding function
Maixll-Dock 摄像头使用
Cobra 快速入门 - 专为命令行程序而生
ADB common commands
Interview shock 62: what are the precautions for group by?
Dichotomy (integer dichotomy, real dichotomy)