依赖 json工具
Arduino_JSON
#include <Arduino_JSON.h>
void setup() {
Serial.begin(9600);
// 创建一个 JSON 对象
JSONVar myObject;
myObject["name"] = "Arduino";
myObject["version"] = 1.0;
// 将 JSON 对象转换为字符串
String jsonString = JSON.stringify(myObject);
Serial.println(jsonString);
// 解析 JSON 字符串
JSONVar parsed = JSON.parse(jsonString);
if (JSON.typeof(parsed) == "undefined") {
Serial.println("Parsing failed!");
return;
}
Serial.print("Name: ");
Serial.println((const char*) parsed["name"]);
Serial.print("Version: ");
Serial.println((double) parsed["version"]);
}
ArduinoJson
#include <ArduinoJson.h>
void setup() {
Serial.begin(9600);
const char* json = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, json);
if (error) {
Serial.print("Failed to deserialize JSON: ");
Serial.println(error.f_str());
return;
}
const char* name = doc["name"];
int age = doc["age"];
const char* city = doc["city"];
Serial.print("Name: ");
Serial.println(name);
Serial.print("Age: ");
Serial.println(age);
Serial.print("City: ");
Serial.println(city);
}
完整示例
#include "header.cpp"
int count; // Ticker计数用变量
int pin = 0; // 设置一个变量代表控制继电器开关的GPIO
// int LED_BUILTIN = 2; led灯开关
// JSON 对象 wifi配置
JSONVar wifiConf;
// json 对象 mqtt配置
JSONVar mqttConf;
// 定时器
Ticker ticker;
// WiFi and MQTT client initialization
BearSSL::WiFiClientSecure espClient;
PubSubClient mqtt_client(espClient);
// Function declarations
void connectToWiFi();
void connectToMQTT();
void syncTime();
void mqttCallback(char *topic, byte *payload, unsigned int length);
// wifi 账号密码
void initWifiConfig() {
wifiConf["user"] = "hy1";
wifiConf["password"] = "13363641456";
}
// mqtt 配置
void initMqttConfig() {
mqttConf["mqtt_port"] = 8883;
// 去 EMQX 官网注册账号可以申请免费额度
mqttConf["mqtt_broker"] = "n9a7eff0.ala.cn-hangzhou.emqxsl.cn";
// 订阅主题
mqttConf["mqtt_subscribe_topic"] = "emqx/esp8266";
// 发布主题
mqttConf["mqtt_publish_topic"] = "emqx/esp8266";
// 用户名
mqttConf["mqtt_username"] = "test";
// 密码
mqttConf["mqtt_password"] = "test123456";
// NTP Server settings
mqttConf["ntp_server"] = "pool.ntp.org";// Recommended NTP server for users in China
mqttConf["gmt_offset_sec"] = 0; // GMT offset in seconds (adjust for your time zone)
mqttConf["daylight_offset_sec"] = 0;// Daylight saving time offset in seconds
// 每间隔多少秒发布一次当前状态
mqttConf["push_state_m"] = 20;
// SSL certificate for MQTT broker
// Load DigiCert Global Root G2, which is used by EMQX Public Broker: broker.emqx.io
// static const char ca_cert[]
// PROGMEM = R"EOF()EOF";
// 服务端的 ssl/tls ca证书
mqttConf["ca_cert"] = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
)EOF";
}
void initConfig() {
initWifiConfig();
initMqttConfig();
}
void tickerCount() {
count++;
}
void setup() {
Serial.begin(115200);
initConfig();
pinMode(LED_BUILTIN, OUTPUT); // 这里换成变量
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW); // GPIO0 低电平,吸合继电器,作为初始状态
// Ticker定时对象
ticker.attach(1, tickerCount);
//设置ESP8266工作模式为无线终端模式
WiFi.mode(WIFI_STA);
connectToWiFi();
syncTime(); // X.509 validation requires synchronization time
mqtt_client.setServer((const char *)mqttConf["mqtt_broker"], (const int)mqttConf["mqtt_port"]);
mqtt_client.setCallback(mqttCallback);
connectToMQTT();
}
void connectToWiFi() {
WiFi.begin((const char *)wifiConf["user"], (const char *)wifiConf["password"]);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
}
void syncTime() {
configTime((const long)mqttConf["gmt_offset_sec"], (const int)mqttConf["daylight_offset_sec"], (const char *)mqttConf["ntp_server"]);
Serial.print("Waiting for NTP time sync: ");
while (time(nullptr) < 8 * 3600 * 2) {
delay(1000);
Serial.print(".");
}
Serial.println("Time synchronized");
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
Serial.print("Current time: ");
Serial.println(asctime(&timeinfo));
} else {
Serial.println("Failed to obtain local time");
}
}
void connectToMQTT() {
BearSSL::X509List serverTrustedCA((const char *)mqttConf["ca_cert"]);
espClient.setTrustAnchors(&serverTrustedCA);
JSONVar mqttMsg;
while (!mqtt_client.connected()) {
// String client_id = "esp8266-client-" + String(WiFi.macAddress());
mqttMsg["client_id"] = "esp8266-client-" + String(WiFi.macAddress());
Serial.printf("Connecting to MQTT Broker as %s.....\n", ((String)mqttMsg["client_id"]).c_str());
if (mqtt_client.connect(((String)mqttMsg["client_id"]).c_str(), (const char *)mqttConf["mqtt_username"], (const char *)mqttConf["mqtt_password"])) {
Serial.println("Connected to MQTT broker");
mqttMsg["msg"] = "Hi EMQX I'm ESP8266";
mqttMsg["key"] = "connect";
mqtt_client.subscribe((const char *)mqttConf["mqtt_subscribe_topic"]);
// Publish message upon successful connection
// 将 JSON 对象转换为字符串
String jsonString = JSON.stringify(mqttMsg);
mqtt_client.publish((const char *)mqttConf["mqtt_publish_topic"], jsonString.c_str());
} else {
char err_buf[128];
espClient.getLastSSLError(err_buf, sizeof(err_buf));
Serial.print("Failed to connect to MQTT broker, rc=");
Serial.println(mqtt_client.state());
Serial.print("SSL error: ");
Serial.println(err_buf);
delay(5000);
}
}
}
// 发布上报针脚状态信息
void pubMQTTmsg() {
JSONVar mqttMsg;
// 建立发布主题。
// 定时向服务器主题发布当前GPIO0引脚状态
String state;
if (digitalRead(0)) {
mqttMsg["state"] = false; // 高电平断开继电器
} else {
mqttMsg["state"] = true; // 低电平吸合继电器
}
String jsonString = JSON.stringify(mqttMsg);
// 实现ESP8266向主题发布信息
if (mqtt_client.publish((const char *)mqttConf["mqtt_publish_topic"], jsonString.c_str())) {
Serial.print("Publish Topic: ");
Serial.println((const char *)mqttConf["mqtt_publish_topic"]);
Serial.print("Publish message: ");
Serial.println(jsonString.c_str());
} else {
Serial.println("Message Publish Failed.");
}
}
void mqttCallback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message received on topic: ");
Serial.print(topic);
Serial.print("]: ");
// 将获取到的pyte类payload消息转换为String类型的data
String jsonString = "";
for (int i = 0; i < length; i++) {
jsonString = jsonString + (char)payload[i];
}
Serial.println(jsonString);
// mqttRes=
// 解析 JSON 字符串
JSONVar parsed = JSON.parse(jsonString);
if (JSON.typeof(parsed) == "undefined") {
Serial.println("Parsing failed!");
return;
}
if (parsed["switch"] != null) {
Serial.println((String)parsed["switch"]);
if ((String)parsed["switch"] == "1") { // 如果收到的信息为"1",注意双引号为String,单引号为char
digitalWrite(LED_BUILTIN, LOW); // 则点亮LED。
digitalWrite(pin, LOW); // GPIO0 低电平,吸合继电器
} else {
digitalWrite(LED_BUILTIN, HIGH); // 否则熄灭LED。
digitalWrite(pin, HIGH); // GPIO0 高电平,断开继电器
}
}
}
// 状态持续函数,一直重复执行
void loop() {
if (!mqtt_client.connected()) {
// 建立链接
connectToMQTT();
} else {
// 每隔3秒钟发布一次信息,一般用于状态报告
if (count >= (int)mqttConf["push_state_m"]) {
pubMQTTmsg();
count = 0;
}
// 心跳
mqtt_client.loop();
}
}
// 使用
// 服务端向订阅主题发布 消息内容 {"switch": "1"} 1是开灯,否则是关灯
header.h
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <time.h>
#include <Ticker.h>
#include <Arduino_JSON.h>