IoT-For-Beginners 实战:用 MQTT 将 Wio Terminal 夜灯接入互联网(Arduino + PubSubClient 完整指南)
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
本篇技术指南是开源课程 IoT-For-Beginners 第 1 单元第 4 课《将设备接入互联网》中Wio Terminal 硬件篇的核心实战内容:通过 PlatformIO + Arduino 框架,让 Wio Terminal 借助 Seeed rpcWiFi 库连接 WiFi,再通过 PubSubClient 库连接公共 MQTT brokertest.mosquitto.org,为后续发送光传感器遥测数据、接收服务器 LED 控制命令铺平道路。读完本文你将掌握:在platformio.ini中声明 Arduino 库依赖、编写 WiFi 与 MQTT 的连接/重连代码、使用串口监视器验证连接状态,并理解这套代码在完整"夜灯"应用中的位置。
一、本节任务概览:夜灯如何"上网"
在本课中,夜灯应用的目标是让物联网设备与云端"双向通信":
- 上行(遥测 Telemetry):设备读取光传感器值,通过 MQTT 发布到 broker;
- 下行(命令 Commands):设备订阅命令主题,收到服务器下发的指令后控制 LED 开关。
而wio-terminal-mqtt.md这一步骤只解决其中"地基"问题——把设备连上 WiFi 和 MQTT broker。整个应用的通信架构可参考本课 README 中的 MQTT 架构图:设备发布遥测到主题,云端服务订阅该主题;云端发布命令到主题,设备订阅命令主题。IoT 设备与云服务之间通过 broker 以"发布/订阅"(Pub/Sub)模式解耦通信,这也是 MQTT 最核心的设计。
本课使用的 broker 是 Eclipse Mosquitto 特别提醒:该 broker 是公开且不安全的,任何人都有可能监听你发布的内容,因此绝不能用来传输需要保密的数据。
二、安装 WiFi 与 MQTT 的 Arduino 库
要为 Wio Terminal 编写 MQTT 客户端代码,首先需要两类 Arduino 库:
- Seeed 官方 WiFi 库——驱动 Wio Terminal 板载 WiFi 芯片(这些库与特定硬件强相关);
- 第三方 MQTT 客户端库——负责与 broker 进行 MQTT 协议交互。
Arduino 生态的库以源码形式发布,PlatformIO 可以自动下载、编译并链接进你的项目。库可以全局安装,也可以安装到某个具体项目中;本课采用安装到项目内的方式(在platformio.ini中声明lib_deps)。
任务一:在 platformio.ini 中声明库依赖
打开 VS Code 中的 nightlight 项目(即 code-mqtt/wio-terminal/nightlight),在platformio.ini末尾追加:
lib_deps = 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这组依赖引入了 Seeed 的 WiFi 软件栈。语法@ <number>表示锁定指定版本号的库。
💁 可以去掉
@ <number>以始终使用库的最新版本,但新版本并不能保证与下文代码兼容——本文代码仅针对所列版本做过测试。
接着,在lib_deps中继续追加:
knolleary/PubSubClient @ 2.8这引入了 PubSubClient——一个适用于 Arduino 的经典 MQTT 客户端库。
添加库到此结束。下一次 PlatformIO 构建项目时,它会自动下载这些库的源码并编译进你的项目。仓库中实际项目 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可以看到:目标平台为atmelsam(Atmel SAMD 系列 MCU)、板型为seeed_wio_terminal、框架为arduino。
三、创建 config.h 存放凭据
在src文件夹下新建config.h。在 VS Code 资源管理器中,将鼠标悬停在src文件夹(或其内的main.cpp)上,点击出现的New file按钮即可创建新文件。
向config.h写入 WiFi 凭据常量:
#pragma once #include <string> using namespace std; // WiFi credentials const char *SSID = "<SSID>"; const char *PASSWORD = "<PASSWORD>";将<SSID>替换为你的 WiFi 名称,将<PASSWORD>替换为你的 WiFi 密码。仓库中的成品示例见 config.h(占位符保留,供你复制修改)。
四、连接 WiFi:编写并调用 connectWiFi
打开main.cpp,在文件顶部添加头文件引用:
#include <PubSubClient.h> #include <rpcWiFi.h> #include <SPI.h> #include "config.h"这些头文件负责告诉 PlatformIO 把库代码链接进来。如果不显式 include,部分代码不会被编译,并会报编译错误。
在setup函数上方添加 WiFi 连接函数:
void connectWiFi() { while (WiFi.status() != WL_CONNECTED) { Serial.println("Connecting to WiFi.."); WiFi.begin(SSID, PASSWORD); delay(500); } Serial.println("Connected!"); }这段代码在设备尚未连上 WiFi 时循环执行:每 500ms 用config.h中的 SSID 和密码调用一次WiFi.begin(),直到WiFi.status()返回WL_CONNECTED为止。
在setup函数末尾(引脚配置完成之后)调用它:
connectWiFi();把代码上传到设备后,打开串口监视器(PlatformIO 的platformio device monitor),应看到如下输出:
> Executing task: platformio device monitor < --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time --- More details at http://bit.ly/pio-monitor-filters --- Miniterm on /dev/cu.usbmodem1101 9600,8,N,1 --- --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- Connecting to WiFi.. Connected!注意串口监视器以9600 波特率打开,这与仓库 main.cpp 中
Serial.begin(9600)的设置一致。
五、连接 MQTT:配置 broker 连接参数
WiFi 就绪后,设备即可连接 MQTT broker。先在config.h末尾追加 MQTT 连接信息:
// MQTT settings const string ID = "<ID>"; const string BROKER = "test.mosquitto.org"; const string CLIENT_NAME = ID + "nightlight_client";三个常量的含义:
| 常量 | 说明 | 取值建议 |
|---|---|---|
ID | 设备的唯一标识 | 替换<ID>为唯一 ID,可用 GUIDGen 之类的工具生成 |
BROKER | MQTT broker 的地址 | 本课固定为test.mosquitto.org |
CLIENT_NAME | 该 MQTT client 在 broker 上的唯一名字 | 由ID + "nightlight_client"拼接而成 |
为什么必须唯一?test.mosquitto.org是公共 broker,大量用户(包括其他正在学习本课的同学)同时在线。拥有唯一的 MQTT client 名称和主题名称,可以确保你的代码不会与他人冲突。而且这个ID后续还会用于:
- 定义遥测主题(
<ID>/telemetry); - 定义命令主题(
<ID>/commands); - 编写本课后半部分的 Python 服务器代码(README 服务器示例 中要求使用同一个 ID,否则服务器代码无法订阅/发布到正确的主题)。
六、编写 MQTT 客户端:创建、重连与消息泵
6.1 实例化 MQTT 客户端
在main.cpp中,connectWiFi函数下方、setup函数上方添加:
WiFiClient wioClient; PubSubClient client(wioClient);第一行用 Wio Terminal 的 WiFi 库创建一个 WiFi client;第二行将其作为底层传输通道,构造 PubSubClient 的 MQTT client。WiFiClient与PubSubClient的组合正是 main.cpp 中的实现。
6.2 重连函数 reconnectMQTTClient
继续添加:
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); } } }该函数在未连接状态不断循环:用config.h中的唯一 client 名调用client.connect()尝试连接;失败时打印返回码client.state()并等待 5 秒后重试。
从源码结构看(main.cpp),这个函数既承担"首次连接",也承担"断线重连",因此在
setup和loop中都会被调用。
6.3 创建客户端 createMQTTClient
void createMQTTClient() { client.setServer(BROKER.c_str(), 1883); reconnectMQTTClient(); }setServer()设置 broker 地址(test.mosquitto.org)与端口(1883,MQTT 默认 TCP 端口),随后立即执行首次连接。然后在setup函数中、WiFi 连接成功后调用createMQTTClient()。
6.4 重写 loop:持续重连 + 消息泵
用以下代码替换整个loop函数:
void loop() { reconnectMQTTClient(); client.loop(); delay(2000); }这段代码的职责非常关键:
reconnectMQTTClient():MQTT 连接很容易意外断开,因此每次循环先检查并重连;client.loop():处理网络连接上等待的入站消息。本应用是单线程的,消息无法在后台线程接收,必须在主线程分配时间处理;delay(2000):2 秒延时既避免光感数据发送过于频繁,也降低设备功耗。
将以上完整步骤组合后,可对照仓库中的完整实现 main.cpp 逐行核对。
七、上传验证:串口监视器观察连接过程
将代码上传到 Wio Terminal,用串口监视器观察,应看到类似输出:
> Executing task: platformio device monitor < source /Users/jimbennett/GitHub/IoT-For-Beginners/1-getting-started/lessons/4-connect-internet/code-mqtt/wio-terminal/nightlight/.venv/bin/activate --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time --- More details at http://bit.ly/pio-monitor-filters --- Miniterm on /dev/cu.usbmodem1201 9600,8,N,1 --- --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- Connecting to WiFi.. Connected! Attempting MQTT connection...connected看到Attempting MQTT connection...connected即表示设备已成功连上 MQTT broker。完整代码存放于仓库的 code-mqtt/wio-terminal 目录,可直接打开对照或运行。
八、下一步:从"连上"到"通信"
连上 broker 只是本课的第一步。后续步骤将在此基础上扩展:
- 发送遥测:设备把光传感器读数以 JSON 形式发布到
<ID>/telemetry主题,见 wio-terminal-telemetry.md; - 接收命令:设备订阅
<ID>/commands主题,通过回调函数解析 JSON 中的led_on字段控制 LED,见 wio-terminal-commands.md 及对应的 code-commands/wio-terminal 源码; - 服务器端配合:本课服务器代码以 Python + Paho-MQTT 运行在本地电脑,订阅遥测、发布命令,代码见 code-server/server 与 code-commands/server。
以仓库中 config.h 为例,ID、BROKER、CLIENT_NAME这三个常量构成后续所有主题与客户端命名的基石,建议在正式动手前规划好你的唯一ID。
九、常见问题与注意事项
- 串口监视器无输出:确认
Serial.begin(9600)与监视器波特率一致(9600); - WiFi 一直重试:检查
config.h中 SSID/密码是否正确,设备是否处于可接收 WiFi 信号的范围; - MQTT 连接返回失败码:
client.state()会打印失败原因(返回码),结合 PubSubClient 状态定义 排查;5 秒后会自动重试; - 公共 broker 的隐私风险:
test.mosquitto.org上所有消息都是公开可监听的,切勿传输敏感数据; - 库版本锁定:文中所有
@ <版本号>为经过测试的版本组合,擅自升级可能引入兼容性问题。
至此,你的 Wio Terminal 已经成功接入一个 MQTT broker,为完整的"互联网控制夜灯"应用打下了通信基础。
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考