news 2026/9/14 19:38:06

IoT-For-Beginners 实战:使用 Wio Terminal 通过 MQTT 发布光照遥测数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
IoT-For-Beginners 实战:使用 Wio Terminal 通过 MQTT 发布光照遥测数据

IoT-For-Beginners 实战:使用 Wio Terminal 通过 MQTT 发布光照遥测数据

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

本篇技术指南是微软《IoT-For-Beginners》开源课程第 4 课(连接设备到互联网)的 Wio Terminal 实操环节,核心任务是让夜灯(nightlight)项目通过 MQTT 协议把光敏传感器读取的光照强度(telemetry)发布到公共 MQTT 代理(broker)test.mosquitto.org,为后续服务器端代码订阅遥测并回传控制命令打下基础。读完本篇,你将掌握在 PlatformIO 项目中引入 ArduinoJson 库、配置遥测主题、编写 JSON 序列化发布代码,以及通过串口监视器验证 MQTT 消息流的完整链路。

前置准备与背景

本课节的完整上下文位于 4-connect-internet/README.md。在进入本篇的遥测发布之前,你的 Wio Terminal 夜灯项目应当已经完成两个前置步骤:

  1. 连接 WiFi:通过config.h中的SSID/PASSWORD常量接入局域网;
  2. 连接 MQTT 代理:使用PubSubClient客户端连上test.mosquitto.org的 1883 端口,并在loop中维持心跳与重连。

如果你尚未完成上述步骤,请先阅读 wio-terminal-mqtt.md。本篇(对应原文 wio-terminal-telemetry.md)将在此基础上,让设备把光照强度以 JSON 格式发布到 MQTT 遥测主题。

说明:课程采用公共测试代理test.mosquitto.org,无需注册账号即可使用,但它属于公共且不安全的服务,任何人都有可能监听到你发布的内容,切勿用于任何需要保密的数据。

安装 ArduinoJson 库

MQTT 消息的载荷(payload)常以 JSON 编码,即 JavaScript Object Notation——一种用键值对在文本中编码数据的标准格式。Arduino 生态中有专门的 JSON 库,可以极大简化 JSON 文档的读写与序列化。

操作步骤:在 platformio.ini 中声明依赖

  1. 在 VS Code 中打开夜灯项目(Wio Terminal 的 PlatformIO 工程)。

  2. 编辑项目根目录下的platformio.ini,在lib_deps列表中追加一行:

    bblanchon/ArduinoJson @ 6.17.3

    bblanchon/ArduinoJson是 Arduino 上使用最广泛的 JSON 库,@ 6.17.3表示锁定该库的 6.17.3 版本。参考仓库中完整版配置 code-telemetry/wio-terminal/nightlight/platformio.ini:

    [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

    lib_deps中同时包含了 MQTT 通信所需的PubSubClient、Wio Terminal WiFi 芯片所需的 Seeed rpcWiFi 系列库,以及本步新增的 ArduinoJson。PlatformIO 在下次编译时会自动下载并编译这些依赖库。

发布遥测:配置主题与编写发布代码

遥测(telemetry)一词源自希腊语,本义是"远程测量",指从传感器采集数据并发送到云端的行为。接下来你要完成三处代码改动:定义遥测主题、引入 JSON 头文件、在loop中读取光敏值并发布。

第一步:在 config.h 中定义遥测主题

打开src/config.h,在文件末尾追加一行,声明 MQTT 遥测主题:

const string CLIENT_TELEMETRY_TOPIC = ID + "/telemetry";

CLIENT_TELEMETRY_TOPIC是设备发布光照强度的主题。它以config.h中已定义的唯一标识符ID作为主题前缀(例如"9f8e..." + "/telemetry"),这样多个学生/设备使用同一个公共代理时,各自的主题不会相互冲突。

参考仓库 code-telemetry/wio-terminal/nightlight/src/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";

需要将<SSID><PASSWORD>替换为你的 WiFi 凭据,将<ID>替换为一个全局唯一标识(可在后续编写服务器代码时继续复用,保证订阅/发布到正确的主题)。

第二步:在 main.cpp 引入 ArduinoJson 头文件

打开src/main.cpp,在文件头部加入以下#include指令:

#include <ArduinoJSON.h>

注意:#include的作用是告知编译器把对应库的代码链接进工程。参考仓库 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"

第三步:在 loop 函数中读取光敏值并发布

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());

这段代码的执行逻辑:

  • analogRead(WIO_LIGHT)从 Wio Terminal 板载光敏传感器引脚读取 0~1023 的模拟量,作为当前光照强度;
  • DynamicJsonDocument doc(1024)在堆上创建一个容量为 1024 字节的动态 JSON 文档,doc["light"] = light写入键值对;
  • serializeJson(doc, telemetry)将 JSON 文档序列化为std::string字符串;
  • Serial打印待发送内容,方便在串口监视器中观察;
  • client.publish(...)由 MQTT 客户端把字符串发布到遥测主题CLIENT_TELEMETRY_TOPIC

仓库中 完整的 main.cpp 实现 展示了上下文全貌——loop开头先调用reconnectMQTTClient()确保连接存活,再调用client.loop()处理网络收发的消息,随后执行上述遥测发布,最后delay(2000)让两次发布间隔 2 秒:

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); }

第四步:上传并验证

将代码上传到 Wio Terminal,打开 PlatformIO 的 Serial Monitor(串口监视器),可以看到设备先连接 WiFi、再连接 MQTT 代理,随后持续输出发布遥测的日志:

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

