0

What I'm trying to achieve is to use GPIO pin 5 (BCM) on my raspberry pi b+ to receive input from a momentary switch and in response take specified actions.
The actions will differ based on how long the momentary switch is held for.
I was using a piece of code that monitored the pull up pin for interrupts and when detected toggled a different GPIO pin set as an output.
Now I'm trying to do more....and it is not working very well.

I'm trying to use this:

import os
import RPi.GPIO as GPIO
import webiopi
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

BUTTON_5 = 5 

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

GPIO.setup(12,GPIO.OUT)

GPIO.output(12,1)

def system_action(BUTTON_5):
    print('Button press = negative edge detected on channel %s'%BUTTON_5)
    button_press_timer = 0

    while True:

        if (GPIO.input(5) == False) : # if button is pressed down
            button_press_timer += 1 # count seconds until button is released
        else: # button is released, figure out for how long
            if (button_press_timer > 7) : # pressed for > 7 seconds
                subprocess.call(['shutdown -r now "System halted by GPIO action" &'], shell=True)
            elif (button_press_timer > 1) : # press for > 1 < 7 seconds
                GPIO.output(12, not GPIO.input(12))
            button_press_timer = 0
        time.sleep(1)

GPIO.add_event_detect(BUTTON_5, GPIO.FALLING,callback=system_action(BUTTON_5), bouncetime=200)

while True:
   time.sleep (2)

I've tried a few similar variations without any success.
I think this version is the closest I've come.
To elaborate, the goal is to have a momentary switch attached to a pin as a pull up resistor.
The the button is pressed for anything more than one second up to anyhting less than seven seconds it toggles the state of an output pin.
When the button is pressed for seven or more seconds it will reboot the pi.

The code runs without error but when I interact with the button I have wired up.....nothing happens.

What have I missed here? What have I done wrong? What have I done right and what could I do differently.
Any and all help/feedback is appreciated.
I am new to coding and am trying hard to teach myself with practical projects.

  • Just a suggestion: Since you seem to know how to add an interrupt (event) to detect the button being pressed (GPIO.FALLING), can't you just add another event to detect the button being released? Then you can save the timestamp of the press time in the first one, and compare this with release time in the second interrupt, and do your logic based on the value of the difference .... PS: Looks like you are missing some indentation in the pasted code - likely a copy&paste error. You might want to correct this. – Phil B. Sep 30 '15 at 14:36
  • I have fixed the indenting (was a copy + paste error). Thanks. Your suggestion sounds like it would achieve what I am trying to achieve but I'm not really sure how to compare the timestamps. What might this look like? – Meph88 Sep 30 '15 at 14:49
  • You're getting into generic Python support - for which you should post your question on StackOverflow (our larger sister site). Check this post - you should be able to use datetime.now() to get a timestamp, do that in both events (let's say you use variables t1 and t2) and then compare the two by doing t2 - t1 to get the elapsed time. – Phil B. Sep 30 '15 at 14:53
  • That post is helpful. I follow the idea of what's happening but I lack the knowledge of how to generate the time now and time then values. I'm still missing something, I know it's just my lack of knowledge/experience. Is it possible to migrate this question to a more appropriate section like you suggested at StackOverflow? – Meph88 Sep 30 '15 at 15:00
  • I won't do that because if you want help there, you will be much better off sitting down and writing a focused question about, e.g., how to get and compare timestamps in python, and ditch the tangential context about which (to be frank) no one but you cares. If you have a further question about event handling, that's a separate issue; I think all the python pi GPIO libs provide an interface for this, and if you want to ask about it in that context here, that's fine. But remember: Focus and abstract/generalize as far as you can. – goldilocks Sep 30 '15 at 15:44
1

After a substantial amount of investigating and learning I was able to achieve the desired result with the following code:

import os
import RPi.GPIO as GPIO
import webiopi
import time  
import subprocess
import datetime
from datetime import datetime
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
BUTTON_5 = 5
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(12,GPIO.OUT)
GPIO.output(12,1)
#Just to visually distinguish between setup steps and main program
t1 = 999999999999999999999
def pressed(BUTTON_5):
    if GPIO.input(5) == False:
        global t1 
        t1 = datetime.now()
        print "Button 5 pressed"
    elif GPIO.input(5) == True:
        print "Button 5 released"
        t2 = datetime.now()
        delta = t2-t1
        deltaseconds = delta.total_seconds()
        if (deltaseconds > 7) : # pressed for > 7 seconds
            print "Restarting System"
            subprocess.call(['shutdown -r now "System halted by GPIO action" &'], shell=True)
        elif (deltaseconds > 1) : # press for > 1 < 7 seconds
            print "Toggling GPIO 12"
            GPIO.output(12, not GPIO.input(12))
GPIO.add_event_detect(BUTTON_5, GPIO.BOTH, bouncetime=200)
GPIO.add_event_callback(BUTTON_5, pressed)
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    GPIO.cleanup()       # clean up GPIO on CTRL+C exit  

This code seems to run smoothly and I have tested it thoroughly. I had to define "t1" as a global variable, once I learned what they were and how they work it all started to fall into place.

Thank you to everyone who contributed to me getting to this answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.