提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本系列将以0基础新手视角,完整演示从账号注册到云端数据可视化的全流程,涵盖数据流模型设计、MQTT协议配置及代码实现。建议搭配Arduino IDE 2.0+和ESP32-S3开发板使用。
(四)本文为ESP32-S3连接OneNET云平台的订阅主题与发布主题、消息(数据流)
本文仅仅是《数据上传与命令下发的验证》
注:此核心代码为基础版本,若需更深入的版本私聊。
一、核心代码
1.修改对应的《WiFi,密码,PRODUCT_ID,DEVICE_ID,TOKEN》,其他不用修改
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
/*云平台下发格式*/
/*
{
"TLED": {
"v": 1 // 1=开灯,0=关灯
}
}
*/
// 配置参数
const char* ssid = "your_wifi";/***************************WiFi名字****************************************/
const char* password = "your_password";/***************************密码****************************************/
const char* mqtt_server = "mqtts.heclouds.com";
const int mqtt_port = 1883;
/*************************PRODUCT_ID,DEVICE_ID,TOKEN***************************************/
#define PRODUCT_ID "/**/"
#define DEVICE_ID "/**/"
#define TOKEN "/**/"
#define TLED_PIN 5
// 数据定义
int msgId = 1;
float temp = 22.60;
int humi = 80;
int TLED_state = 0; // 测试灯
WiFiClient espClient;
PubSubClient client(espClient);
// MQTT主题 /*PRODUCT_ID为产品id,DEVICE_ID为设备名字*/
const char* pubTopic = "$sys/" PRODUCT_ID "/" DEVICE_ID "/dp/post/json";//发布主题
const char* subTopic = "$sys/" PRODUCT_ID "/" DEVICE_ID "/#";//订阅主题:
void setup() {
Serial.begin(115200);
pinMode(TLED_PIN, OUTPUT);
digitalWrite(TLED_PIN, TLED_state);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
client.setServer(mqtt_server, mqtt_port);
client.setCallback(mqttCallback);
mqttConnect();
}
void loop() {
if (!client.connected()) {
mqttConnect();
}
client.loop();
static unsigned long lastPost = 0;
if (millis() - lastPost >= 3000) { //上传云平台的时间间隔
postData();
lastPost = millis();
}
}
void mqttConnect() {
while (!client.connected()) {
if (client.connect(DEVICE_ID, PRODUCT_ID, TOKEN)) {
client.subscribe(subTopic);
Serial.println("Subscribed to control topic");
} else {
delay(5000);
}
}
}
void postData() {
JsonDocument doc;
if(msgId > 65535) msgId = 1;
doc["id"] = msgId++;
// 构建数据点
JsonObject dp = doc["dp"].to<JsonObject>();
// 温度数据点
JsonArray tempArr = dp["temp"].to<JsonArray>();
JsonObject tempObj = tempArr.add<JsonObject>();
tempObj["v"] = temp;
// 湿度数据点
JsonArray humiArr = dp["humi"].to<JsonArray>();
JsonObject humiObj = humiArr.add<JsonObject>();
humiObj["v"] = humi;
// TLED数据点
JsonArray ledArr = dp["TLED"].to<JsonArray>();
JsonObject ledObj = ledArr.add<JsonObject>();
ledObj["v"] = TLED_state;
// 序列化并发送
char payload[256];
serializeJson(doc, payload);
if (client.publish(pubTopic, payload)) {
Serial.println("Data sent:");
Serial.println(payload);
}
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String msg;
for (int i=0; i<length; i++) {
msg += (char)payload[i];
}
Serial.println("Received: " + msg);
// 解析TLED控制指令
JsonDocument doc;
deserializeJson(doc, msg);
if (doc.containsKey("TLED")) {
int newState = doc["TLED"]["v"];
if (newState != TLED_state) {
TLED_state = newState;
digitalWrite(TLED_PIN, TLED_state);
postData(); // 状态改变后立即上报
Serial.println("TLED changed to: " + String(TLED_state));
}
}
}
注意事项
代码中的temp与humi是直接定义的固定值,本文仅仅是《数据上传与命令下发的验证》
二、数据上传
三、命令下发
注意事项
- 响应时间,调成最小值就行,避免延迟太久。
- 下发命令的格式也不能变。
- 右边响应超时是正常情况,不影响命令的下发,控制开灯关灯
总结
本文讲解了ESP32-S3连接OneNET云平台的订阅主题与发布主题、消息(数据流)。