基于Arduino的ESP8266连接OneNET云平台(MQTT协议 物模型)(二)连接云平台

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本系列将以0基础新手视角,完整演示Arduino+ESP8266连接OneNET云平台的全流程,涵盖ESP8266固件烧录、物模型的模型设计、MQTT协议配置及代码实现。建议搭配Arduino IDE 2.0+和Arduino开发板使用。

(二)本文为arduino连接ESP8266(ESP-01S)

前文为,ESP8266模块的测试以及MQTT固件的烧录,不可缺少。

一、前期准备

1.1 硬件配置

需准备Arduino开发板 和 ESP8266

1.2 软件环境配置

安装Arduino IDE 2.0.2
安装 EspSoftwareSerial 库(工具→库管理→搜索EspSoftwareSerial→安装)

二、接线

注:arduino的 5V 给ESP8266的3.3V 供电,不然电压可能不够。

代码中的这句话是指 arduino的软串口,RX为9,TX为10;此时我们用ESP8266的TX接9,RX接10
SoftwareSerial espSerial(9, 10);  // RX=9, TX=10  注意前面的是指arduino的TRX,连线时候ESP8266的TX应接9,RX接10
arduino unoESP8266
5V3.3V 和 EN(即CH_PD)
10RX
9TX
GNDGND

再从 引脚5 引出一根导线,连接 小电阻→LED灯→GND
以备之后测试云平台下发

三、核心代码

3.1 总代码

替换

const char* WIFI_SSID = "Xiaomi 15";
const char* WIFI_PWD = "147258369";
// OneNET参数
#define PRODUCT_ID "1SX9Lm39T5"
#define DEVICE_NAME "arduino"
#define TOKEN "version=2018-10-31&res=products%2F1SX

代码:

#include <SoftwareSerial.h>
#include <ArduinoJson.h>


// 网络配置
const char* WIFI_SSID = "Xiaomi 15";
const char* WIFI_PWD = "147258369";
const char* MQTT_SERVER = "mqtts.heclouds.com";


// OneNET 物联参数
const int MQTT_PORT = 1883;
#define PRODUCT_ID "1SX9Lm39T5"
#define DEVICE_NAME "arduino"
#define TOKEN "version=2018-10-31&res=products%2F1SX9Lm39T5%2Fdevices%2Farduino&et=2059472864&method=md5&sign=F5DI%2FHUhIdIeZx1CUsR%2ByQ%3D%3D"
// 硬件配置
SoftwareSerial espSerial(9, 10);  // RX=9, TX=10  注意前面的是指arduino的TRX,连线时候ESP8266的TX应接9,RX接10
#define TLED_PIN 5                   // LED控制引脚

// 全局变量
const unsigned long readInterval = 3000;// 数据上报周期(ms)
int postMsgId = 0;       // 消息序列号
float temp = 20.25;      // 温度值
bool TLED_state = true;  // LED开关状态



//前置函数声明
bool sendATCommand(const char* cmd, const char* ack, unsigned int timeout);

void initESP8266();
void initSwitch();
void Post_Sensor();
void Post_Switch();

void setup() {
  Serial.begin(9600);    // 调试串口
  espSerial.begin(9600); // ESP8266通信
  initESP8266();
  initSwitch();


}
void loop() {

  handleMQTTMessage();

  // 定时上传数据
  static unsigned long lastPost = 0;
  if (millis() - lastPost >= readInterval) {
    Post_Switch();
   // Post_Sensor();
    lastPost = millis();
  }
}

// AT指令发送函数(带超时检测)
bool sendATCommand(const char* cmd, const char* ack, unsigned int timeout) {
  espSerial.println(cmd);
  unsigned long start = millis();
  String response;
  
  while (millis() - start < timeout) {
    while (espSerial.available()) {
      char c = espSerial.read();
      response += c;
    }
    if (response.indexOf(ack) != -1) {
      Serial.print("[SUCCESS] ");
      Serial.println(cmd);
      return true;
    }
  }
  Serial.print("[ERROR] ");
  Serial.print(cmd);
  Serial.println(" 未收到预期响应");
  return false;
}

void initESP8266(){
  // 初始化ESP8266
  sendATCommand("AT", "OK", 2000);
//  sendATCommand("AT+RST", "ready", 8000); 
  sendATCommand("AT+CWMODE=1", "OK", 1000);
  sendATCommand("AT+CWDHCP=1,1", "OK", 1000);
  
  // 连接WiFi
  String cmd = "AT+CWJAP=\"" + String(WIFI_SSID) + "\",\"" + String(WIFI_PWD) + "\"";
  sendATCommand(cmd.c_str(), "OK", 5000);\
  // 配置MQTT
  String mqttCfg = "AT+MQTTUSERCFG=0,1,\"" + String(DEVICE_NAME) + "\",\"" + String(PRODUCT_ID) + "\",\"" + String(TOKEN) + "\",0,0,\"\"";
  sendATCommand(mqttCfg.c_str(), "OK", 5000);

  // 连接服务器
  String connCmd = "AT+MQTTCONN=0,\"" + String(MQTT_SERVER) + "\"," + String(MQTT_PORT) + ",1";
  sendATCommand(connCmd.c_str(), "OK", 5000);

  
   // 添加订阅命令(在MQTT连接成功后)
   String subscribeCmd = "AT+MQTTSUB=0,\"$sys/" + String(PRODUCT_ID) + "/" + String(DEVICE_NAME) + "/thing/property/set\",1";
  sendATCommand(subscribeCmd.c_str(), "OK", 2000);
}


