ESP8266 RTOS學習之旅(5)— MQTT通信
一、前言
在上一節:ESP8266 RTOS學習之旅(4)— UDP通信和TCP客戶端通信 的基礎上,將ESP8266_RTOS_SDK-2.0.0\examples\mqtt_demo\
下出去user_main.c
的文件複製到app
目錄下(提示覆蓋則確認)。
因爲RTOS 2.0.0對MQTT的支持好像有問題,所以我拉取v2.1.1版本的代碼下來使用,樂鑫官方的倉庫:
git clone -b v2.1.1 https://github.com/espressif/ESP8266_RTOS_SDK.git
然後因爲github不穩定,特別是網速不夠的話經常出問題,所以我複製了一份代碼到gitee上:
git clone -b v2.1.1 https://gitee.com/william_william/ESP8266_RTOS_SDK.git
二、開始MQTT通信
還有一個問題就是,MQTT不支持斷線重連,所以我只好每隔5s發佈一個主題,當發佈不成功時,重新連接MQTT。編寫app_main.c
文件如下:
#include "esp_common.h"
#if !defined(MQTT_TASK)
#define MQTT_TASK
#endif
#include "lwip/sockets.h"
#include "mqtt/MQTTClient.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static void messageArrived(MessageData* data)
{
printf("topic Message arrived: \n%s\n", data->message->payload);
}
/* 1、定義一個MQTT客戶端結構體 */
MQTTClient client;
/* 2、網絡連接參數結構體 */
Network network;
/* 3、MQTT連接參數結構體 */
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
unsigned char sendbuf[80], readbuf[80] = {0};
int count = 0;
MQTTMessage message;
char payload[30];
void mqtt_connect(void)
{
/* 4、連接到mqtt服務器 */
int rc = NetworkConnect(&network, "39.96.35.207", 1883);
if (rc!= 0) {
printf("Return code from network connect is %d\n", rc);
}
#if defined(MQTT_TASK)
if ((rc = MQTTStartTask(&client)) != pdPASS) {
printf("Return code from start tasks is %d\n", rc);
} else {
printf("Use MQTTStartTask\n");
}
#endif
/* 5、設置MQTT連接參數 */
connectData.MQTTVersion = 3;
connectData.clientID.cstring = "ESP8266"; /* clientID */
connectData.username.cstring = "ESP8266"; /* 用戶名 */
connectData.password.cstring = "123456"; /* 用戶名密碼 */
/* 6、向mqtt服務器發送連接報文 */
rc = MQTTConnect(&client, &connectData);
if (rc != 0) {
printf("Return code from MQTT connect is %d\n", rc);
} else {
printf("MQTT Connected\n");
}
/* 7、訂閱一個主題 ,並設置訂閱主題回調函數 */
rc = MQTTSubscribe(&client, "ESP8266_Subscribe", QOS0, messageArrived);
if (rc != 0) {
printf("Return code from MQTT subscribe is %d\n", rc);
} else {
printf("MQTT subscribe to topic ESP8266_Subscribe OK\n");
}
}
int app_main(void)
{
int rc = 0;
client.defaultMessageHandler = messageArrived;
NetworkInit(&network);
MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));
while(1)
{
message.qos = QOS0;
message.retained = 0;
message.payload = payload;
sprintf(payload, "message number %d", count);
message.payloadlen = strlen(payload);
if ((rc = MQTTPublish(&client, "ESP8266_Publish", &message)) != 0) {
printf("Return code from MQTT publish is %d\n", rc);
mqtt_connect();
} else {
printf("MQTT publish topic ESP8266_Publish ok, message number is %d\n", count++);
}
vTaskDelay(5000 / portTICK_RATE_MS); //send every 1 seconds
}
return 0;
}
編譯下載運行,可以看到,連接MQTT服務器成功,訂閱和發佈主題也沒問題
打開EMQ的控制檯,可以看到,其連接成功
接收到了其發佈的主題