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

如何用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)

代码说明

  1. 配置参数区:可直接修改测试/实际参数,无需改动核心逻辑
  2. 状态变量:
    • last_light_time:每次检测到光照就更新,用于计算持续无光照时长
    • fan_running_until:记录风扇应关闭的时间,通过时间戳对比判断是否停止
    • last_fan_start_time:记录上次启动风扇的时间,用于判断是否达到再次启动间隔
  3. 主循环逻辑:
    • 优先处理光照情况,重置所有风扇状态
    • 无光照时先关闭LED,再判断风扇是否需要启动/保持运行
    • 用时间戳对比替代utime.sleep(),避免阻塞主循环影响LDR检测

测试与切换

  • 测试阶段用当前秒级参数验证逻辑,确认无误后修改:
    • FAN_RUN_DURATION = 300(5分钟)
    • FAN_REPEAT_INTERVAL = 86400(1天,246060)

内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 20:50:25