新人博主第一次寫blog,本文主要是對于MQTT協議報文和stm32的硬體、代碼層面進行講解,有不足的地方歡迎大家指正,
本人在學習MQTT協議時走了不少彎路,而且網路上對于STM32與MQTT通訊的資料少之又少,所以寫下本文供大家參考
前期準備
本次實驗材料主要有: STM32F103ZET6開發板/核心板+ESP8266開發板+n個led燈

上面這款ESP8266就可以,很方便使用
MQTT協議
基本原理
先講一下MQTT是怎么通訊的吧
MQTT共有3個角色和1個資料流:發布者(Publisher),訂閱者(Subscriber)、代理者(Broker)、主題(public)
相信大家都用過B站,我在這里做個比喻:b站用戶好比是訂閱者,up主是發布者,b站平臺是代理者
我們之間有這樣的關系:

我們先只看藍色部分就是一次MQTT通訊,up主發布視頻到視頻發布主題,b站服務器收到后通知用戶,
當然我們可以建立多個public進行雙向資料交流,互不干涉(筆者第一從想實作雙向通訊,當時只建立了一個主題,導致雙方的資料紊亂,大家記得避坑)
我們的STM32與EMQ服務器通訊也是同理,stm32(Pubilsher)與EMQ服務器的Websocket(Subscriber)同時訂閱一個主題,就可以實作將stm32資料傳輸到主題中,Websocket從主題中獲取資料
報文
由于報文內容太多,網路上的資料很詳細,這里不在詳細講解,想了解報文的同學可以移步mqtt報文決議—超詳細_不懂一休-CSDN博客_mqtt報文
筆者當時在學習報文的時候被搞得頭大,所以為了方便大家學習使用,在這里我們只講幾個簡單無腦常用的報文型別的寫法
CONNECT:
固定報頭:10 ??
此處?? 為剩余長度,即可變報頭長度+負載長度,通常是構建完可變報頭和負載才去計算的,舉個例子,如果剩余長度小于128,例如剩余長度=88,則此位為0x58,固定報頭為10 58 ,如果大于128,則固定報頭再加一個位元組為10 ?? ?? ,例如剩余長度為152,則第2位元組=152/128=1=0x01,第3位元組=152%128=24=0x18,固定報頭為 10 01 18,
ps:一定注意報文都是HEX(16進制)格式
可變報頭:00 04 4D 51 54 54 04 C2 00 64
負載報文:?? "客戶端ID" ?? "用戶名" ?? "密碼"
負載報文上的3個??分別為ID長度、用戶名長度、密碼長度,它們的計算方法與固定報頭中的剩余長度一樣,這里給大家舉一個簡單的例子
ID:123
用戶名:LOUIS
密碼:123456
則負載報文為:03 31 32 33 05 4C 4F 55 49 53 06 31 32 33 34 35 36
最終這個CONNECT報文就為:10 18 00 04 4D 51 54 54 04 C2 00 64 03 31 32 33 05 4C 4F 55 49 53 06 31 32 33 34 35 36
下面是connect報文資料的處理代碼
/*----------------------------------------------------------*/
/*函式名:連接服務器報文 */
/*參 數:無 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void MQTT_ConectPack(void)
{
int temp,Remaining_len;
Fixed_len = 1; //連接報文中,固定報頭長度暫時先=1
Variable_len = 10; //連接報文中,可變報頭長度=10
Payload_len = 2 + ClientID_len + 2 + Username_len + 2 + Passward_len; //連接報文中,負載長度
Remaining_len = Variable_len + Payload_len; //剩余長度=可變報頭長度+負載長度
temp_buff[0]=0x10; //固定報頭第1個位元組 :固定0x01
do{ //回圈處理固定報頭中的剩余長度位元組,位元組量根據剩余位元組的真實長度變化
temp = Remaining_len%128; //剩余長度取余128
Remaining_len = Remaining_len/128; //剩余長度取整128
if(Remaining_len>0)
temp |= 0x80; //按協議要求位7置位
temp_buff[Fixed_len] = temp; //剩余長度位元組記錄一個資料
Fixed_len++; //固定報頭總長度+1
}while(Remaining_len>0); //如果Remaining_len>0的話,再次進入回圈
temp_buff[Fixed_len+0]=0x00; //可變報頭第1個位元組 :固定0x00
temp_buff[Fixed_len+1]=0x04; //可變報頭第2個位元組 :固定0x04
temp_buff[Fixed_len+2]=0x4D; //可變報頭第3個位元組 :固定0x4D
temp_buff[Fixed_len+3]=0x51; //可變報頭第4個位元組 :固定0x51
temp_buff[Fixed_len+4]=0x54; //可變報頭第5個位元組 :固定0x54
temp_buff[Fixed_len+5]=0x54; //可變報頭第6個位元組 :固定0x54
temp_buff[Fixed_len+6]=0x04; //可變報頭第7個位元組 :固定0x04
temp_buff[Fixed_len+7]=0xC2; //可變報頭第8個位元組 :使能用戶名和密碼校驗,不使用遺囑,不保留會話
temp_buff[Fixed_len+8]=0x00; //可變報頭第9個位元組 :保活時間高位元組 0x00
temp_buff[Fixed_len+9]=0x64; //可變報頭第10個位元組:保活時間高位元組 0x64 100s
/* CLIENT_ID */
temp_buff[Fixed_len+10] = ClientID_len/256; //客戶端ID長度高位元組
temp_buff[Fixed_len+11] = ClientID_len%256; //客戶端ID長度低位元組
memcpy(&temp_buff[Fixed_len+12],ClientID,ClientID_len); //復制過來客戶端ID字串
/* 用戶名 */
temp_buff[Fixed_len+12+ClientID_len] = Username_len/256; //用戶名長度高位元組
temp_buff[Fixed_len+13+ClientID_len] = Username_len%256; //用戶名長度低位元組
memcpy(&temp_buff[Fixed_len+14+ClientID_len],Username,Username_len); //復制過來用戶名字串
/* 密碼 */
temp_buff[Fixed_len+14+ClientID_len+Username_len] = Passward_len/256; //密碼長度高位元組
temp_buff[Fixed_len+15+ClientID_len+Username_len] = Passward_len%256; //密碼長度低位元組
memcpy(&temp_buff[Fixed_len+16+ClientID_len+Username_len],Passward,Passward_len); //復制過來密碼字串
TxDataBuf_Deal(temp_buff, Fixed_len + Variable_len + Payload_len); //加入發送資料緩沖區
}
Subscribe:
固定:82 ??(此處為剩余長度與connect同理計算)
可變:00 01
負載:?? "主題名" 00 (此處00為訂閱等級Qs0)(計算與connect負載同理)
/*----------------------------------------------------------*/
/*函式名:SUBSCRIBE訂閱topic報文 */
/*參 數:QoS:訂閱等級 */
/*參 數:topic_name:訂閱topic報文名稱 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void MQTT_Subscribe(char *topic_name, int QoS)
{
Fixed_len = 2; //SUBSCRIBE報文中,固定報頭長度=2
Variable_len = 2; //SUBSCRIBE報文中,可變報頭長度=2
Payload_len = 2 + strlen(topic_name) + 1; //計算有效負荷長度 = 2位元組(topic_name長度)+ topic_name字串的長度 + 1位元組服務等級
temp_buff[0]=0x82; //第1個位元組 :固定0x82
temp_buff[1]=Variable_len + Payload_len; //第2個位元組 :可變報頭+有效負荷的長度
temp_buff[2]=0x00; //第3個位元組 :報文識別符號高位元組,固定使用0x00
temp_buff[3]=0x01; //第4個位元組 :報文識別符號低位元組,固定使用0x01
temp_buff[4]=strlen(topic_name)/256; //第5個位元組 :topic_name長度高位元組
temp_buff[5]=strlen(topic_name)%256; //第6個位元組 :topic_name長度低位元組
memcpy(&temp_buff[6],topic_name,strlen(topic_name)); //第7個位元組開始 :復制過來topic_name字串
temp_buff[6+strlen(topic_name)]=QoS; //最后1個位元組:訂閱等級
TxDataBuf_Deal(temp_buff, Fixed_len + Variable_len + Payload_len); //加入發送資料緩沖區
}
PING:
固定:C0 00
/*----------------------------------------------------------*/
/*函式名:PING報文,心跳包 */
/*參 數:無 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void MQTT_PingREQ(void)
{
temp_buff[0]=0xC0; //第1個位元組 :固定0xC0
temp_buff[1]=0x00; //第2個位元組 :固定0x00
TxDataBuf_Deal(temp_buff, 2); //加入資料到緩沖區
}
Publish:
固定:30 ??
可變:?? "主題名"
??為主題名的長度
負載:?? "要發送的資料"
??為資料的長度
/*----------------------------------------------------------*/
/*函式名:等級0 發布訊息報文 */
/*參 數:topic_name:topic名稱 */
/*參 數:data:資料 */
/*參 數:data_len:資料長度 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void MQTT_PublishQs0(char *topic, char *data, int data_len)
{
int temp,Remaining_len;
Fixed_len = 1; //固定報頭長度暫時先等于:1位元組
Variable_len = 2 + strlen(topic); //可變報頭長度:2位元組(topic長度)+ topic字串的長度
Payload_len = data_len; //有效負荷長度:就是data_len
Remaining_len = Variable_len + Payload_len; //剩余長度=可變報頭長度+負載長度
temp_buff[0]=0x30; //固定報頭第1個位元組 :固定0x30
do{ //回圈處理固定報頭中的剩余長度位元組,位元組量根據剩余位元組的真實長度變化
temp = Remaining_len%128; //剩余長度取余128
Remaining_len = Remaining_len/128; //剩余長度取整128
if(Remaining_len>0)
temp |= 0x80; //按協議要求位7置位
temp_buff[Fixed_len] = temp; //剩余長度位元組記錄一個資料
Fixed_len++; //固定報頭總長度+1
}while(Remaining_len>0); //如果Remaining_len>0的話,再次進入回圈
temp_buff[Fixed_len+0]=strlen(topic)/256; //可變報頭第1個位元組 :topic長度高位元組
temp_buff[Fixed_len+1]=strlen(topic)%256; //可變報頭第2個位元組 :topic長度低位元組
memcpy(&temp_buff[Fixed_len+2],topic,strlen(topic)); //可變報頭第3個位元組開始 :拷貝topic字串
memcpy(&temp_buff[Fixed_len+2+strlen(topic)],data,data_len); //有效負荷:拷貝data資料
TxDataBuf_Deal(temp_buff, Fixed_len + Variable_len + Payload_len); //加入發送資料緩沖區
}
處理Publisher發送的命令,筆者這里用的是EMQ個人服務器所以Publisher發的報文相對簡單
只有長度+資料的格式
下面是對收到的資料的處理
*----------------------------------------------------------*/
/*函式名:處理服務器發來的等級0的推送 */
/*參 數:redata:接收的資料 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void MQTT_DealPushdata_Qs0(unsigned char *redata)
{
int re_len; //定義一個變數,存放接收的資料總長度
int pack_num; //定義一個變數,當多個推送一起過來時,保存推送的個數
int temp,temp_len; //定義一個變數,暫存資料
int totle_len; //定義一個變數,存放已經統計的推送的總資料量
int topic_len; //定義一個變數,存放推送中主題的長度
int cmd_len; //定義一個變數,存放推送中包含的命令資料的長度
int cmd_loca; //定義一個變數,存放推送中包含的命令的起始位置
int i; //定義一個變數,用于for回圈
int local,multiplier;
unsigned char tempbuff[RBUFF_UNIT]; //臨時緩沖區
unsigned char *data; //redata過來的時候,第一個位元組是資料總量,data用于指向redata的第2個位元組,真正的資料開始的地方
re_len = redata[0]*256+redata[1]; //獲取接收的資料總長度
data = &redata[2]; //data指向redata的第2個位元組,真正的資料開始的
pack_num = temp_len = totle_len = temp = 0; //各個變數清零
local = 1;
multiplier = 1;
do{
pack_num++; //開始回圈統計推送的個數,每次回圈推送的個數+1
do{
temp = data[totle_len + local];
temp_len += (temp & 127) * multiplier;
multiplier *= 128;
local++;
}while ((temp & 128) != 0);
totle_len += (temp_len + local); //累計統計的總的推送的資料長度
re_len -= (temp_len + local) ; //接收的資料總長度 減去 本次統計的推送的總長度
local = 1;
multiplier = 1;
temp_len = 0;
}while(re_len!=0); //如果接收的資料總長度等于0了,說明統計完畢了
u1_printf("本次接收了%d個推送資料\r\n",pack_num);//串口輸出資訊
temp_len = totle_len = 0; //各個變數清零
local = 1;
multiplier = 1;
for(i=0;i<pack_num;i++){ //已經統計到了接收的推送個數,開始for回圈,取出每個推送的資料
do{
temp = data[totle_len + local];
temp_len += (temp & 127) * multiplier;
multiplier *= 128;
local++;
}while ((temp & 128) != 0);
topic_len = data[local+totle_len]*256+data[local+1+totle_len] + 2; //計算本次推送資料中主題占用的資料量
cmd_len = temp_len-topic_len; //計算本次推送資料中命令資料占用的資料量
cmd_loca = totle_len + local + topic_len; //計算本次推送資料中命令資料開始的位置
memcpy(tempbuff,&data[cmd_loca],cmd_len); //命令資料拷貝出來
CMDBuf_Deal(tempbuff, cmd_len); //加入命令到緩沖區
totle_len += (temp_len+local); //累計已經統計的推送的資料長度
local = 1;
multiplier = 1;
temp_len = 0;
}
}
初始化
下面是各部分緩沖區初始化,及上面函式中變數的相關定義
#include "stm32f10x.h"
#include "mqtt.h"
#include "string.h"
#include "stdio.h"
#include "usart1.h"
#include "wifi.h"
unsigned char MQTT_RxDataBuf[R_NUM][RBUFF_UNIT]; //資料的接識訓沖區,所有服務器發來的資料,存放在該緩沖區,緩沖區第一個位元組存放資料長度
unsigned char *MQTT_RxDataInPtr; //指向接識訓沖區存放資料的位置
unsigned char *MQTT_RxDataOutPtr; //指向接識訓沖區讀取資料的位置
unsigned char *MQTT_RxDataEndPtr; //指向接識訓沖區結束的位置
unsigned char MQTT_TxDataBuf[T_NUM][TBUFF_UNIT]; //資料的發送緩沖區,所有發往服務器的資料,存放在該緩沖區,緩沖區第一個位元組存放資料長度
unsigned char *MQTT_TxDataInPtr; //指向發送緩沖區存放資料的位置
unsigned char *MQTT_TxDataOutPtr; //指向發送緩沖區讀取資料的位置
unsigned char *MQTT_TxDataEndPtr; //指向發送緩沖區結束的位置
unsigned char MQTT_CMDBuf[C_NUM][CBUFF_UNIT]; //命令資料的接識訓沖區
unsigned char *MQTT_CMDInPtr; //指向命令緩沖區存放資料的位置
unsigned char *MQTT_CMDOutPtr; //指向命令緩沖區讀取資料的位置
unsigned char *MQTT_CMDEndPtr; //指向命令緩沖區結束的位置
char ClientID[128]; //存放客戶端ID的緩沖區
int ClientID_len; //存放客戶端ID的長度
char Username[128]; //存放用戶名的緩沖區
int Username_len; //存放用戶名的長度
char Passward[128]; //存放密碼的緩沖區
int Passward_len; //存放密碼的長度
char ServerIP[128]; //存放服務器IP或是域名
int ServerPort; //存放服務器的埠號
int Fixed_len; //固定報頭長度
int Variable_len; //可變報頭長度
int Payload_len; //有效負荷長度
unsigned char temp_buff[TBUFF_UNIT]; //臨時緩沖區,構建報文用
char Ping_flag; //ping報文狀態 0:正常狀態,等待計時時間到,發送Ping報文
//ping報文狀態 1:Ping報文已發送,當收到 服務器回復報文的后 將1置為0
char Connect_flag; //同服務器連接狀態 0:還沒有連接服務器 1:連接上服務器了
char ConnectPack_flag; //CONNECT報文狀態 1:CONNECT報文成功
char SubcribePack_flag; //訂閱報文狀態 1:訂閱報文成功
/*----------------------------------------------------------*/
/*函式名:初始化接收,發送,命令資料的 緩沖區 以及各狀態引數 */
/*參 數:無 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void MQTT_Buff_Init(void)
{
MQTT_RxDataInPtr=MQTT_RxDataBuf[0]; //指向發送緩沖區存放資料的指標歸位
MQTT_RxDataOutPtr=MQTT_RxDataInPtr; //指向發送緩沖區讀取資料的指標歸位
MQTT_RxDataEndPtr=MQTT_RxDataBuf[R_NUM-1]; //指向發送緩沖區結束的指標歸位
MQTT_TxDataInPtr=MQTT_TxDataBuf[0]; //指向發送緩沖區存放資料的指標歸位
MQTT_TxDataOutPtr=MQTT_TxDataInPtr; //指向發送緩沖區讀取資料的指標歸位
MQTT_TxDataEndPtr=MQTT_TxDataBuf[T_NUM-1]; //指向發送緩沖區結束的指標歸位
MQTT_CMDInPtr=MQTT_CMDBuf[0]; //指向命令緩沖區存放資料的指標歸位
MQTT_CMDOutPtr=MQTT_CMDInPtr; //指向命令緩沖區讀取資料的指標歸位
MQTT_CMDEndPtr=MQTT_CMDBuf[C_NUM-1]; //指向命令緩沖區結束的指標歸位
MQTT_ConectPack(); //發送緩沖區添加連接報文
MQTT_Subscribe(S_TOPIC_NAME,0); //發送緩沖區添加訂閱topic,等級0
Ping_flag = ConnectPack_flag = SubcribePack_flag = 0; //各個引數清零
}
/*----------------------------------------------------------*/
/*函式名:云初始化引數,得到客戶端ID,用戶名和密碼 */
/*參 數:無 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void IoT_Parameter_Init(void)
{
memset(ClientID,128,0); //客戶端ID的緩沖區全部清零
sprintf(ClientID,"%s",DEVICEID); //構建客戶端ID,并存入緩沖區
ClientID_len = strlen(ClientID); //計算客戶端ID的長度
memset(Username,128,0); //用戶名的緩沖區全部清零
sprintf(Username,"%s",PRODUCTID); //構建用戶名,并存入緩沖區
Username_len = strlen(Username); //計算用戶名的長度
memset(Passward,128,0); //用戶名的緩沖區全部清零
sprintf(Passward,"%s",AUTHENTICATION); //構建密碼,并存入緩沖區
Passward_len = strlen(Passward); //計算密碼的長度
memset(ServerIP,0,128);
sprintf(ServerIP,"%s","39.104.27.119"); //構建服務器域名
ServerPort = 1883; //服務器埠號1883
u1_printf("服 務 器:%s:%d\r\n",ServerIP,ServerPort); //串口輸出除錯資訊
u1_printf("客戶端ID:%s\r\n",ClientID); //串口輸出除錯資訊
u1_printf("用 戶 名:%s\r\n",Username); //串口輸出除錯資訊
u1_printf("密 碼:%s\r\n",Passward); //串口輸出除錯資訊
}
/*----------------------------------------------------------*/
/*函式名:處理發送緩沖區 */
/*參 數:data:資料 */
/*參 數:size:資料長度 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void TxDataBuf_Deal(unsigned char *data, int size)
{
memcpy(&MQTT_TxDataInPtr[2],data,size); //拷貝資料到發送緩沖區
MQTT_TxDataInPtr[0] = size/256; //記錄資料長度
MQTT_TxDataInPtr[1] = size%256; //記錄資料長度
MQTT_TxDataInPtr+=TBUFF_UNIT; //指標下移
if(MQTT_TxDataInPtr==MQTT_TxDataEndPtr) //如果指標到緩沖區尾部了
MQTT_TxDataInPtr = MQTT_TxDataBuf[0]; //指標歸位到緩沖區開頭
}
/*----------------------------------------------------------*/
/*函式名:處理命令緩沖區 */
/*參 數:data:資料 */
/*參 數:size:資料長度 */
/*回傳值:無 */
/*----------------------------------------------------------*/
void CMDBuf_Deal(unsigned char *data, int size)
{
memcpy(&MQTT_CMDInPtr[2],data,size); //拷貝資料到命令緩沖區
MQTT_CMDInPtr[0] = size/256; //記錄資料長度
MQTT_CMDInPtr[1] = size%256; //記錄資料長度
MQTT_CMDInPtr[size+2] = '\0'; //加入字串結束符
MQTT_CMDInPtr+=CBUFF_UNIT; //指標下移
if(MQTT_CMDInPtr==MQTT_CMDEndPtr) //如果指標到緩沖區尾部了
MQTT_CMDInPtr = MQTT_CMDBuf[0]; //指標歸位到緩沖區開頭
}
頭檔案
為了方便大家使用代碼筆者順便把mqtt頭檔案貼出來吧
#ifndef __MQTT_H
#define __MQTT_H
#define R_NUM 5 //接識訓沖區個數
#define RBUFF_UNIT 300 //接識訓沖區長度
#define T_NUM 5 //發送緩沖區個數
#define TBUFF_UNIT 300 //發送緩沖區長度
#define C_NUM 5 //命令緩沖區個數
#define CBUFF_UNIT 300 //命令緩沖區長度
#define MQTT_TxData(x) u2_TxData(x) //串口2負責資料發送
#define PRODUCTID "Car001" //ID
#define PRODUCTID_LEN strlen(PRODUCTID) //ID長度
#define DEVICEID "OurIoT" //用戶名
#define DEVICEID_LEN strlen(DEVICEID) //用戶名長度
#define AUTHENTICATION "000000" //密碼
#define AUTHENTICATION_LEN strlen(AUTHENTICATION) //密碼長度
#define S_TOPIC_NAME "t/c" //需要訂閱的主題
#define P_TOPIC_NAME "t/v" //需要發布的主題
extern unsigned char MQTT_RxDataBuf[R_NUM][RBUFF_UNIT]; //外部變數宣告,資料的接識訓沖區,所有服務器發來的資料,存放在該緩沖區,緩沖區第一個位元組存放資料長度
extern unsigned char *MQTT_RxDataInPtr; //外部變數宣告,指向緩沖區存放資料的位置
extern unsigned char *MQTT_RxDataOutPtr; //外部變數宣告,指向緩沖區讀取資料的位置
extern unsigned char *MQTT_RxDataEndPtr; //外部變數宣告,指向緩沖區結束的位置
extern unsigned char MQTT_TxDataBuf[T_NUM][TBUFF_UNIT]; //外部變數宣告,資料的發送緩沖區,所有發往服務器的資料,存放在該緩沖區,緩沖區第一個位元組存放資料長度
extern unsigned char *MQTT_TxDataInPtr; //外部變數宣告,指向緩沖區存放資料的位置
extern unsigned char *MQTT_TxDataOutPtr; //外部變數宣告,指向緩沖區讀取資料的位置
extern unsigned char *MQTT_TxDataEndPtr; //外部變數宣告,指向緩沖區結束的位置
extern unsigned char MQTT_CMDBuf[C_NUM][CBUFF_UNIT]; //外部變數宣告,命令資料的接識訓沖區
extern unsigned char *MQTT_CMDInPtr; //外部變數宣告,指向緩沖區存放資料的位置
extern unsigned char *MQTT_CMDOutPtr; //外部變數宣告,指向緩沖區讀取資料的位置
extern unsigned char *MQTT_CMDEndPtr; //外部變數宣告,指向緩沖區結束的位置
extern char ClientID[128]; //外部變數宣告,存放客戶端ID的緩沖區
extern int ClientID_len; //外部變數宣告,存放客戶端ID的長度
extern char Username[128]; //外部變數宣告,存放用戶名的緩沖區
extern int Username_len; //外部變數宣告,存放用戶名的長度
extern char Passward[128]; //外部變數宣告,存放密碼的緩沖區
extern int Passward_len; //外部變數宣告,存放密碼的長度
extern char ServerIP[128]; //外部變數宣告,存放服務器IP或是域名
extern int ServerPort; //外部變數宣告,存放服務器的埠號
extern char Ping_flag; //外部變數宣告,ping報文狀態 0:正常狀態,等待計時時間到,發送Ping報文
//外部變數宣告,ping報文狀態 1:Ping報文已發送,當收到 服務器回復報文的后 將1置為0
extern char Connect_flag; //外部變數宣告,同服務器連接狀態 0:還沒有連接服務器 1:連接上服務器了
extern char ReConnect_flag; //外部變數宣告,重連服務器狀態 0:連接還存在 1:連接斷開,重連
extern char ConnectPack_flag; //外部變數宣告,CONNECT報文狀態 1:CONNECT報文成功
extern char SubcribePack_flag; //外部變數宣告,訂閱報文狀態 1:訂閱報文成功
void MQTT_Buff_Init(void);
void IoT_Parameter_Init(void);
void MQTT_ConectPack(void);
void MQTT_Subscribe(char *, int);
void MQTT_PingREQ(void);
void MQTT_PublishQs0(char *, char *, int);
void MQTT_DealPushdata_Qs0(unsigned char *);
void TxDataBuf_Deal(unsigned char *, int);
void CMDBuf_Deal(unsigned char *, int);
#endif
本節主要講解了報文的資料發送處理,之后會更新esp8266如何連接mqtt服務器,以及stm32對服務器命令的相關處理,最終實作服務器控制點燈,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/290361.html
標籤:其他
上一篇:真實世界中的網路與圖模型
下一篇:圖形繪制——pygame之旅
