Administrator
发布于 2025-12-01 / 21 阅读
0
0

如何使用ESP32对接thingsboard

ESP32 对接 ThingsBoard 是物联网开发的经典场景,核心流程是:ESP32 通过 MQTT 协议(推荐)连接 ThingsBoard → 上报传感器数据(遥测数据)→ 接收 ThingsBoard 下发的控制命令(RPC)。以下是详细的实操步骤,包含环境准备、代码编写、ThingsBoard 配置,新手也能快速上手:

一、对接前准备

1. 核心工具与环境

  • 硬件:ESP32 开发板(如 ESP32-DevKitC)、传感器(以 DHT11 温湿度传感器为例,可选)、USB 数据线;

  • 软件:Arduino IDE(或 PlatformIO)、ThingsBoard 平台(已部署在阿里云 ECS,参考你之前的配置);

  • 依赖库(Arduino 中安装):

    • ESP32WiFi:ESP32 无线连接库(内置,无需额外安装);

    • PubSubClient:MQTT 客户端库(用于与 ThingsBoard 通信);

    • DHT sensor library:DHT11/DHT22 传感器驱动库(若用其他传感器,安装对应驱动)。

2. ThingsBoard 前期配置(关键)

需在 ThingsBoard 中创建「设备」,获取连接凭证(设备访问令牌):

  1. 登录 ThingsBoard 后台(http://你的ECS IP:8080),用租户管理员账号登录;

  2. 左侧菜单 →「设备(Devices)」→ 右上角「+」添加设备;

  3. 填写设备名称(如「ESP32 - 温湿度传感器」),其他默认,点击「添加」;

  4. 设备创建后,点击设备名称进入详情页 →「凭证(Credentials)」→ 复制「设备访问令牌(Access token)」(后续代码中需用到)。

3. 网络与端口确认

  • ESP32 需连接能访问阿里云 ECS 的网络(如公司 Wi-Fi、手机热点,避免网络拦截);

  • ThingsBoard MQTT 默认端口:1883(TCP 明文)、8883(SSL 加密),确保 ECS 安全组已放行 1883 端口(之前已放行 8080,需额外添加 1883 入方向规则)。

二、核心步骤:ESP32 代码编写(Arduino IDE)

以下代码实现「ESP32 连接 Wi-Fi → 连接 ThingsBoard MQTT 服务器 → 周期性上报温湿度数据 → 接收 ThingsBoard RPC 控制命令(如控制 ESP32 板载 LED)」。

1. 代码整体结构

cpp

运行

#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>

// ------------------- 配置参数(必须修改为你的信息)-------------------
const char* WIFI_SSID = "你的Wi-Fi名称";       // 如 "Company-WiFi"
const char* WIFI_PASS = "你的Wi-Fi密码";       // 如 "12345678"
const char* TB_SERVER = "47.98.193.197";      // 你的阿里云ECS公网IP
const uint16_t TB_PORT = 1883;                // ThingsBoard MQTT默认端口
const char* DEVICE_TOKEN = "你的设备访问令牌"; // 从ThingsBoard设备凭证中复制
const int DHT_PIN = 4;                        // DHT11传感器数据引脚(接ESP32 GPIO4)
const int LED_PIN = 2;                        // ESP32板载LED引脚(默认GPIO2)
// -------------------------------------------------------------------

// 初始化传感器和MQTT客户端
DHT dht(DHT_PIN, DHT11); // DHT11传感器对象
WiFiClient espClient;
PubSubClient client(espClient); // MQTT客户端对象
unsigned long lastMsg = 0;     // 上次上报数据的时间戳
const long interval = 10000;   // 数据上报间隔(10秒)

// Wi-Fi连接函数
void connectWiFi() {
  Serial.print("连接Wi-Fi: ");
  Serial.println(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("Wi-Fi连接成功!IP地址:");
  Serial.println(WiFi.localIP());
}

// MQTT连接函数(连接ThingsBoard)
void connectMQTT() {
  while (!client.connected()) {
    Serial.print("连接ThingsBoard MQTT服务器...");
    // ThingsBoard MQTT连接规则:用户名留空,密码为设备访问令牌
    if (client.connect("ESP32-Device", DEVICE_TOKEN, "")) {
      Serial.println("连接成功!");
      // 订阅RPC命令主题(接收ThingsBoard下发的控制命令)
      client.subscribe("v1/devices/me/rpc/request/+");
    } else {
      Serial.print("连接失败,错误码:");
      Serial.println(client.state());
      delay(5000); // 5秒后重试
    }
  }
}

// MQTT消息回调函数(处理ThingsBoard下发的RPC命令)
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("收到命令:");
  Serial.print(topic);
  Serial.print(" -> ");
  String payloadStr;
  for (int i = 0; i < length; i++) {
    payloadStr += (char)payload[i];
  }
  Serial.println(payloadStr);

  // 解析RPC命令(示例:控制板载LED开关)
  // ThingsBoard下发的RPC命令格式:{"method":"setLED","params":{"state":true}}
  if (payloadStr.indexOf("setLED") > 0) {
    bool ledState = payloadStr.indexOf("true") > 0 ? HIGH : LOW;
    digitalWrite(LED_PIN, ledState);
    Serial.print("LED状态设置为:");
    Serial.println(ledState ? "亮" : "灭");

    // 向ThingsBoard回复RPC执行结果
    String responseTopic = String(topic) + "/response";
    String response = "{\"success\":true,\"data\":\"LED状态已更新为" + String(ledState) + "\"}";
    client.publish(responseTopic.c_str(), response.c_str());
  }
}

// 上报遥测数据到ThingsBoard
void sendTelemetry() {
  // 读取DHT11传感器数据
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  // 检查传感器数据是否有效
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("读取传感器数据失败!");
    return;
  }

  // 构造遥测数据JSON格式(ThingsBoard要求的格式)
  String telemetry = "{\"temperature\":" + String(temperature) + ",\"humidity\":" + String(humidity) + "}";
  Serial.print("上报数据:");
  Serial.println(telemetry);

  // 发布到ThingsBoard的遥测主题
  client.publish("v1/devices/me/telemetry", telemetry.c_str());
}

