I'm getting started with a project on a Raspberry Pi (never done anything with RPi or python before, so it's all new to me, but I've done a little Arduino stuff). I'm trying to create a very simply python script to run a bit of code whenever a digital input signal switches from low to high or high to low.
I'm treating the input as a button, and using the gpiozero
library. I'm trying to use the callback method to run my code whenever the transitions take place.
The problem is that the callback only happens once. I expect each callback to run every time I make or break contact on the switch, so I should see "pressed" and "released" printed N times if I toggle the switch N times. But instead I only see a single line printed, as though the callbacks are firing once and then just stopping. The script does not exit (because of the "pause" call at the end), so that's not the problem.
I've based my work on the examples in the gpiozero Recipes. There is an example (See 3rd codeblock under the "Button" heading) that is almost exactly what I need, and the description says "Run a function every time the button is pressed", but my code only runs the function once.
Perhaps I'm making some newbie RPi or Python mistake, but I'm stuck. Please help me out. Thanks.
Here is my code:
from gpiozero import Button
import signal
button = Button(3)
def pressed():
print("pressed")
def released():
print("released")
button.when_pressed = pressed
button.when_released = released
signal.pause()
1 Answer 1
I think the signal.pause()
may be the issue.
Could you replace signal.pause()
with the following?
import time
while True:
time.sleep(1)
Alternatively perhaps you should try GPIO4. GPIO2 and GPIO3 have hard-wired pull-ups to 3V3. Does your button take this into account?
EDITED TO ADD
Given that both of the above variants work on my system perhaps your system is out of date.
Try updating the modules, e.g.
sudo apt-get update
sudo apt-get upgrade
If it still doesn't work try the following if your system is very old
sudo apt-get dist-upgrade
-
1Yes, I actually depend on the pull-up. The button either leaves the pin floating (and hence pulled-up) or connects it to ground. I'll try your suggestion this evening.rothloup– rothloup2016年06月02日 20:34:48 +00:00Commented Jun 2, 2016 at 20:34
-
Tried it. Behavior is unchanged. Does the execution environment matter? I'm running this in IDLE3.rothloup– rothloup2016年06月02日 23:07:42 +00:00Commented Jun 2, 2016 at 23:07
-
1I've moved the relevant pin to GPIO 4 (pin 7), which has no hard-wired pull-ups. I've also including code to print "pressed" or "not pressed" in the while loop. The "pressed" and "not pressed" messages print and toggle properly - but it still only fires the callback once.rothloup– rothloup2016年06月03日 19:59:39 +00:00Commented Jun 3, 2016 at 19:59
-
I'm afraid both versions work fine for me. Make sure your modules are up to date (sudo apt-get update/upgrade).joan– joan2016年06月03日 20:01:44 +00:00Commented Jun 3, 2016 at 20:01
-
1Joan -- I independently came to the same conclusion that I probably needed to update my system, and that did fix the issue (I was using a fresh raspbian install that was created in 2013) . After sudo apt-get dist-upgrade, it works as expected. Thanks for your help. Why don't you update your answer with your comment so I can accept it as the correct solution? The time.sleep(1) and signal.pause() methods both work.rothloup– rothloup2016年06月04日 01:56:37 +00:00Commented Jun 4, 2016 at 1:56