HankB
Posts: 127
Joined: Fri Jan 01, 2016 2:45 pm

GPIO - am I doin' i right?

Thu Mar 17, 2016 8:24 pm

Hi folks,
Here is some code to something (*) when the user presses a button. It generally works but I'm curious if it is really the 'right' way to do this or if I just got lucky. ;)

Code: Select all

#!/usr/bin/python3

"""
    Debounce and detect long press vs. short press from
    a button connected to a GPIO input. The input is 
    configured with a pullup and the external switch 
    shorts the input to ground.

    User needs membership in group 'gpio' for this to work.
"""
import RPi.GPIO as GPIO
import time

#GPIO.setmode(GPIO.BOARD)       # ... in the end there can be only one. ;)
GPIO.setmode(GPIO.BCM)

input=18            # GPIO18 in BCM nomenclature, Pin 12 as Board
debounce = 0.05     # debounce time
longPress = 0.5     # minimum time for long press

GPIO.setup(input, GPIO.IN, pull_up_down=GPIO.PUD_UP)

print("pin", input, "is now", GPIO.input(input))

def myFallingCallback(channel):
    """
    Activate when button is pressed and debounce/wait for long press
    """
    startTime = time.time()         # start timing for long press
    print("timing")
    time.sleep(debounce)            # wait to see if it is going to stay low
    if(GPIO.input(channel)==1):     # go high again?
        return
    loopCount = longPress-2*debounce    # how long to wait
    while loopCount > 0:            # loop for 'long press time' or until button is released
        time.sleep(debounce)        # pause a bit
        if(GPIO.input(channel)==1): # button released?
            print ("single press")
            return
        loopCount -= debounce
    while(GPIO.input(channel)==0):  # loop until button released
        time.sleep(debounce)        # pause a bit
    print("long press")
    return


GPIO.add_event_detect(input, GPIO.FALLING)
GPIO.add_event_callback(input, myFallingCallback)

try:
    while(1):
        time.sleep(5)
        #print("still sleeping", int(time.monotonic()))
except (KeyboardInterrupt, SystemExit):
    print("GPIO cleanup")
    GPIO.cleanup()       # clean up GPIO on CTRL+C exit  

One of the questions I have is what restrictions there are on code that runs in myFallingCallback(). I think this is probably just something that runs in a separate thread (and should be able to do anything) but if it runs as part of an interrupt routine then it would be restricted.

(*) Something in this case is control omxplayer which runs on startup and displays a video to the screen. My plan is to use the short press to cycle omxplayer to the next video and to stop it on a long press. (It's really hard to use the console when omxplayer is running continuously. ;) )

Feel free to comment on any aspect of the script. I'm really a noob when it comes to Python. Most of my efforts have been batch processing incoming data files so the I/O has been a lot more straightforward.

Thanks!

Edit: formatted as quote. Doh!

Return to “Python”