需要用到的庫:
PubSubClient : 發(fā)送和接收MQTT消息
ArduinoJson : Json字符串轉(zhuǎn)換庫
AliyunMqttArduino: 阿里云相關(guān)
先做一件事!!!!!!
引入'PubSubClient.h'后
#include 'PubSubClient.h'
打開'PubSubClient.h'
修改如下內(nèi)容:
一. 阿里云MQTT協(xié)議
關(guān)于MQTT協(xié)議, 請參考文章:https://zhuanlan.zhihu.com/p/89057819
請參考我之前整理的文檔:
【騰訊文檔】MQTT連接阿里云示例(1)https://docs.qq.com/sheet/DWXBaUE9nWmZVaGJX
如果使用了AliyunMqttArduino, 就不需要關(guān)系協(xié)議的報文和加密方式了
二. 主要函數(shù)
首先創(chuàng)建一個mqtt客戶端
WiFiClient espClient; //創(chuàng)建網(wǎng)絡(luò)連接客戶端PubSubClient mqttClient(espClient); //通過網(wǎng)絡(luò)客戶端連接創(chuàng)建mqtt連接客戶端
1. 連接阿里云 connectAliyunMQTT
connectAliyunMQTT(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET)
返回值: 連接結(jié)果
2. 判斷是否連接了 mqttClient.connected()
mqttClient.connected()
3. mqtt客戶端狀態(tài) mqttClient.state()
mqttClient.state()
返回: 狀態(tài)碼
狀態(tài)碼 | 含義 |
---|---|
0 | 連接成功 |
1 | 不正確的協(xié)議版本 |
2 | 無效的登錄信息 |
3 | 連接不上服務(wù)器 |
4 | 用戶名密碼錯誤 |
5 | 未授權(quán) |
6~255 | 備用 |
4. 發(fā)布主題消息
mqttClient.publish(主題, 內(nèi)容)
mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf)
5. setCallback-- 設(shè)置收到命令下發(fā)時的回調(diào)
mqttClient.setCallback(callback); //綁定收到set主題時的回調(diào)(命令下發(fā)回調(diào))
6. 客戶端監(jiān)聽消息隊列 mqttClient.loop();
三. 一個點燈的例子(創(chuàng)建產(chǎn)品和設(shè)備)
首先, 創(chuàng)建產(chǎn)品:
其次, 為產(chǎn)品添加設(shè)備
第三, 查看設(shè)備關(guān)鍵信息:
四. 一個點燈的例子(ESP32連接上述產(chǎn)品和設(shè)備)
#include delay(10); Serial.println('連接WIFI'); WiFi.begin(WIFI_SSID, WIFI_PASSWD); while (!WiFi.isConnected()) { Serial.print('.'); delay(500); } Serial.println('OK'); Serial.println('Wifi連接成功');}//重連函數(shù), 如果客戶端斷線,可以通過此函數(shù)重連void clientReconnect(){ while (!mqttClient.connected()) //再重連客戶端 { Serial.println('reconnect MQTT...'); if (connectAliyunMQTT(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET)) { Serial.println('connected'); } else { Serial.println('failed'); Serial.println(mqttClient.state()); Serial.println('try again in 5 sec'); delay(5000); } }}//mqtt發(fā)布post消息(上傳數(shù)據(jù))void mqttPublish(){ if (mqttClient.connected()) { //先拼接出json字符串 char param[32]; char jsonBuf[128]; sprintf(param, '{'LightSwitch':%d}', digitalRead(LED_B)); //我們把要上傳的數(shù)據(jù)寫在param里 postMsgId += 1; sprintf(jsonBuf, ALINK_BODY_FORMAT, postMsgId, ALINK_METHOD_PROP_POST, param); //再從mqtt客戶端中發(fā)布post消息 if (mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf)) { Serial.print('Post message to cloud: '); Serial.println(jsonBuf); } else { Serial.println('Publish message to cloud failed!'); } }}//收到set主題的命令下發(fā)時的回調(diào)函數(shù),(接收命令)void callback(char *topic, byte *payload, unsigned int length){ if (strstr(topic, ALINK_TOPIC_PROP_SET)) //如果收到的主題里包含字符串ALINK_TOPIC_PROP_SET(也就是收到/sys/a17lGhkKwXs/esp32LightHome/thing/service/property/set主題) { Serial.println('收到下發(fā)的命令主題:'); Serial.println(topic); Serial.println('下發(fā)的內(nèi)容是:'); payload[length] = '