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

树莓派Genset监控项目问题:如何中断计时并返回待机提示

Fixing the Blocking Sleep Issue in Your Raspberry Pi Genset Monitor

Hey there! I see exactly the problem you're stuck with—using time.sleep() locks up your entire program, so even if the genset switches back to standby early, you can't interrupt the timer until it finishes counting down. Let's fix this with a non-blocking approach using Python's threading module, which lets us cancel the timer the second the genset's state changes.

What's Wrong with the Original Code?

The time.sleep() call (I noticed you used 20 seconds for testing, smart move!) blocks your main loop completely. While the program is sleeping, it can't check the GPIO pin for state changes. So even if the genset goes back to standby after 30 minutes, the program won't notice until the sleep finishes—frustrating, right?

Solution: Use threading.Timer for Cancelable Timers

We'll use a Timer object that runs in a background thread. When the genset starts, we kick off the timer. If the genset switches back to standby before the timer finishes, we cancel the timer immediately and print the standby message.

Step-by-Step Modified Code

First, let's fix the typo in your original code (you used DOOR_SENSOR_PIN instead of GENSET_SENSOR_PIN in GPIO.setup()—that would throw an error!). Then add the threading logic:

import RPi.GPIO as GPIO
import time
import threading

GPIO.setmode(GPIO.BCM)
GENSET_SENSOR_PIN = 23
GPIO.setup(GENSET_SENSOR_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Global variable to hold our active timer object
running_timer = None

def print_running_alert():
    """Function that triggers when the timer finishes"""
    print("Genset is still Running!")

try:
    old_is_open = GPIO.input(GENSET_SENSOR_PIN)
    while True:
        current_is_open = GPIO.input(GENSET_SENSOR_PIN)
        
        # Check if the genset's state has changed
        if current_is_open != old_is_open:
            old_is_open = current_is_open
            
            if current_is_open:
                # Genset switched to standby
                print("Genset is Ok")
                # Cancel the timer if it's still running
                if running_timer is not None:
                    running_timer.cancel()
                    running_timer = None
            else:
                # Genset switched to running
                print("Genset is Running!")
                # Cancel any existing timer first (in case of rapid state flips)
                if running_timer is not None:
                    running_timer.cancel()
                # Start a new 1-hour timer (use 20 seconds for testing)
                running_timer = threading.Timer(3600, print_running_alert)
                running_timer.start()
        
        time.sleep(0.01)  # Small delay to keep CPU usage low

finally:
    # Clean up GPIO and cancel timer when exiting the program
    GPIO.cleanup()
    if running_timer is not None:
        running_timer.cancel()

How This Works

  • threading.Timer: This creates a background thread that waits the specified time (3600 seconds for 1 hour) before running the print_running_alert() function. Your main loop keeps running normally, so it can keep checking the GPIO pin for state changes.
  • Instant Cancel on State Change: When the genset switches back to standby, we call running_timer.cancel() to stop the timer immediately. This prevents the "still running" message from printing if the genset didn't stay on for the full hour.
  • Cleanup: The finally block ensures GPIO is properly reset and the timer is canceled when you exit the program—good practice for Raspberry Pi projects to avoid pin lockups.

Testing Tips

For quick testing, replace 3600 with a smaller number like 20 (as you did before). Try switching the genset to standby before the timer finishes—you'll see the standby message right away, and the "still running" message won't print at all.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:57:36