树莓派Pico W与AWS IoT的MQTT连接异常断开问题求助
树莓派Pico W与AWS IoT连接12-24小时后意外断开的排查思路
我正在尝试让树莓派Pico W与AWS IoT建立通信,连接成功后约12-24小时会意外断开。已设置KeepAlive参数,且能观测到设备向服务器发送Ping请求,但Ping会突然停止。目前无法定位连接断开原因,恳请提供排查思路。
相关实现代码
import machine import time import ussl as ssl from robust import MQTTClient def sub_cb(btopic, bmsg): global led led = machine.Pin(15, machine.Pin.OUT) topic = btopic.decode() msg = bmsg.decode() mqtt_message_json = ujson.loads(msg) if 'desired' in mqtt_message_json['state']: led_status_update = (mqtt_message_json['state']['desired']['led_status']) if led.value() != str(led_status_update): if led_status_update == '0': print("turning off LED") led.value(0) elif led_status_update == '1': print("turning on LED") led.value(1) DeviceID='PicoTestBed03' PORT=8883 AWS_ENDPOINT={My AWS API End Point} DISCONNECTED = 0 CONNECTING = 1 CONNECTED = 2 state = DISCONNECTED KeepAliveSeconds = 60 led = machine.Pin(15, machine.Pin.OUT, value=1) #Use Websockets useWebsocket = False #Create SSL Params object #Assume the cert, key, and rootCA are all created correctly because my connection is successful SSL_PARAMS = {'cert': cert, 'key': key, 'server_side': False, "cert_reqs":ssl.CERT_REQUIRED, 'cadata':rootCA} #Create MQTT Client client = MQTTClient(DeviceId, AWS_ENDPOINT, port=PORT, keepalive=KeepAliveSeconds, ssl=True, ssl_params=SSL_PARAMS) #Connect MQTT Client while state != CONNECTED: try: state = CONNECTING print('AWS TEST: Trying to connect via MQTT...') client.connect() state = CONNECTED except Exception as e: print('AWS TEST: Could not establish MQTT connection') continue print('AWS TEST: MQTT LIVE!') device_shadow_last_checked = time.localtime() while 1: if current_led_status != led.value(): current_led_status = led.value() device_shadow_update_msg = b'{"state":{"reported":{"led_status":%d}}}' %(led.value()) mqtt_client.publish(led_status_shadow_topic_update, device_shadow_update_msg, qos=0) if (time.mktime(time.localtime()) - time.mktime(device_shadow_last_checked)) >=60: client.ping() device_shadow_last_checked = time.localtime() client.check_msg()
排查思路
- 修复代码逻辑错误
current_led_status未初始化就进行比较,会导致首次循环报错中断后续逻辑,需在主循环前添加current_led_status = led.value()。- 代码中
mqtt_client未定义,实际应为创建的client对象,该错误会导致发布消息时抛出异常中断循环。 led_status_shadow_topic_update变量未定义,需补全主题定义(如led_status_shadow_topic_update = f"$aws/things/{DeviceID}/shadow/update")。
- 优化MQTT保活逻辑
- 当前Ping操作嵌套在LED状态变化分支中,LED状态不变时会完全停止Ping,违反KeepAlive机制。需将Ping和
check_msg()移到分支外部,确保每次循环都执行保活检查:current_led_status = led.value() device_shadow_last_checked = time.time() while 1: # 检查LED状态变化并上报 if current_led_status != led.value(): current_led_status = led.value() device_shadow_update_msg = b'{"state":{"reported":{"led_status":%d}}}' %(led.value()) client.publish(led_status_shadow_topic_update, device_shadow_update_msg, qos=0) # 定时发送Ping并检查消息 if (time.time() - device_shadow_last_checked) >= KeepAliveSeconds: client.ping() device_shadow_last_checked = time.time() client.check_msg() time.sleep(0.1) # 降低CPU占用
- 当前Ping操作嵌套在LED状态变化分支中,LED状态不变时会完全停止Ping,违反KeepAlive机制。需将Ping和
- 排查网络与硬件稳定性
- 定期检查Wi-Fi连接状态,断开时重新连接并重建MQTT连接:
import network wlan = network.WLAN(network.STA_IF) # 在主循环中添加 if not wlan.isconnected(): print("Wi-Fi disconnected, reconnecting...") wlan.connect(SSID, PASSWORD) while not wlan.isconnected(): time.sleep(1) client.connect() - 检查电源供应是否稳定,建议使用官方推荐的5V/2A电源,避免因电压波动导致模块异常。
- 定期检查Wi-Fi连接状态,断开时重新连接并重建MQTT连接:
- MQTT客户端与AWS配置检查
- 确认
robust.MQTTClient是否正确处理Ping响应,可替换为umqtt.simple或umqtt.robust库测试。 - 查看AWS IoT控制台的连接日志,获取断开时的错误代码,明确终止原因(如超时、认证失败等)。
- 尝试调整KeepAlive时间为120秒,避免过于频繁的Ping导致网络负载,同时确保客户端在周期内至少发送一次消息。
- 确认
内容的提问来源于stack exchange,提问作者michaeka
相关产品推荐
相关产品推荐

