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

Python中树莓派LED延时控制的代码优化问题

优化树莓派LED延时点亮方案(基于程序启动延时,而非固定时间点)

原代码的核心问题是依赖固定系统时间点,且硬编码修改不便。下面提供的方案基于程序启动后的相对延时实现,完全符合你“启动N分钟后点亮第一个LED,再过M分钟点亮第二个”的需求,同时灵活性拉满:

优化后代码

import RPi.GPIO as GPIO
from datetime import datetime, timedelta
import time

# 配置区:可直接修改这里的参数,无需改动逻辑代码
LED_CONFIGS = [
    {"gpio": 24, "delay_minutes": 5, "message": "请服用第一种药物"},
    {"gpio": 6, "delay_minutes": 10, "message": "请服用第二种药物"},
    # 可以继续添加更多LED配置,比如 {"gpio":5, "delay_minutes":15, "message": "..."}
]
LED_ON_DURATION = 10  # LED点亮持续时间(秒)
CHECK_INTERVAL = 1    # 状态检查间隔(秒,可根据精度调整)

# GPIO初始化
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
for config in LED_CONFIGS:
    GPIO.setup(config["gpio"], GPIO.OUT)
    GPIO.output(config["gpio"], False)  # 初始状态熄灭

# 记录程序启动时间
start_time = datetime.now()
# 标记每个LED是否已经点亮过
led_triggered = {config["gpio"]: False for config in LED_CONFIGS}

try:
    while True:
        current_time = datetime.now()
        # 遍历每个LED配置,检查是否到达触发时间
        for config in LED_CONFIGS:
            gpio_pin = config["gpio"]
            # 计算该LED的触发时间:启动时间 + 配置的延时
            trigger_time = start_time + timedelta(minutes=config["delay_minutes"])
            
            # 如果还没触发过,且当前时间已超过触发时间
            if not led_triggered[gpio_pin] and current_time >= trigger_time:
                print(f"{current_time.strftime('%H:%M:%S')} - {config['message']}")
                GPIO.output(gpio_pin, True)
                # 保持点亮指定时长后熄灭
                time.sleep(LED_ON_DURATION)
                GPIO.output(gpio_pin, False)
                led_triggered[gpio_pin] = True  # 标记为已触发,避免重复执行
        
        # 检查所有LED是否都已触发,完成后退出循环(可选)
        if all(led_triggered.values()):
            print("所有LED任务已完成,退出程序")
            break
        
        time.sleep(CHECK_INTERVAL)

finally:
    print("清理GPIO资源")
    GPIO.cleanup()

关键优化点说明

  • 配置与逻辑分离:所有可调整参数都放在LED_CONFIGS和LED_ON_DURATION里,修改延时、添加LED只需要改配置列表,不用碰核心逻辑。
  • 基于启动时间的相对延时:用start_time记录程序启动时刻,每个LED的触发时间是启动时间 + 配置的延时,完全不依赖系统固定时间,重启程序就重新计时。
  • 状态标记避免重复触发:用led_triggered字典记录每个LED是否已经执行过,防止循环中重复点亮。
  • 可选的任务完成退出:当所有LED都触发完成后自动退出,也可以去掉这段逻辑让程序一直运行(比如需要循环执行的场景)。

扩展建议

如果需要支持循环执行(比如每天重复这个流程),可以把start_time的逻辑改成基于当天零点的时间计算,或者用定时任务框架(比如APScheduler),但对于简单的延时需求,上面的代码已经足够轻量好用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:41:06