void initSwitch(){
  pinMode(TLED_PIN, OUTPUT);
  digitalWrite(TLED_PIN, TLED_state);
}


void Post_Sensor(){
  postMsgId++;

  // 手动拼接字符串,双引号 \",逗号 \,,符合 ESP8266 的 AT 命令转义要求
  String jsonPayload = "\\\"id\\\":\\\"" + String(postMsgId) + "\\\"\\,"
                     + "\\\"version\\\":\\\"1.0\\\"\\,"
                     + "\\\"params\\\":{"
                     + "\\\"temp\\\":{\\\"value\\\":" + String(temp, 2) + "}\\,"
                     + "\\\"TLED\\\":{\\\"value\\\":" + (TLED_state ? "true" : "false") + "}"
                     + "}";

  jsonPayload = "{" + jsonPayload + "}";

  // 构造 MQTT 发布命令
  String pubCmd = "AT+MQTTPUB=0,\"$sys/" + String(PRODUCT_ID) + "/" + String(DEVICE_NAME)
                  + "/thing/property/post\",\"" + jsonPayload + "\",0,0";

  // 发送
  sendATCommand(pubCmd.c_str(), "OK", 3000);
}


void Post_Switch(){
  postMsgId++;

  // 手动拼接字符串,双引号 \",逗号 \,,符合 ESP8266 的 AT 命令转义要求
  String jsonPayload = "\\\"id\\\":\\\"" + String(postMsgId) + "\\\"\\,"
                     + "\\\"version\\\":\\\"1.0\\\"\\,"
                     + "\\\"params\\\":{"
                     + "\\\"temp\\\":{\\\"value\\\":" + String(temp, 2) + "}\\,"
                     + "\\\"TLED\\\":{\\\"value\\\":" + (TLED_state ? "true" : "false") + "}"
                     + "}";

  jsonPayload = "{" + jsonPayload + "}";

  // 构造 MQTT 发布命令
  String pubCmd = "AT+MQTTPUB=0,\"$sys/" + String(PRODUCT_ID) + "/" + String(DEVICE_NAME)
                  + "/thing/property/post\",\"" + jsonPayload + "\",0,0";

  // 发送
  sendATCommand(pubCmd.c_str(), "OK", 3000);


}

// 接收数据函数 ▼
void handleMQTTMessage() {
  while (espSerial.available()) {
    String message = espSerial.readStringUntil('\n');
    if (message.indexOf("+MQTTSUBRECV:") != -1) { // 检测到新消息
     Serial.print("收到原始消息:"); 
  Serial.println(message); // 调试输出

  // 提取JSON部分
  int jsonStart = message.indexOf('{');
  String jsonStr = message.substring(jsonStart);

     JsonDocument doc;
     DeserializationError error = deserializeJson(doc, jsonStr);

  if (!error) {
    if (doc["params"]["TLED"].as<bool>()) {
      digitalWrite(TLED_PIN, HIGH);
      TLED_state = true;
      Serial.println("✅ 已开灯");
    } else {
      digitalWrite(TLED_PIN, LOW);
      TLED_state = false;
      Serial.println("✅ 已关灯");
    }

    // 回复 set 指令
    int id = doc["id"] | 0; // 取出id进行回复(可选)
    String replyJson = String("{\\\"id\\\":\\\"") + id + "\\\",\\\"code\\\":200}";
    String cmd = "AT+MQTTPUB=0,\"$sys/" + String(PRODUCT_ID) + "/" + String(DEVICE_NAME) + "/thing/property/set/reply\",\"" + replyJson + "\",0,0";
       sendATCommand(cmd.c_str(), "OK", 1000);
  } 
  else {
    Serial.println("[ERROR] JSON解析失败");
  }
    }
  }
}


三、最终效果

串口上,会出现几个error,属于正常情况,如响应超时等
后续出现的success,就代表上传成功
若有问题,则重复上篇文章,使用USB转TTL,进行AT指令测试
在这里插入图片描述在这里插入图片描述在这里插入图片描述

总结

本文搭建了 基于Arduino的ESP8266连接OneNET云平台(MQTT协议 物模型)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

承前智

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值