ESP8266(MicroPython):如何实现无阻塞轮询?
解决ESP8266 + DHT11 非阻塞定时采集的问题
嘿,我完全懂你现在的处境——刚开始搞微控制器编程,用time.sleep()确实能快速实现定时,但代价是整个设备被“锁死”,期间没法响应任何其他操作,这肯定不是长期运行的理想方案。咱们来聊聊MicroPython里处理这类连续任务的核心思路,给你两个实用的方案:
方案1:基于时间戳的非阻塞循环(最基础易理解)
这个思路的核心是记录上次采集的时间,每次循环只检查当前时间和上次时间的差值是否达到设定间隔,而不是让设备进入休眠。这样ESP8266在等待期间可以处理其他任务(比如维持WiFi连接、处理串口输入等)。
示例代码:
import time from machine import Pin import dht # 初始化DHT11传感器 sensor = dht.DHT11(Pin(4)) # 假设你接在D4引脚,可根据实际接线修改 last_read_time = 0 read_interval = 120 # 2分钟,单位秒 while True: current_time = time.time() # 检查是否到了采集时间 if current_time - last_read_time >= read_interval: try: sensor.measure() temp = sensor.temperature() humi = sensor.humidity() print(f"温度: {temp}°C, 湿度: {humi}%") last_read_time = current_time # 更新上次采集时间 except OSError as e: print("读取传感器失败:", e) # 这里可以加其他需要执行的任务,比如检查WiFi连接、处理按键输入等 time.sleep_ms(100) # 短暂休眠,降低CPU占用率
方案2:使用硬件定时器(更高效)
如果你的ESP8266需要处理更复杂的任务,或者不想依赖主循环的轮询检查,可以用machine.Timer模块创建一个定时器,定时触发采集任务。这种方式是硬件级别的定时,不会占用主循环资源。
示例代码:
from machine import Pin, Timer import dht # 初始化DHT11传感器 sensor = dht.DHT11(Pin(4)) def read_sensor(timer): try: sensor.measure() temp = sensor.temperature() humi = sensor.humidity() print(f"温度: {temp}°C, 湿度: {humi}%") except OSError as e: print("读取传感器失败:", e) # 创建定时器,每120秒触发一次(period单位是毫秒,120秒=120000毫秒) timer = Timer(-1) # -1表示使用虚拟定时器,ESP8266支持该模式 timer.init(period=120000, mode=Timer.PERIODIC, callback=read_sensor) # 主循环可以处理其他任务,比如维持网络连接、响应外部输入等 while True: pass
关键概念提醒
- 阻塞vs非阻塞:
time.sleep()是阻塞操作,会暂停整个程序的运行;而时间戳检查或定时器是非阻塞的,程序可以同时处理多个并行任务。 - 异常处理:DHT11这类低成本传感器偶尔会出现读取失败的情况,一定要加
try-except捕获OSError,避免程序直接崩溃。 - 资源优化:主循环里加短暂的
time.sleep_ms()能有效降低CPU使用率,延长ESP8266的续航时间。
希望这些方案能帮到你,要是还有细节问题随时问!
内容的提问来源于stack exchange,提问作者JTW
相关产品推荐
相关产品推荐

