无法将Raspberry Pi Pico W连接到MQTT代理,未收到CONNACK响应
Raspberry Pi Pico W无法连接密码保护的MQTT代理问题
问题描述
我尝试将Raspberry Pi Pico W连接到运行MQTT代理和Node-RED服务器的虚拟机,该MQTT代理受密码保护。Node-RED的MQTT节点已配置代理IP且连接正常,但通过Thonny在Pico上运行MicroPython脚本时,设备无法连接到MQTT代理,收不到CONNACK信号,报错socket read timeout。
运行的MicroPython脚本
from mqtt_as import MQTTClient, config import uasyncio as asyncio import socket # Local configuration config['ssid'] = 'user' config['wifi_pw'] = 'password' config['server'] = '192.168.122.1' # Change to suit e.g. 'iot.eclipse.org' async def messages(client): # Respond to incoming messages async for topic, msg, retained in client.queue: print((topic, msg, retained)) async def up(client): # Respond to connectivity being (re)established while True: await client.up.wait() # Wait on an Event client.up.clear() await client.subscribe('Nodered', 0) # renew subscriptions async def main(client): print("Hello") await client.connect() print("Hello") for coroutine in (up, messages): asyncio.create_task(coroutine(client)) n = 0 while True: await asyncio.sleep(5) print('publish', n) # If WiFi is down the following will pause for the duration. await client.publish('Nodered', 'hello there', qos = 0) n += 1 config["queue_len"] = 1 # Use event interface with default queue size MQTTClient.DEBUG = True # Optional: print diagnostic messages client = MQTTClient(config) try: asyncio.run(main(client)) finally: client.close() # Prevent LmacRxBlk:1 errors
错误信息
MPY: soft reboot Hello Checking WiFi integrity. Got reliable connection Connecting to broker. Traceback (most recent call last): File "<stdin>", line 38, in <module> File "uasyncio/core.py", line 1, in run File "uasyncio/core.py", line 1, in run_until_complete File "uasyncio/core.py", line 1, in run_until_complete File "<stdin>", line 22, in main File "/lib/mqtt_as.py", line 645, in connect File "/lib/mqtt_as.py", line 314, in _connect File "/lib/mqtt_as.py", line 213, in _as_read OSError: (-1, 'Timeout on socket read')
解决方案
1. 添加MQTT认证信息
你的MQTT代理是密码保护的,但当前脚本未配置用户名和密码,这是最可能的原因。在config配置中添加以下两行:
config['user'] = '你的MQTT代理用户名' config['password'] = '你的MQTT代理密码'
2. 验证网络连通性
- 测试端口可达性:在Pico上添加一段代码测试MQTT默认端口(1883)是否开放:
s = socket.socket() try: s.connect(('192.168.122.1', 1883)) print("端口1883可连接") except OSError as e: print(f"连接失败: {e}") s.close() - 检查防火墙设置:确保虚拟机的防火墙允许1883端口的入站连接,可临时关闭防火墙测试。
- 确认代理绑定地址:检查MQTT代理的配置文件,确保
bind_address设置为0.0.0.0(允许所有IP访问),而非127.0.0.1(仅本地访问)。
3. 调整连接超时时间
如果网络存在延迟,可增大mqtt_as的连接超时,在config中添加:
config['connect_timeout'] = 10 # 单位:秒,默认可能为5秒
4. 查看MQTT代理日志
检查虚拟机上MQTT代理的日志文件,查看是否有来自Pico的连接请求记录,比如认证失败、IP被拒绝等信息,这能快速定位问题。
内容的提问来源于stack exchange,提问作者Magnus Bane
相关产品推荐
相关产品推荐