void setup() {
  Serial.begin(115200); // 初始化串口(调试用)
  pinMode(LED_PIN, OUTPUT); // 配置LED引脚为输出模式
  dht.begin(); // 初始化DHT11传感器

  // 连接Wi-Fi和MQTT
  connectWiFi();
  client.setServer(TB_SERVER, TB_PORT); // 设置ThingsBoard MQTT服务器地址和端口
  client.setCallback(callback); // 设置MQTT消息回调函数(接收RPC命令)
}

void loop() {
  // 若MQTT断开连接,自动重连
  if (!client.connected()) {
    connectMQTT();
  }
  client.loop(); // 维持MQTT连接,处理消息

  // 周期性上报遥测数据(间隔10秒)
  unsigned long currentMillis = millis();
  if (currentMillis - lastMsg > interval) {
    lastMsg = currentMillis;
    sendTelemetry();
  }
}

2. 代码关键配置说明(必须修改)

  • WIFI_SSID/WIFI_PASS:ESP32 要连接的 Wi-Fi 名称和密码(公司 Wi-Fi 或手机热点);

  • TB_SERVER:你的阿里云 ECS 公网 IP(如 47.98.193.197);

  • DEVICE_TOKEN:从 ThingsBoard 设备详情页复制的「设备访问令牌」(至关重要,错误会导致连接失败);

  • DHT_PIN:若未使用 DHT11 传感器,可删除传感器相关代码,直接上报模拟数据(如 temperature: 25.5)。

三、硬件接线(可选,若用 DHT11 传感器)

若需上报温湿度数据,按以下方式接线(ESP32 为 3.3V 供电,避免 5V 烧毁):

DHT11 引脚

ESP32 引脚

说明

VCC

3.3V

供电(3.3V)

GND

GND

接地

DATA

GPIO4

数据引脚(可自定义)

若没有传感器,可注释掉 dht 相关代码,在 sendTelemetry() 中直接写死数据(如 float temperature = 24.3;),仅测试连接功能。

