OPENWRT-ESP32-Day03-mqtt联调-边缘网关项目
·
ESP32-S3 MQTT 节点调试总结
项目:
esp32-mqtt-node
硬件:ESP32-S3-DevKitC-1 N8(8MB Flash,无可用 PSRAM),WS2812 GPIO48,串口 COM6
Broker:OpenWrt Pi 上的 Mosquitto
文档日期:2026-06-17
一、目标与最终成果
目标
- ESP32-S3 连接 WiFi,通过 MQTT 连接 OpenWrt Pi 上的 Mosquitto
- 支持 LED 控制(
led/set)与遥测上报(RSSI、uptime、online 状态) - Topic 前缀:
node/esp32-01/
最终可用配置
| 项目 | 值 |
|---|---|
| WiFi SSID | TP-LINK_02FC |
| WiFi 密码 | 12345678 |
| ESP32 IP | 192.168.0.199(DHCP,建议在 TP-Link 静态绑定) |
| MQTT Broker | mqtt://192.168.0.102:1883 |
| Pi WiFi(wan) | 192.168.0.102(phy0-sta0,连 TP-Link) |
| Pi 有线(lan) | 192.168.50.1(br-lan,PC 网线 SSH 用) |
| Pi 上网(wan 原路径) | 192.168.1.113(曾连 South 305,后改为 TP-Link STA) |
| 掩码覆盖 | 关闭(/24,不用 /16) |
验证成功的现象
- 串口出现:
MQTT connected - Pi 上执行:
mosquitto_sub -h 127.0.0.1 -t 'node/esp32-01/#' -v
可收到:
node/esp32-01/status/online 1
node/esp32-01/led/state 0
node/esp32-01/telemetry/rssi -40
node/esp32-01/telemetry/uptime ...
二、网络拓扑演进
2.1 最终拓扑
[South 305 / 上级路由]
│
TP-Link WAN(可选上级)
│
TP-Link 192.168.0.1
DHCP: 0.100 ~ 0.200
│
┌───────────────┼───────────────┐
│ │ │
[ESP32 WiFi] [Pi phy0-sta0] [PC WiFi 0.x]
192.168.0.199 192.168.0.102 (Broker 客户端)
[PC 以太网 192.168.50.166] ──网线── [Pi eth0 / br-lan 192.168.50.1]
(SSH / 调试,与 MQTT 主路径分离)
2.2 关键认知
- MQTT 是 TCP 双向通信:不仅 ESP 要能发到 Pi,Pi 回包也必须能到 ESP。
- PC 能 ping 通 ≠ ESP 能连 MQTT:PC 曾同时有网线
50.x和 WiFi0.x两条路径,ESP 只有 WiFi0.x。 - Broker 放在
192.168.50.1本身没问题,但 ESP 在0.x时必须存在 L3 路由 或 同网段,否则esp-tls: select() timeout。 - OpenWrt 的 lan 与 wan 必须不同网段(例如
50.x+1.x,或50.x+0.x),否则会出现udhcpc: no lease, failing等冲突。
三、问题与解决方案
3.1 WiFi 连接失败(reason 2 / 205)
现象
W mqtt_node: WiFi disconnect reason=2 AUTH_EXPIRE(2)
W mqtt_node: WiFi disconnect reason=205 CONN_FAIL(205)
同一板子、同一路由器上 stationtest 能连,mqtt_node 不能。
根因(按影响排序)
| 优先级 | 问题 | stationtest | mqtt_node(改前) |
|---|---|---|---|
| 高 | pmf_cfg.capable |
false |
true |
| 中 | WiFi 存储 | WIFI_STORAGE_RAM + clear_fast_connect |
无 |
| 中 | 射频兼容 | wifi_apply_rf_compat()(CN/HT20/关省电) |
无 |
| 低 | 连接触发 / 重试间隔 | STA_START 触发 + 2s 延迟 | 手动 connect、无延迟 |
解决
- 将
mqtt_node的 WiFi 初始化对齐stationtest(PMF、RAM 存储、RF 兼容、事件处理等) - 确认
sdkconfig中 SSID/密码与路由器一致
3.2 MQTT 超时(WiFi 已连上)
现象
E esp-tls: [sock=54] select() timeout
E mqtt_client: Error transport connect
根因
- ESP 在
192.168.0.x,Broker 配置为192.168.50.1 - mini/TP-Link 的
0.x与 Pi 的50.x无路由 - Pi
ip route中没有192.168.0.0/24,Pi 也 ping 不通 ESP
尝试过的方案
| 方案 | 结果 |
|---|---|
改 ESP 掩码为 /16 |
有时能通,但不稳定;且曾引发代码 bug(见 3.3) |
| TP-Link 静态路由 + WAN 接 South 305 | WAN 接不到 Pi,Pi 在 50.x 孤立 |
| PC 网线代接 WAN→Pi | PC 未开 IP 转发,不能代替路由器 |
Pi WiFi STA 连 TP-Link,Broker 用 0.102 |
最终可行 |
3.3 掩码覆盖(/16)相关 Bug
现象 A
netmask override failed: ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED
解决:改掩码前先 esp_netif_dhcpc_stop()。
现象 B
netmask override -> 255.255.0.0 (刷屏数十次)
根因:esp_netif_set_ip_info() 再次触发 GOT_IP,形成死循环,MQTT 无法连接。
解决:仅首次改掩码,改完 return,等第二次 GOT_IP 再置 WIFI_CONNECTED_BIT。
最终决策:关闭 CONFIG_WIFI_NETMASK_OVERRIDE,ESP 使用 /24,与 TP-Link 同网段访问 Pi 0.102。
3.4 Pi OpenWrt 连不上 TP-Link WiFi
现象
iw dev phy0-sta0 link
Not connected.
phy0-sta0: state DOWN
踩坑记录
| 错误配置 | 日志 / 现象 | 正确写法 |
|---|---|---|
band='5g' |
扫不到 2.4G 的 SSID | band='2g' |
band='2.4g' |
band: 2.4g has to be one of [ "2g", "5g", ... ],radio Died |
band='2g' |
htmode='VHT80' on 2.4G |
Not supported (-95) |
htmode='HT20' |
密码 123456789 |
认证失败 | 12345678(与 TP-Link/ESP 一致) |
正确 wireless 片段
uci set wireless.radio0.band='2g'
uci set wireless.radio0.channel='6'
uci set wireless.radio0.htmode='HT20'
uci set wireless.sta.ssid='TP-LINK_02FC'
uci set wireless.sta.key='12345678'
uci set wireless.sta.network='wan'
uci commit wireless
wifi reload
若仍 Failed to initiate sched scan(可选)
echo 'options brcmfmac feature_disable=0x82000' > /etc/modprobe.d/brcmfmac.conf
reboot
3.5 早期硬件 / 工程问题(已解决)
| 问题 | 解决 |
|---|---|
目标芯片误设为 esp32 |
改为 esp32s3 |
| 开启 PSRAM 但板子无 PSRAM | sdkconfig 关闭 SPIRAM |
| GCC ICE(esp_lcd) | 根目录 MINIMAL_BUILD ON |
| USB 线/ hub 供电不稳 | 直连 USB,改善 WiFi 异常 |
四、代码与配置改动摘要
4.1 main/mqtt_node.c
- WiFi 初始化对齐
stationtest(PMF、RAM 存储、RF 兼容、事件重试) - 可选掩码覆盖(默认关闭):
CONFIG_WIFI_NETMASK_OVERRIDE - WiFi 未连接时不启动 MQTT
- MQTT 连上后发布
online、订阅led/set、周期上报 RSSI/uptime
4.2 main/Kconfig.projbuild
WIFI_NETMASK_OVERRIDE(默认 n)WIFI_NETMASKMQTT_BROKER_URI、NODE_ID、WS2812 等
4.3 sdkconfig(当前推荐)
CONFIG_WIFI_SSID="TP-LINK_02FC"
CONFIG_WIFI_PASSWORD="12345678"
# CONFIG_WIFI_NETMASK_OVERRIDE is not set
CONFIG_MQTT_BROKER_URI="mqtt://192.168.0.102:1883"
CONFIG_NODE_ID="esp32-01"
CONFIG_ESP32S3_DEVKITC_LED_WS2812=y
CONFIG_LED_GPIO=48
4.4 Pi Mosquitto
listener 1883
allow_anonymous true
防火墙规则(示例名称):
Allow-MQTT-ESPAllow-MQTT-wan
五、MQTT Topic 与测试命令
Topic 列表
| Topic | 方向 | 说明 |
|---|---|---|
node/esp32-01/status/online |
ESP → Broker | 在线状态,遗嘱 0 |
node/esp32-01/telemetry/rssi |
ESP → Broker | 约每 10s |
node/esp32-01/telemetry/uptime |
ESP → Broker | 约每 10s |
node/esp32-01/led/state |
ESP → Broker | LED 状态反馈 |
node/esp32-01/led/set |
Broker → ESP | 1 开 / 0 关 |
常用命令
Pi 上订阅
mosquitto_sub -h 127.0.0.1 -t 'node/esp32-01/#' -v
PC PowerShell 测端口
Test-NetConnection 192.168.0.102 -Port 1883
控制 LED
mosquitto_pub -h 192.168.0.102 -t "node/esp32-01/led/set" -m "1"
mosquitto_pub -h 192.168.0.102 -t "node/esp32-01/led/set" -m "0"
六、运维建议
6.1 TP-Link 静态地址保留
在 DHCP 服务器 → 静态地址保留 → 添加新条目:
| 设备 | MAC | IP |
|---|---|---|
| Pi WiFi | 2C:CF:67:41:99:62 |
192.168.0.102 |
| ESP32 | 28:37:2F:E5:73:18 |
192.168.0.199 |
绑完后 使所有条目生效。若 Pi IP 变更,需同步修改 CONFIG_MQTT_BROKER_URI 并重新 Flash ESP。
6.2 烧录注意
- 修改
sdkconfig或代码后必须 Build + Flash,不能仅 Monitor 旧固件 - 串口确认:
Compile time更新、无netmask override刷屏、有MQTT connected
6.3 SSH 路径
| 方式 | 地址 |
|---|---|
| PC 网线 → Pi eth0 | ssh root@192.168.50.1 |
| PC/手机 WiFi → Pi STA | ssh root@192.168.0.102 |
七、排查速查表
| 症状 | 优先检查 |
|---|---|
| WiFi reason 2/205 | PMF、SSID/密码、是否 Flash 新固件 |
| WiFi OK,MQTT timeout | ESP 与 Broker 是否同网段;Pi 防火墙 1883 |
netmask override 刷屏 |
升级固件(死循环已修)或关闭 OVERRIDE |
| Pi WiFi Not connected | band=2g(非 2.4g/5g)、HT20、密码 |
Pi radio0 Died |
uci 里 band 必须是 2g / 5g,不能写 2.4g |
| Pi 收不到 ESP 消息 | mosquitto_sub 本地测;Broker URI 是否指向 Pi 当前 0.x IP |
八、经验结论
- 先打通 WiFi,再查 MQTT;MQTT 失败多数是 IP 路由,不是 Mosquitto 配置本身。
- stationtest 能连而 mqtt_node 不能 时,优先对比
wifi_config_t与初始化序列(PMF 一字之差即可 reason 2)。 - Broker 地址不必固定为
50.1;应使用 ESP 能路由到的 Pi 地址(本次为192.168.0.102)。 - OpenWrt 双接口:lan/wan 不同网段是硬性要求;Pi 用 WiFi 作 wan 连 TP-Link 是本次最简可行方案。
- 文档与 lab 环境强相关:换路由器、换 Pi 接线或改 DHCP 后,应重新核对 Broker URI 与静态绑定。
九、后续可选工作
- TP-Link 完成 Pi / ESP 静态 IP 绑定
- 测试
led/set与led/state闭环 - Mosquitto 关闭
allow_anonymous,配置账号密码 - OpenWrt / 上位机订阅
node/esp32-01/#做展示或自动化 - 多节点:修改
CONFIG_NODE_ID烧录第二块板
更多推荐

所有评论(0)