news 2026/9/16 16:10:50

Wio Terminal 夜灯上云实战:通过 MQTT 向 Broker 发布 JSON 遥测数据(IoT-For-Beginners 第 4 课)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Wio Terminal 夜灯上云实战:通过 MQTT 向 Broker 发布 JSON 遥测数据(IoT-For-Beginners 第 4 课)

Wio Terminal 夜灯上云实战:通过 MQTT 向 Broker 发布 JSON 遥测数据(IoT-For-Beginners 第 4 课)

【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners

本篇技术指南聚焦于 IoT-For-Beginners 课程第 4 课「将设备连接到互联网」中 Wio Terminal 一节的遥测发布环节:在前一课完成 WiFi 与 MQTT 连接的基础上,为夜灯项目引入 ArduinoJson 库、定义遥测主题,并在loop中把光敏传感器读取到的光照强度序列化为 JSON 消息,发布到test.mosquitto.org公共 MQTT Broker。读完本文,你将掌握 Arduino 环境下 MQTT 遥测发布的完整链路——从platformio.ini依赖管理、config.h主题常量定义,到main.cppanalogReadDynamicJsonDocumentclient.publish的组合用法,并能在串口监视器中验证{"light":652}形式的遥测输出。

本环节的定位:从「连接上」到「发数据」

在 IoT-For-Beginners 的 第 4 课总览 中,遥测(Telemetry)被定义为「从传感器采集数据并发送到云端」的过程。整节课围绕一个远程可控的夜灯展开,整体分四个环节:

  1. 连接 MQTT Broker(对应 wio-terminal-mqtt.md);
  2. 发布遥测数据(本文主题)
  3. 服务端接收遥测并回发命令;
  4. 设备接收命令并控制 LED。

本文对应的是第 2 环节:设备把光敏传感器(WIO Terminal 板载WIO_LIGHT引脚)读取到的光照强度,通过 MQTT 发布到一个以ID + "/telemetry"命名的主题上。这里的ID是你为设备指定的唯一标识,用于确保在公共 Broker(test.mosquitto.org)上不会与其他学习者或设备的主题/客户端名冲突。该环节的完整可运行代码存放在仓库 code-telemetry/wio-terminal 目录下。

💡 公共测试 Brokertest.mosquitto.org无需注册账号即可使用,但它公开且不安全——任何人都有可能监听到你发布的消息,因此绝不能用它传输需要保密的私有数据。

安装 ArduinoJson 库:在 platformio.ini 中声明依赖

通过 MQTT 发送消息的常用方式之一是使用 JSON 编码。Arduino 生态中有专门的 JSON 库(本课程使用 ArduinoJson),它封装了 JSON 文档的读取与写入,让开发者不必手工拼接字符串。

操作步骤

  1. 在 VS Code 中打开夜灯项目(nightlight);
  2. platformio.ini文件的lib_deps列表中追加一行:
bblanchon/ArduinoJson @ 6.17.3

该声明即引入 ArduinoJson 库(作者 bblanchon,版本锁定为 6.17.3)。@ 版本号语法用于锁定具体版本,PlatformIO 在下次构建项目时会自动下载对应源码并编译进你的工程。

仓库中的完整依赖清单

在仓库的 code-telemetry/wio-terminal/nightlight/platformio.ini 中,[env:seeed_wio_terminal]环境的完整lib_deps如下:

[env:seeed_wio_terminal] platform = atmelsam board = seeed_wio_terminal framework = arduino lib_deps = knolleary/PubSubClient @ 2.8 seeed-studio/Seeed Arduino rpcWiFi @ 1.0.5 seeed-studio/Seeed Arduino FS @ 2.1.1 seeed-studio/Seeed Arduino SFUD @ 2.0.2 seeed-studio/Seeed Arduino rpcUnified @ 2.1.3 seeed-studio/Seeed_Arduino_mbedtls @ 3.0.1 bblanchon/ArduinoJson @ 6.17.3

可以看出,本环节新增的只有最后一行bblanchon/ArduinoJson @ 6.17.3,其余五条分别来自前一环节(连接 MQTT 时)引入的 Seeed WiFi 库与 PubSubClient。各依赖的作用如下:

  • knolleary/PubSubClient @ 2.8:Arduino 平台的 MQTT 客户端库;
  • seeed-studio/Seeed Arduino rpcWiFi @ 1.0.5:Wio Terminal 板载 WiFi 芯片的通信驱动(硬件相关,仅适用于 Seeed 硬件);
  • Seeed Arduino FSSFUDrpcUnifiedmbedtls:WiFi 库运行所需的底层支持库;
  • bblanchon/ArduinoJson @ 6.17.3:本环节新增的 JSON 读写库。

💁 如果你去掉@ 版本号,PlatformIO 将始终拉取最新版本;但最新版本不保证与本节代码兼容——仓库中这些代码是经指定版本测试通过的。

定义遥测主题:在 config.h 中声明常量

