当前位置:网站首页>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 :
边栏推荐
- atcoder它A Mountaineer
- epoll()无论涉及wait队列分析
- 使用block实现两个页面之间的传统价值观
- Jerry is the custom background specified by the currently used dial enable [chapter]
- STM32+ESP8266+MQTT协议连接OneNet物联网平台
- Interview shock 62: what are the precautions for group by?
- 面向程序员的精品开源字体
- Shangsilicon Valley JUC high concurrency programming learning notes (3) multi thread lock
- Grafana 9.0 正式发布!堪称最强!
- [sword finger offer] 60 Points of N dice
猜你喜欢
Interesting - questions about undefined
微信为什么使用 SQLite 保存聊天记录?
44 colleges and universities were selected! Publicity of distributed intelligent computing project list
Take you through ancient Rome, the meta universe bus is coming # Invisible Cities
[swoole series 2.1] run the swoole first
C language exchanges two numbers through pointers
虚拟机VirtualBox和Vagrant安装
Comparative examples of C language pointers *p++, * (p++), * ++p, * (++p), (*p) + +, +(*p)
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
1700C - Helping the Nature
随机推荐
UDP协议:因性善而简单,难免碰到“城会玩”
阿里云国际版ECS云服务器无法登录宝塔面板控制台
TOP命令详解
Codeforces Round #803 (Div. 2)
Why does wechat use SQLite to save chat records?
POJ 2208 已知边四面体六个长度,计算体积
Common - magic number 7
30 分钟看懂 PCA 主成分分析
【.NET CORE】 请求长度过长报错解决方案
Reprint: defect detection technology of industrial components based on deep learning
用友OA漏洞学习——NCFindWeb 目录遍历漏洞
Will openeuler last long
從交互模型中蒸餾知識!中科大&美團提出VIRT,兼具雙塔模型的效率和交互模型的性能,在文本匹配上實現性能和效率的平衡!...
Markdown syntax for document editing (typera)
This article discusses the memory layout of objects in the JVM, as well as the principle and application of memory alignment and compression pointer
Cocos2d Lua smaller and smaller sample memory game
Release of the sample chapter of "uncover the secrets of asp.net core 6 framework" [200 pages /5 chapters]
Blue Bridge Cup real question: one question with clear code, master three codes
Echart simple component packaging
declval(指导函数返回值范例)