IoT-For-Beginners 实战:用 MQTT 将 Wio Terminal 夜灯接入互联网(Arduino + PubSubClient 完整指南)
2026/9/17 21:37:11 网站建设 项目流程

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 库:

  1. Seeed 官方 WiFi 库——驱动 Wio Terminal 板载 WiFi 芯片(这些库与特定硬件强相关);
  2. 第三方 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 之类的工具生成
BROKERMQTT 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。WiFiClientPubSubClient的组合正是 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),这个函数既承担"首次连接",也承担"断线重连",因此在setuploop中都会被调用。

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

这段代码的职责非常关键:

  1. reconnectMQTTClient():MQTT 连接很容易意外断开,因此每次循环先检查并重连;
  2. client.loop():处理网络连接上等待的入站消息。本应用是单线程的,消息无法在后台线程接收,必须在主线程分配时间处理;
  3. 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 只是本课的第一步。后续步骤将在此基础上扩展:

  1. 发送遥测:设备把光传感器读数以 JSON 形式发布到<ID>/telemetry主题,见 wio-terminal-telemetry.md;
  2. 接收命令:设备订阅<ID>/commands主题,通过回调函数解析 JSON 中的led_on字段控制 LED,见 wio-terminal-commands.md 及对应的 code-commands/wio-terminal 源码;
  3. 服务器端配合:本课服务器代码以 Python + Paho-MQTT 运行在本地电脑,订阅遥测、发布命令,代码见 code-server/server 与 code-commands/server。

以仓库中 config.h 为例,IDBROKERCLIENT_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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询