设备需要知道把遥测发布到哪个 MQTT 主题。这一步通过修改config.h完成:在文件末尾追加一行常量定义:

const string CLIENT_TELEMETRY_TOPIC = ID + "/telemetry";

仓库中完整的 config.h 内容为:

#pragma once #include <string> using namespace std; // WiFi credentials const char *SSID = "<SSID>"; const char *PASSWORD = "<PASSWORD>"; // MQTT settings const string ID = "<ID>"; const string BROKER = "test.mosquitto.org"; const string CLIENT_NAME = ID + "nightlight_client"; const string CLIENT_TELEMETRY_TOPIC = ID + "/telemetry";

要点说明:

  • CLIENT_TELEMETRY_TOPIC是设备发布光照强度所用的主题名,由唯一标识ID拼接"/telemetry"生成。例如ID = "abc123"时,主题为abc123/telemetry
  • 使用ID前缀可以避免在公共 Broker 上与其他设备或同学的项目相互串扰——主题和客户端名(CLIENT_NAME = ID + "nightlight_client")都需要唯一;
  • 回顾前一环节可知,wio-terminal-mqtt.md 中创建config.h时已经定义了SSIDPASSWORD(WiFi 凭据)以及IDBROKERCLIENT_NAME(MQTT 连接信息)。本环节只新增CLIENT_TELEMETRY_TOPIC一行;
  • BROKER固定为test.mosquitto.org,MQTT 默认端口为 1883(见下文client.setServer(BROKER.c_str(), 1883))。

⚠️ 别忘了把<SSID><PASSWORD><ID>替换为你自己的值:SSID 与密码来自你的 WiFi,ID可以是 GUIDGen 这类工具生成的随机串。这个ID在后续编写服务端代码时还要复用,必须保持一致。

发布遥测:在 loop 中读取光照并序列化 JSON

打开main.cpp,先在其文件顶部添加#include指令:

#include <ArduinoJSON.h>

然后,在loop函数内、delay调用之前插入如下代码:

int light = analogRead(WIO_LIGHT); DynamicJsonDocument doc(1024); doc["light"] = light; string telemetry; serializeJson(doc, telemetry); Serial.print("Sending telemetry "); Serial.println(telemetry.c_str()); client.publish(CLIENT_TELEMETRY_TOPIC.c_str(), telemetry.c_str());

这段代码完成了四件事:

  1. 读取传感器analogRead(WIO_LIGHT)从 Wio Terminal 板载光敏传感器引脚读取 0~1023 的模拟量,即当前光照强度;
  2. 构造 JSON 文档DynamicJsonDocument doc(1024)在堆上分配一块 1024 字节的缓冲区(足以容纳本场景的小型文档),doc["light"] = light把光照值写入light键;
  3. 序列化serializeJson(doc, telemetry)将 JSON 文档输出到string变量,例如{"light":652}
  4. 发布与调试输出Serial.println在串口打印遥测内容便于观察,client.publish(CLIENT_TELEMETRY_TOPIC.c_str(), telemetry.c_str())通过 PubSubClient 把消息发布到之前定义的主题。

发布效果验证

将代码上传到 Wio Terminal 后,打开串口监视器即可看到遥测数据持续发送到 MQTT Broker:

Connecting to WiFi.. Connected! Attempting MQTT connection...connected Sending telemetry {"light":652} Sending telemetry {"light":612} Sending telemetry {"light":583}

这段输出展示了完整的启动链路:先连 WiFi,再连 MQTT,随后每 2 秒发布一条遥测。用手遮挡光敏传感器(或用手指改变进光量),light数值会随之变化。

源码全景:从连接管理到遥测发布的完整闭环

仓库 code-telemetry/wio-terminal/nightlight/src/main.cpp 提供了本环节的完整实现。除上文新增的发布代码外,它还包含前一环节搭建的连接管理函数,共同构成一个可独立运行的遥测发布程序:

#include <Arduino.h> #include <ArduinoJSON.h> #include <PubSubClient.h> #include <rpcWiFi.h> #include <SPI.h> #include "config.h" void connectWiFi() { while (WiFi.status() != WL_CONNECTED) { Serial.println("Connecting to WiFi.."); WiFi.begin(SSID, PASSWORD); delay(500); } Serial.println("Connected!"); } WiFiClient wioClient; PubSubClient client(wioClient); void reconnectMQTTClient() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); if (client.connect(CLIENT_NAME.c_str())) { Serial.println("connected"); } else { Serial.print("Retying in 5 seconds - failed, rc="); Serial.println(client.state()); delay(5000); } } } void createMQTTClient() { client.setServer(BROKER.c_str(), 1883); reconnectMQTTClient(); } void setup() { Serial.begin(9600); while (!Serial) ; // Wait for Serial to be ready delay(1000); pinMode(WIO_LIGHT, INPUT); pinMode(D0, OUTPUT); connectWiFi(); createMQTTClient(); } void loop() { reconnectMQTTClient(); client.loop(); int light = analogRead(WIO_LIGHT); DynamicJsonDocument doc(1024); doc["light"] = light; string telemetry; serializeJson(doc, telemetry); Serial.print("Sending telemetry "); Serial.println(telemetry.c_str()); client.publish(CLIENT_TELEMETRY_TOPIC.c_str(), telemetry.c_str()); delay(2000); }

