关于 xiao-esp32s3-mqtt-dashboard
用于搭建多块 XIAO ESP32S3 的 MQTT 仪表板技能,组合 Mosquitto 代理与浏览器界面。内容涵盖代理配置、固件设置、部署和验证,各板可使用同一份编译固件。
主要功能
- 01配置 Mosquitto 代理和防火墙
- 02按 MAC 地址生成板卡 ID
- 03通过 MQTT 传输触摸和 LED 消息
- 04使用 WebSocket 浏览器仪表板
- 05提供固件编译与上传流程
适用场景
- 01监控多块板的触摸读数
- 02通过浏览器控制板载 LED
- 03通过 MQTT 主题验证连接
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ shain1912/ esp32-skills --skill xiao-esp32s3-mqtt-dashboard安装后在 Claude Code 中输入/xiao-esp32s3-mqtt-dashboard确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/esp32s3_mqtt_dashboard.ino.tplassets/dashboard_web/app.jsindex.htmlstyles.cssassets/mqtt-broker/mosquitto_listeners.confsetup_broker.ps1setup_firewall.ps1详细介绍
XIAO ESP32S3 多板 MQTT 仪表盘
架构:N 块开发板(STA 模式,连接同一 WiFi)→ MQTT 代理(Mosquitto,运行在该 WiFi 中的一台电脑上)→ 浏览器仪表盘(MQTT-over-WebSocket,mqtt.js)。每块开发板运行相同的已编译固件——无需针对单块开发板修改——因为固件会根据自身的 MAC 地址生成唯一 ID。
请先阅读 xiao-esp32s3 技能(同一仓库),了解基础的 arduino-cli 工作流程和注意事项(PSRAM 标志、DTR 复位卡住后的恢复、有界串口读取)。
此技能在此基础上添加代理、网络和仪表盘部分。
步骤 1 — 务必先询问用户
切勿编造凭据或擅自假设代理的运行位置。请询问:
- WiFi SSID / 密码——必须是每块开发板和代理电脑都能加入的网络(2.4 GHz;ESP32 无法发现 5 GHz 网络)。
- Mosquitto 的运行位置——这台电脑(技能会进行设置,见步骤 2),还是其他位置已有的代理(获取主机和端口,跳过步骤 2 的本地设置)。
- 现在是否会烧录多块实体开发板(这不会影响固件——固件会自行分配 ID——但会影响你向用户说明“将此固件烧录到每块开发板”时的措辞)。
步骤 2 — 设置代理(如果其他位置已有代理,则跳过)
在共用 WiFi 的代理电脑上查找 LAN IP(Windows):
Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.InterfaceAlias -eq 'Wi-Fi'} | Select-Object IPAddress
检查是否已安装 Mosquitto,以及当前有哪些端口正在监听:
netstat -an | findstr "1883 9001"
Get-Service -Name mosquitto -ErrorAction SilentlyContinue
如果没有程序监听 0.0.0.0:1883/0.0.0.0:9001(默认如此的原因见下方注意事项 1–3),请将 assets/mqtt-broker/setup_broker.ps1 和 assets/mqtt-broker/setup_firewall.ps1 放在用户工作区的同一目录下,然后以管理员权限运行这两个脚本(普通 shell 会静默失败,原因见注意事项 2):
Start-Process powershell -ArgumentList '-NoProfile','-ExecutionPolicy','Bypass','-File','<path>\setup_broker.ps1' -Verb RunAs -Wait
Start-Process powershell -ArgumentList '-NoProfile','-ExecutionPolicy','Bypass','-File','<path>\setup_firewall.ps1' -Verb RunAs -Wait
这会触发 Windows UAC 授权提示——请告知用户该提示会出现,并且需要点击“Yes”;你无法替用户点击。两个脚本都会在自身所在目录写入 setup_result.txt——请读取该文件确认成功,不要假设已捕获管理员权限窗口中的输出。
验证 LAN 访问确实成功(而不仅仅是进程正在监听):
netstat -an | findstr "1883 9001" # expect 0.0.0.0:1883 and 0.0.0.0:9001, not 127.0.0.1
步骤 3 — 根据模板生成草图
assets/esp32s3_mqtt_dashboard.ino.tpl 是已验证可运行的代码——不要重写。将其复制到 <workspace>\<name>\<name>.ino(文件夹名称必须与 .ino 文件名一致),然后按原样替换占位符:
| 占位符 | 含义 | 示例 |
|---|---|---|
__WIFI_SSID__ | WiFi SSID(2.4 GHz) | myhome |
__WIFI_PASS__ | WiFi 密码 | pass1234 |
__MQTT_HOST__ | 代理电脑的 LAN IP | 192.168.0.42 |
安装草图所需的额外库(WiFi/WiFiClient 已随 esp32 核心一同提供):
arduino-cli lib install "PubSubClient"
步骤 4 — 编译并上传
arduino-cli compile --fqbn esp32:esp32:XIAO_ESP32S3 <SKETCH_DIR>
arduino-cli upload -p COM4 --fqbn esp32:esp32:XIAO_ESP32S3 <SKETCH_DIR>
要添加更多开发板,只需将完全相同的已编译草图烧录到每块开发板上——无需在开发板之间进行修改。
步骤 5 — 无需一直打开串口监视器即可验证
烧录后立即读取一次串口,确认 WiFi 和 MQTT 已连接(使用基础技能中的 read_serial.ps1,切勿使用 arduino-cli monitor)。之后,不要再打开串口,而是完全通过 MQTT 验证后续运行情况(注意事项 6 会解释为什么重新打开串口可能看起来像是出现了回归问题,其实并非如此):
# expects: <topic-prefix>/<id>/status online, then a touch value every ~0.5s
mosquitto_sub -h <broker-ip> -p 1883 -t "xiao/#" -v
# flip a board's LED from the command line the same way the dashboard does
mosquitto_pub -h <broker-ip> -p 1883 -t "xiao/<id>/led/set" -m "ON"
(如果 mosquitto_sub/mosquitto_pub 不在 PATH 中,它们与 mosquitto.exe 一同提供,通常位于 C:\Program Files\Mosquitto\。)
步骤 6 — 运行仪表盘
assets/dashboard_web/(index.html、app.js、styles.css)是静态站点——无需构建,也无需填写占位符(代理地址是在页面本身中输入的,不会写入 JS)。用户可以选择任意方式托管,例如:
cd assets/dashboard_web
python -m http.server 8080
然后打开 http://localhost:8080(或在同一 WiFi 中的其他设备上打开 http://<broker-ip>:8080)。在“브로커 주소”框中输入代理的 LAN IP,然后点击 연결——之后该值会保存在 localStorage 中。收到 status/touch 消息后,开发板会自动显示为卡片;无需也不存在针对单块开发板的仪表盘配置。
MQTT 主题方案
<id> 是基于开发板自身 MAC 地址生成的十六进制 ID(自动生成,例如 4b4cf4),
因此许多开发板可以共用一个代理而不会发生冲突。
| 主题 | 方向 | 负载 | 备注 |
|---|---|---|---|
xiao/<id>/touch | 开发板 → 仪表板 | 整数字符串 | 每 500 ms 一次 |
xiao/<id>/led/set | 仪表板 → 开发板 | ON / OFF / TOGGLE | 命令 |
xiao/<id>/led/state | 开发板 → 仪表板 | ON / OFF,保留消息 | 当前状态 |
xiao/<id>/status | 开发板 → 仪表板 | online / offline,保留消息 | LWT — 非正常断开连接时,代理会自动发布 offline |
触摸基线在裸导线/焊盘上约为 16,000–18,000;触摸时数值会大幅升至 40,000 以上(ESP32-S3 的触摸方向 — 请参阅基础技能)。
已知陷阱 — 请在“调试”前阅读
- 未配置侦听器时,Mosquitto 2.x 只绑定到回环地址——这是刻意设置的安全默认值,并非错误。全新安装 Windows 后,如果使用原始的
mosquitto.conf(其中全是注释,没有listener行),netstat会显示127.0.0.1:1883,而不会显示0.0.0.0:1883,直到你添加显式配置listener 1883 0.0.0.0。 - **Windows Mosquitto 服务以
LocalSystem身份运行。**普通(非管理员)Shell 执行Stop-Service/Restart-Service时会收到无提示的Access is denied,也无法写入C:\Program Files\Mosquitto\mosquitto.conf。使用Start-Process powershell -Verb RunAs -Wait以提升的权限运行两个设置脚本(步骤 2)——这是针对用户已要求执行的配置变更,合法且范围明确的 UAC 提权操作;这不是绕过权限提升的办法,而且仍需用户在确认提示中自行点击“Yes”。 - Windows 防火墙默认会阻止来自局域网的入站连接访问新开放的端口,尤其是 WiFi 适配器的网络配置文件为“Public”时(使用
Get-NetConnectionProfile检查)。仅开放 Mosquitto 侦听器还不够——两个端口都要添加显式的New-NetFirewallRule -Direction Inbound规则(步骤 2 中的setup_firewall.ps1)。误报提醒:在 Broker 设备本身运行Test-NetConnection <own-LAN-IP> -Port 1883,即使防火墙会阻止真正的远程设备,也可能报告TcpTestSucceeded: True——通过自己的局域网 IP 进行本机到本机测试,不能可靠替代从实际开发板进行的测试。 PubSubClient::connect()返回rc=-2(MQTT_CONNECT_FAILED)表示 TCP 连接本身失败——Broker 无法访问或被防火墙拦截——并非凭据或身份验证被拒绝。为这个错误排查allow_anonymous/用户名配置会浪费时间;先检查陷阱 1 和 3。- 每次打开 ESP32S3 的串口都会重置开发板(DTR 切换,与基础技能的陷阱 1 相同)——但对于已连接 WiFi/MQTT 的开发板,这不仅仅是多一次重启:之后关闭串口可能会让它陷入复位卡死状态(基础技能的陷阱 8),几秒后 MQTT 会话就会中断。于是 Broker 会通过 LWT 报告该开发板
offline,尽管固件本身没有问题。确认一次 WiFi+MQTT 连接日志后,就不要再打开串口——改用mosquitto_sub或仪表板检查连接是否持续正常,绝不要为了“再确认一下”而重新打开串口。 - **浏览器无法通过 TCP 直接使用原始 MQTT 协议。**仪表板需要 Mosquitto 单独配置
listener 9001 ... protocol websockets——陷阱 1–3 中关于allow_anonymous/防火墙的要求也同样适用于它,且独立于端口 1883。“固件能正常连接,但仪表板什么都没显示”几乎总是因为忘记配置 websockets 侦听器。 - **不要在共享模板中硬编码某个用户的 WiFi SSID/密码或某台机器的局域网 IP。**先询问(步骤 1),再按每次部署的情况填入模板(步骤 3)。还要提醒用户,PC 重启后通过 DHCP 分配的 Broker IP 可能会变化——在路由器端预留 DHCP 地址,可以避免之后必须为每块开发板重新烧录固件。
- 每块开发板都必须生成自己的主题唯一 ID(如模板所示,基于 MAC),而不是使用固定的客户端 ID/主题——两块开发板使用相同的 MQTT 客户端 ID 会互相争抢连接(导致反复断开),两块开发板使用相同的主题则会在仪表板上互相覆盖
touch/led/state的值。