当前位置:网站首页>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 :
边栏推荐
- 使用cpolar建立一个商业网站(1)
- F200 - UAV equipped with domestic open source flight control system based on Model Design
- 阿里云国际版ECS云服务器无法登录宝塔面板控制台
- 递归的方式
- Bonecp uses data sources
- 微信为什么使用 SQLite 保存聊天记录?
- Declval of template in generic programming
- Dichotomy (integer dichotomy, real dichotomy)
- Comparative examples of C language pointers *p++, * (p++), * ++p, * (++p), (*p) + +, +(*p)
- 监控界的最强王者,没有之一!
猜你喜欢
[Sun Yat sen University] information sharing of postgraduate entrance examination and re examination
SAP Fiori 应用索引大全工具和 SAP Fiori Tools 的使用介绍
[Android] kotlin code writing standardization document
Recursive way
從交互模型中蒸餾知識!中科大&美團提出VIRT,兼具雙塔模型的效率和交互模型的性能,在文本匹配上實現性能和效率的平衡!...
Docker安装Redis
Implementation of queue
监控界的最强王者,没有之一!
F200 - UAV equipped with domestic open source flight control system based on Model Design
The third season of Baidu online AI competition is coming in midsummer, looking for you who love AI!
随机推荐
D binding function
The third season of Baidu online AI competition is coming in midsummer, looking for you who love AI!
DOM Brief
【.NET CORE】 请求长度过长报错解决方案
Introduction to the usage of model view delegate principal-agent mechanism in QT
UFIDA OA vulnerability learning - ncfindweb directory traversal vulnerability
Redis的五种数据结构
解读云原生技术
Compilation principle - top-down analysis and recursive descent analysis construction (notes)
重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用
阿里云国际版ECS云服务器无法登录宝塔面板控制台
Implementation of queue
随着MapReduce job实现去加重,多种输出文件夹
Self supervised heterogeneous graph neural network with CO comparative learning
Codeforces Round #803 (Div. 2)
std::true_type和std::false_type
Reprint: defect detection technology of industrial components based on deep learning
A method of sequentially loading Unity Resources
十、进程管理
小程序在产业互联网中的作用