其中{"light":652}就是序列化后的 JSON 遥测载荷:键light对应的数值随环境光照变化。遮挡光敏传感器时数值下降,照射强光时数值上升。串口输出中的Connecting to WiFi..Connected!Attempting MQTT connection...connected均来自 main.cpp 中 connectWiFi 与 reconnectMQTTClient 的实现。

遥测发布频率与断连考量

完成发布后有两个工程实践问题值得注意(详见 4-connect-internet/README.md 的 "How often should telemetry be sent?" 与 "Loss of connectivity" 两节):

  • 发布频率:频率取决于场景。恒温器场景每几分钟测一次即可,温度变化并不剧烈;而工厂机械的故障监测可能需要每秒多次采样,宁可浪费带宽也不能漏掉预示故障的遥测。本课夜灯项目取delay(2000)即每 2 秒发布一次,兼顾响应速度、功耗与带宽。此外 MQTT 本身提供 keep alive 机制,在消息间隔较长时仍能维持连接存活。
  • 断连处理:互联网连接不可靠,是否缓存断连期间的遥测取决于业务——恒温器的旧温度可丢弃(新测量已取代旧值),而用于趋势分析与异常检测的机器遥测则可能需要补发。MQTT 本身不支持消息队列(虽然名字里有 Queueing),若客户端断开后重连,不会收到断开期间发布的消息,除非消息设置了 retained 标志或借助 QoS 机制。

与服务器端代码的衔接

本课节的最终目标是搭建"设备 → 代理 → 服务器"的闭环。服务器端使用 Python 的 Paho-MQTT 库订阅遥测主题,示例位于 code-server/server/app.py:

client_telemetry_topic = id + '/telemetry' client_name = id + '_nightlight_server' mqtt_client = mqtt.Client(client_name) mqtt_client.connect('test.mosquitto.org') mqtt_client.loop_start() def handle_telemetry(client, userdata, message): payload = json.loads(message.payload.decode()) print("Message received:", payload) mqtt_client.subscribe(client_telemetry_topic) mqtt_client.on_message = handle_telemetry

注意:服务器代码中的<ID>必须与设备端config.h中使用的ID完全一致,否则服务器无法订阅到正确的遥测主题。运行后,服务器终端会打印形如Message received: {'light': 400}的遥测数据。在后续课程环节中,服务器还会根据light < 300的阈值向/commands主题发布led_on指令,驱动设备端 LED 开关——整个控制链路的起点正是本篇实现的遥测发布。

小结

至此,你的 Wio Terminal 已经能够:

  • 通过platformio.inilib_deps引入 ArduinoJson 6.17.3 依赖;
  • config.h中定义以唯一ID为前缀的遥测主题ID + "/telemetry"
  • loop中使用analogRead(WIO_LIGHT)读取光敏值,用DynamicJsonDocument+serializeJson构造 JSON 载荷并发布到 MQTT 代理;
  • 通过 Serial Monitor 验证{"light":652}形式的遥测输出流。

完整可运行代码位于 code-telemetry/wio-terminal,可作为比对与排错参考。下一环节将是编写接收命令的设备端代码(见 wio-terminal-commands.md),让夜灯响应来自服务器的 LED 控制指令。

【免费下载链接】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/14 19:37:57

测试验证阶段CANoe许可证缺口如何提前预判与规划

如果你管过CANoe许可证&#xff0c;大概率经历过这种场面&#xff1a;项目前期开发阶段License空着一大半&#xff0c;一到测试验证阶段&#xff0c;全员抢License&#xff0c;有人干到一半被挤下线&#xff0c;有人守着电脑不敢关会话&#xff0c;还有人直接在工作群里问“谁不…

作者头像 李华
网站建设 2026/9/14 19:36:21

3步走离线做证件照:免费AI证件照工具HivisionIDPhotos实战

3步走离线做证件照&#xff1a;免费AI证件照工具HivisionIDPhotos实战 【免费下载链接】HivisionIDPhotos ⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。 项目地址: https://gitcode.com/GitHub_Trending/hiv/Hivi…

作者头像 李华
网站建设 2026/9/14 19:33:55

SSM框架在物流配送调度系统中的优化实践

1. 项目概述&#xff1a;物流配送调度系统的核心价值物流配送行业正面临前所未有的效率挑战。根据行业数据显示&#xff0c;超过60%的配送成本来自车辆空驶和路线规划不当。我们设计的这套基于SSM框架的车辆调度管理系统&#xff0c;正是为了解决这些痛点而生。这个系统最核心的…

作者头像 李华
网站建设 2026/9/14 19:33:51

Java双端队列(Deque)核心原理与实战应用

1. Deque接口核心概念解析双端队列&#xff08;Deque&#xff09;是Java集合框架中一个兼具栈和队列特性的数据结构&#xff0c;全称为Double Ended Queue。与普通队列只能一端进另一端出的特性不同&#xff0c;Deque允许在队列的两端进行插入和删除操作。这种设计使得它能够灵…

作者头像 李华
网站建设 2026/9/14 19:31:45

Windows下用WSL 2跑OpenFOAM v12:从环境部署到标准算例全攻略

前阵子一个做流体仿真的朋友问我&#xff1a;新配的笔记本只有 Windows&#xff0c;不想装双系统&#xff0c;还想本地跑 OpenFOAM&#xff0c;到底行不行&#xff1f;这个问题我太熟了——我自己在 Windows 11 和 Windows 10 两台机器上&#xff0c;从 OpenFOAM v2012 一直折腾…

作者头像 李华