从源码结构看,整个程序遵循「连接管理 + 主循环发布」的典型嵌入式 MQTT 模式:

  • connectWiFi():循环重试直到 WiFi 连接成功,每次尝试间隔 500ms;
  • WiFiClient wioClient; PubSubClient client(wioClient);:先用 Wio Terminal WiFi 库创建 TCP 客户端,再以此构造 MQTT 客户端;
  • reconnectMQTTClient():检查并维持 MQTT 连接。连接失败时打印返回码client.state()并等待 5 秒重试。它同时被createMQTTClient()loop()调用,因为 MQTT 连接很容易断开,需要周期性检查重连;
  • createMQTTClient()client.setServer(BROKER.c_str(), 1883)指定 Broker 地址与端口,随后立即尝试连接;
  • setup():串口初始化、配置WIO_LIGHT为输入、D0为输出(后者供后续环节控制 LED),再依次执行connectWiFi()createMQTTClient()
  • loop():先重连并调用client.loop()处理网络上的待收消息——这是单线程程序,必须把主线程时间分配给 MQTT 消息处理;随后读取光照、构造 JSON、序列化、发布;最后的delay(2000)把发送间隔控制在 2 秒,既避免过于频繁地发送(省电、省带宽),也能及时反映光照变化。

遥测频率与断连:工程上必须考虑的两个问题

发布遥测「能跑」只是第一步,实际 IoT 工程还要回答两个问题(详见 第 4 课 README 的「Telemetrie」小节):

多久发一次?答案取决于场景。测得太频繁会浪费电量、占用带宽并推高云端处理存储成本;测得太少又无法及时响应变化。温度类慢变信号(如恒温器)每隔几分钟测一次即可;而工厂里价值高昂、故障代价巨大的设备,可能需要每秒多次采样。本节夜灯采用 2 秒间隔,是功耗与实时性的折中。

断了怎么办?公共 WiFi 与 MQTT 连接并不总是稳定。恒温器这类设备可以接受丢失旧读数——系统只关心当前温度;而用于趋势分析与异常检测(如预测性维护)的场景,则希望在恢复连接后补发断网期间产生的所有遥测。此外,设备还应具备断连时本地兜底的能力(例如恒温器离线时仍能按有限规则控制加热)。本文的reconnectMQTTClient()loop中反复调用,正是为了在断连时尽快恢复连接。

下一步:接收命令与对照参考

发布遥测只是远程夜灯的一半。服务端(Python + Paho-MQTT)订阅ID + "/telemetry"主题接收消息后,会依据光照阈值(如light < 300)向ID + "/commands"主题回发{"led_on": true/false}命令,设备再订阅该主题控制 LED——这是 wio-terminal-commands.md 的后续环节。服务端示例代码可参考仓库的 code-server/server 与 code-commands/server 目录。

如果你使用的是 Raspberry Pi 或虚拟 IoT 设备(而非 Wio Terminal),同一环节的对照实现见 single-board-computer-telemetry.md。

关键文件索引

文件作用
code-telemetry/wio-terminal/nightlight/src/main.cpp遥测发布完整实现(连接管理 + JSON 发布)
code-telemetry/wio-terminal/nightlight/src/config.hWiFi 凭据、MQTT 连接信息与遥测主题常量
code-telemetry/wio-terminal/nightlight/platformio.iniPlatformIO 工程配置与全部库依赖
wio-terminal-mqtt.md前一环节:WiFi 与 MQTT 连接建立
README.md第 4 课总览:MQTT、遥测、命令与断连设计

【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 16:08:14

Java+MySQL学生选课系统:关系型数据库工程实践闭环

简介&#xff1a;本资源是一套完整的数据库课程设计实践项目&#xff0c;面向高校计算机及相关专业学生&#xff0c;解决课程设计与期末大作业中选课系统开发落地难、数据库建模与Java后端整合不熟练等典型问题。压缩包共278个文件&#xff0c;含40个核心Java源码&#xff08;含…

作者头像 李华
网站建设 2026/9/16 16:07:17

STM32H750驱动0.96寸OLED的HAL库时序与DMA安全实践

简介&#xff1a;本资源是一套基于STM32H750微控制器的0.96寸OLED显示屏HAL库驱动工程&#xff0c;面向嵌入式开发初学者与STM32H7系列进阶工程师&#xff0c;解决高性能Cortex-M7平台下OLED外设快速适配与稳定显示的核心问题&#xff0c;适用于工业人机界面、便携仪器、IoT终端…

作者头像 李华