在Pico W的MicroPython中多线程运行报错:core1 in use
解决Raspberry Pi Pico W MicroPython线程启动报错:OSError: core1 in use
错误原因
Raspberry Pi Pico W是双核MCU,但MicroPython的_thread模块仅支持启动一个额外线程:主程序默认运行在core0,第一个start_new_thread会占用core1,尝试启动第二个线程时就会触发"core1 in use"错误。此外,你使用的PicoGraphics库初始化LCD时,可能已经在后台占用core1驱动显示,进一步加剧了线程冲突。
解决方案:单线程非阻塞合并任务
由于Pico W的MicroPython不支持多开额外线程,我们可以将显示更新和web服务合并到同一个主循环,通过非阻塞socket处理请求,避免程序被阻塞。
修改后的代码
"""BME688 / BME680 demo This demo will work for both the BME680 and BME688. """ print("lets import and use the libraries") import time from time import sleep import network import socket from breakout_bme68x import BreakoutBME68X, STATUS_HEATER_STABLE from pimoroni_i2c import PimoroniI2C from picographics import PicoGraphics, DISPLAY_LCD_240X240, PEN_P8 display = PicoGraphics(display=DISPLAY_LCD_240X240, pen_type=PEN_P8) display.set_backlight(1.0) WIDTH, HEIGHT = display.get_bounds() ssid = 'netgear_2.4g' #Your network name password = '9xc4prce' #Your WiFi password print("setting pin breakouts etc") PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} print("finish setting pins and now set i2c") i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) print("i2c set and now set bme") bme = BreakoutBME68X(i2c) print("bme set") # If this gives an error, try the alternative address # bme = BreakoutBME68X(i2c, 0x77) temperatureReadingData = ["","0.0c"] print("Testing sensors on the while loop") def connect(): #Connect to WLAN wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.connect(ssid, password) while wlan.isconnected() == False: print('Waiting for connection...') sleep(1) ip = wlan.ifconfig()[0] print(f'Connected on {ip}') return ip def open_socket(ip): # Open a socket and set to non-blocking address = (ip, 80) connection = socket.socket() connection.bind(address) connection.listen(1) connection.setblocking(False) # 设置socket为非阻塞模式 return connection def readTemperature(): temperature, pressure, humidity, gas, status, _, _ = bme.read() heater = "Stable" if status & STATUS_HEATER_STABLE else "Unstable" temperatureReadingData[0] = "Temperature is {:0.2f}c, Pressure is {:0.2f}Pa, humidity is {:0.2f}%, gas is {:0.2f} Ohms, Heater: {}".format(temperature, pressure, humidity, gas, heater) temperatureReadingData[1] = "{:0.2f}c".format(temperature) def webpage(reading): #Template HTML html = f""" <!DOCTYPE html> <html> <head> <title>Pico W Weather Station</title> <meta http-equiv="refresh" content="10"> </head> <body> <p>{reading}</p> </body> </html> """ return str(html) if __name__ == "__main__": try: # 初始化WiFi和非阻塞socket ip = connect() connection = open_socket(ip) while True: # 处理传感器读取与显示更新 readTemperature() print("display temp" + temperatureReadingData[1]) display.clear() display.set_pen(15) display.text(temperatureReadingData[1], 0, 0, scale=4) display.update() # 非阻塞处理web客户端请求 try: client = connection.accept()[0] request = client.recv(1024) html = webpage(temperatureReadingData[0]) client.send(html) client.close() except OSError: # 无客户端连接时忽略错误 pass time.sleep(1.0) except KeyboardInterrupt: import machine machine.reset()
关键修改点
- socket设置为非阻塞:在
open_socket函数中添加connection.setblocking(False),这样accept()不会一直等待连接,没有请求时会抛出OSError,我们捕获并忽略即可。 - 合并任务到主循环:去掉多线程启动逻辑,在同一个while循环中依次执行显示更新和web请求处理,确保两个任务都能正常运行。
- 修复KeyboardInterrupt中的模块缺失:在中断处理中导入
machine模块,避免重置时报错。
内容的提问来源于stack exchange,提问作者Jono
相关产品推荐
相关产品推荐

