如何用LDR控制5V风扇、WS2812 LED环及定时功能(Pico+MicroPython)
解决方案
核心思路是用时间戳跟踪状态,不用复杂调度库,适配MicroPython轻量环境,能准确实现定时逻辑。
关键逻辑梳理
- 用
utime.time()获取秒级时间戳,避免定时器溢出问题 - 跟踪3个核心状态:
- 上次检测到光照的时间:判断是否持续无光照
- 风扇运行结束时间:判断是否需要关闭风扇
- 上次启动风扇的时间:判断是否达到再次启动的间隔
完整代码
from machine import Pin, ADC import utime from ws2812b import ws2812b # -------------------------- 配置参数 -------------------------- # 测试用秒级参数,实际使用时修改为分钟/天级 LIGHT_THRESHOLD_LOW = 10000 # 有光照的阈值 LIGHT_THRESHOLD_HIGH = 50000 # 无光照的阈值 FAN_RUN_DURATION = 5 # 风扇单次运行时长(秒,测试用,实际改300=5分钟) FAN_REPEAT_INTERVAL = 10 # 持续无光照下再次启动风扇的间隔(秒,测试用,实际改86400=1天) # 硬件初始化 num_leds = 8 pixels = ws2812b(num_leds, 0, 0, delay=0) relay = Pin(15, Pin.OUT) ldr = ADC(Pin(28)) # 状态初始化 pixels.fill(0, 0, 0) pixels.show() relay.value(0) last_light_time = utime.time() # 上次检测到光照的时间戳 fan_running_until = 0 # 风扇运行结束的时间戳(0表示未运行) last_fan_start_time = 0 # 上次启动风扇的时间戳 # -------------------------- 工具函数 -------------------------- def turn_off_leds(): pixels.fill(0, 0, 0) pixels.show() def turn_on_leds(): pixels.fill(255, 255, 255) pixels.show() # -------------------------- 主循环 -------------------------- while True: current_time = utime.time() ldr_value = ldr.read_u16() print(f"LDR读数: {ldr_value}") # 情况1:检测到光照 if ldr_value < LIGHT_THRESHOLD_LOW: last_light_time = current_time # 更新光照时间 relay.value(0) # 关闭风扇 turn_on_leds() # 点亮LED # 重置风扇状态 fan_running_until = 0 last_fan_start_time = 0 # 情况2:无光照 elif ldr_value > LIGHT_THRESHOLD_HIGH: turn_off_leds() # 关闭LED # 判断是否需要启动/保持风扇运行 # 条件1:风扇未在运行,且满足启动条件(首次进入无光 或 距离上次启动超过间隔) if fan_running_until <= current_time: time_since_last_fan = current_time - last_fan_start_time time_since_last_light = current_time - last_light_time # 首次无光照 或 持续无光照达到重复间隔 if last_fan_start_time == 0 or time_since_last_fan >= FAN_REPEAT_INTERVAL: last_fan_start_time = current_time fan_running_until = current_time + FAN_RUN_DURATION relay.value(1) # 启动风扇 print("风扇启动,将运行", FAN_RUN_DURATION, "秒") # 条件2:风扇正在运行中,保持开启 else: relay.value(1) # 风扇运行时间到,关闭 if current_time >= fan_running_until and fan_running_until != 0: relay.value(0) print("风扇已关闭") utime.sleep(0.2)
代码说明
- 配置参数区:可直接修改测试/实际参数,无需改动核心逻辑
- 状态变量:
last_light_time:每次检测到光照就更新,用于计算持续无光照时长fan_running_until:记录风扇应关闭的时间,通过时间戳对比判断是否停止last_fan_start_time:记录上次启动风扇的时间,用于判断是否达到再次启动间隔
- 主循环逻辑:
- 优先处理光照情况,重置所有风扇状态
- 无光照时先关闭LED,再判断风扇是否需要启动/保持运行
- 用时间戳对比替代
utime.sleep(),避免阻塞主循环影响LDR检测
测试与切换
- 测试阶段用当前秒级参数验证逻辑,确认无误后修改:
FAN_RUN_DURATION = 300(5分钟)FAN_REPEAT_INTERVAL = 86400(1天,246060)
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

