Raspberry Pi Pico W Web服务器闲置后无响应问题排查求助
问题排查与修复方案
1. 给监听Socket添加超时,避免永久阻塞
当前connection.accept()为无限阻塞调用,一旦WiFi链路异常,Pico W会一直卡在该调用中无法恢复。修改open_socket函数,给socket设置超时时间:
def open_socket(ip): address = (ip, 80) connection = socket.socket() connection.bind(address) connection.listen(1) # 设置10秒超时,超时会抛出OSError connection.settimeout(10) return connection
同时在serve函数的循环中捕获超时异常,并检查WiFi连接状态:
def serve(connection,wifi): global light, fan, color_light, color_fan, color_reset light = 0 fan = 0 color_light = "red" color_fan = "red" color_reset = "red" temperature = 0 while True: try: client = connection.accept()[0] except OSError as e: # 捕获socket超时,检查WiFi连接 if not wifi.isconnected(): print("WiFi断开,正在重连...") ip = do_connect()[0] # 重新创建监听socket connection.close() connection = open_socket(ip) continue print(client) try: request = client.recv(1024) except: client.close() continue request = str(request) try: request = request.split()[1] except IndexError: pass print(request) requestHandler(request) html = webpage(temperature, color_light, color_fan, color_reset) try: client.send(html) except: pass client.close()
2. 定期主动检查WiFi连接状态
在循环中添加计数器,定期主动验证WiFi是否在线,避免仅依赖socket超时触发重连:
def serve(connection,wifi): global light, fan, color_light, color_fan, color_reset light = 0 fan = 0 color_light = "red" color_fan = "red" color_reset = "red" temperature = 0 check_count = 0 while True: check_count +=1 # 每30次循环(约5分钟)检查一次WiFi if check_count >=30: check_count =0 if not wifi.isconnected(): print("WiFi连接丢失,正在重连...") ip = do_connect()[0] connection.close() connection = open_socket(ip) try: client = connection.accept()[0] except OSError as e: continue # 后续请求处理代码不变
3. 优化异常处理,避免不必要的重启
原代码中client.recv()异常直接触发设备重启过于激进,改为仅在严重错误时重置,其余情况关闭客户端后继续循环:
try: request = client.recv(1024) except OSError as e: print(f"接收请求出错: {e}") client.close() # 仅在严重网络错误时触发重置 if e.args[0] in [-1, 110]: machine.reset() continue
4. 减少全局变量依赖(可选优化)
过多全局变量可能引发内存管理问题,可将设备状态封装为字典,减少全局变量使用:
# 用字典替代全局变量 device_state = { "light": 0, "fan": 0, "color_light": "red", "color_fan": "red", "color_reset": "red" } def requestHandler(request, device_state, relay_light, relay_fan): if request == '/light?': if device_state["light"] == 1: device_state["color_light"] = "red" relay_light.value(0) device_state["light"] = 0 else: device_state["color_light"] = "green" relay_light.value(1) device_state["light"] = 1 # 其余请求处理逻辑同理,改为操作device_state字典
之后在serve函数中传递该字典即可。
5. 升级MicroPython版本
当前使用的1.20版本存在部分网络相关已知bug,建议升级至最新稳定版(如1.22+),官方已修复大量WiFi与socket稳定性问题。
内容的提问来源于stack exchange,提问作者Rohan Arora
相关产品推荐
相关产品推荐

