You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:52:46