四、上传代码与调试

  1. 打开 Arduino IDE,选择对应的 ESP32 开发板(如 ESP32 Dev Module)和端口(USB 连接后在设备管理器中查看);

  2. 点击「上传」按钮,将代码烧录到 ESP32;

  3. 打开串口监视器(波特率 115200),查看调试信息:

    • 若显示「Wi-Fi 连接成功!IP 地址:xxx.xxx.xxx.xxx」→ Wi-Fi 连接正常;

    • 若显示「连接 ThingsBoard MQTT 服务器... 连接成功!」→ MQTT 连接正常;

    • 若显示「上报数据:{"temperature":25.3,"humidity":60.5}」→ 数据上报成功。

五、ThingsBoard 端验证与操作

1. 查看设备在线状态

登录 ThingsBoard 后台 →「设备」→ 目标设备的「状态」显示为「在线」,说明 ESP32 已成功连接。

2. 查看上报的遥测数据

  • 设备详情页 →「遥测数据(Telemetry)」→ 可看到 ESP32 上报的 temperature(温度)和 humidity(湿度),支持实时刷新和历史数据查看。

3. 下发 RPC 控制命令(控制 ESP32 LED)

在 ThingsBoard 中向 ESP32 下发控制命令,测试双向通信:

  1. 设备详情页 →「RPC」→ 点击「+」新建 RPC 请求;

  2. 配置 RPC 命令:

    • 「方法(Method)」:setLED(需与 ESP32 代码中 callback 函数的解析逻辑一致);

    • 「参数(Params)」:{"state":true}(控制 LED 亮)或 {"state":false}(控制 LED 灭);

  3. 点击「执行(Execute)」,ESP32 板载 LED 会对应切换状态,同时串口监视器会打印命令接收日志。

六、常见问题排查(避坑指南)

1. MQTT 连接失败(串口显示「连接失败,错误码:x」)

  • 错误码 1:Wi-Fi 连接失败 → 检查 Wi-Fi 名称 / 密码,确保 ESP32 能访问外网;

  • 错误码 3:MQTT 服务器无法访问 → 检查 ECS 安全组是否放行 1883 端口,用 Telnet 47.98.193.197 1883 验证端口是否通;

  • 错误码 4:设备访问令牌错误 → 重新复制 ThingsBoard 设备的「Access token」,确保代码中无空格或拼写错误;

  • 公司网络拦截:切换到手机热点测试,排除公司防火墙对 MQTT(1883 端口)的拦截。

2. 数据上报成功,但 ThingsBoard 看不到

  • 遥测数据格式错误 → 确保 JSON 格式正确(无多余逗号,数值无引号),示例:{"temperature":25.5,"humidity":60}

  • 上报主题错误 → 必须是 v1/devices/me/telemetry(ThingsBoard 固定遥测主题)。

3. RPC 命令下发后,ESP32 无响应

  • 订阅主题错误 → 代码中需订阅 v1/devices/me/rpc/request/+(+ 表示匹配所有 RPC 请求 ID);

  • 命令格式不匹配 → 确保 ThingsBoard 下发的 methodparams 与 ESP32 代码中 callback 函数的解析逻辑一致。

七、进阶扩展(可选)

  1. SSL 加密连接:将 MQTT 端口改为 8883,启用 SSL 加密(更安全),需修改 WiFiClientWiFiClientSecure,代码调整如下:

    cpp

    运行

    #include <WiFiClientSecure.h>
    WiFiClientSecure espClient; // 替换 WiFiClient espClient;
    
  2. 上报更多数据:添加其他传感器(如光照传感器、土壤湿度传感器),在 sendTelemetry() 中扩展 JSON 字段;

  3. OTA 远程升级:结合 ESP32 的 OTA 功能,通过 ThingsBoard 或 HTTP 服务器远程更新 ESP32 固件;

  4. 规则引擎联动:在 ThingsBoard 中设置规则(如温度超过 30℃ 时发送邮件报警)。

总结

ESP32 对接 ThingsBoard 的核心是「MQTT 协议通信」,关键步骤:

  1. ThingsBoard 中创建设备,获取访问令牌;

  2. ESP32 连接 Wi-Fi 和 ThingsBoard MQTT 服务器;

  3. 按 ThingsBoard 格式上报遥测数据,订阅 RPC 主题接收控制命令。

按以上步骤操作,即可实现 ESP32 与 ThingsBoard 的双向通信,后续可基于此扩展智能硬件控制、数据监控等物联网应用。


评论