A little help with python

Caporegime
Joined
18 Oct 2002
Posts
25,287
Location
Lake District
I'm trying to wrap my brains around getting the following to work:

A timer is set for 5 minutes which then begins to count down, if a GPIO pin goes high, a command is executed then the timer is reset back to 5 minutes, however if it goes low, the timer continues to run out, when the timer reaches zero, a command is executed.

I think I'm going to have to use threading to do this? I'm using a callback from the GPIO.add_event_detect but I can't get my head around the logic required to make this work.
 
I'm not too familiar with Python and GPIO but there is two ways to approach it - either having a main loop in your program that periodically queries the GPIO state and then does something or interrupt based where a function will be called (externally program execution moved to a specific place) when an event happens.

I'm not personally a fan of built in timers - I prefer to set a variable to a millisecond value and then calculate time passed since when needed and reset as appropriate.

EDIT: For your use milliseconds probably not relevant so you can just use "import time" and reference time.time() to get seconds.
 
Last edited:
This is what I have ended up with and it appears to be working:

Code:
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import subprocess
GPIO.setmode(GPIO.BCM)
PIR_PIN = 7
GPIO.setup(PIR_PIN, GPIO.IN)
global timer
timer = 300 # 5 mins
subprocess.call("sudo /home/pi/rpi-hdmi.sh on", shell=True)
try :
    print "Screen Timer (CTRL+C to exit)"
    time.sleep(5)
    print "Ready..."
    while 1:
        time.sleep(0.985)
        print timer
        # Test PIR_PIN condition
        current_state = GPIO.input(PIR_PIN)
        if timer > 0:
            timer -= 1
            if current_state: #is true
                # Reset timer
                timer = 300
        else:
            if current_state: #is true
                subprocess.call("sudo /home/pi/rpi-hdmi.sh on", shell=True)
                # Reset timer
                timer = 300
            else:
                # Wait for edge
                channel = GPIO.wait_for_edge(PIR_PIN, GPIO.RISING)
                if channel is None:
                        print('Timeout occurred')
                else:
                        subprocess.call("sudo /home/pi/rpi-hdmi.sh on", shell=True)
                        # Reset timer
                        timer = 300
except KeyboardInterrupt:
    print "Quit"
    GPIO.cleanup()
 
Actually that didn't work and it got stuck waiting for edge, revised code is now below, but having issues with false positives on the PIR.

Code:
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import subprocess
GPIO.setmode(GPIO.BCM)
PIR_PIN = 7
GPIO.setup(PIR_PIN, GPIO.IN)
global timer
time_limit = 300 #5 mins
timer = time_limit
subprocess.call("sudo /home/pi/rpi-hdmi.sh off", shell=True)
try :
    print "Screen Timer (CTRL+C to exit)"
    time.sleep(5)
    print "Ready..."
    while 1:
        time.sleep(0.985)
        # Test PIR_PIN condition
        current_state = GPIO.input(PIR_PIN)
        if timer > 0:
            timer -= 1
        if current_state: #is true
                subprocess.call("sudo /home/pi/rpi-hdmi.sh on", shell=True)
                # Reset timer
                timer = time_limit
        elif timer == 0:
                # turn off hdmi as timer expired
                subprocess.call("sudo /home/pi/rpi-hdmi.sh off", shell=True)
                # Wait for edge
                channel = GPIO.wait_for_edge(PIR_PIN, GPIO.RISING)
                if channel == PIR_PIN:
                        # turn hdmi back on
                        subprocess.call("sudo /home/pi/rpi-hdmi.sh on", shell=True)
                        # Reset timer
                        timer = time_limit
except KeyboardInterrupt:
    print "Quit"
 
Last edited:
Some really quick and dirty code but my approach would have been

Code:
import time
import sys

timer_end = time.time() + 300

try:
    while 1:
        current_state = GPIO.input(PIR_PIN)
        if current_state:
            subprocess.call("sudo /home/pi/rpi-hdmi.sh on", shell=True)
            timer_end = time.time() + 300
        if time.time() >= timer_end:
            subprocess.call("sudo /home/pi/rpi-hdmi.sh off", shell=True)
            channel = GPIO.wait_for_edge(PIR_PIN, GPIO.RISING)
            if channel == PIR_PIN:
                subprocess.call("sudo /home/pi/rpi-hdmi.sh on", shell=True)
                timer_end = time.time() + 300
        time.sleep(1)
except KeyboardInterrupt:
    sys.exit(0)

No idea if that is functional and/or might have missed something in what you are trying to do - I've not touched Python in years and years. Not a fan of the way you are progressing the timer unless I'm misunderstanding and personally not a fan of blocking functions though for the kind of stuff you are doing that is by the by.
 
Back
Top Bottom