4

I'm trying to read from all my Raspberry Pi B+ GPIOs. Using the Python3 RPi.GPIO library, it is quite easy to do, but I've come across a problem that I can't seem to resolve :

GPIO 17 does not trigger callbacks

I don't know if it's me, the library or the hardware; I'm using a very standard Rapsbian, no fancy stuff, on a stock Raspberry Pi B+. I've tested this on different boards (all new) but same behavior everywhere.

Quick and dirty test script :

import RPi.GPIO as GPIO

pin = 17

GPIO.setmode(GPIO.BCM)

def callback(channel):
  print("Callback trigger (%d)" % channel)

GPIO.setup(pin, GPIO.IN, GPIO.PUD_DOWN)
GPIO.add_event_detect(pin, GPIO.RISING, callback=callback, bouncetime=300)

while(True):
  if (GPIO.input(pin) == 1):
    print("Direct trigger")

If you run this with say, a button attached between 3V3 and GPIO 17 (PIN 1-11), and push it, you will never reach the callback function. Never. But the pin will correctly report its state, and the print statement in the while will get executed as expected.

If you run this script on any other pins, you get to see the print function from the callback AND the print function from the while loop.

Any ideas ? I feel lost !

Thanks a lot !

1

4 Answers 4

6

Ok. I think I found it.

Once, I installed and connected a screen to my B+, a 4DPi-32 3.2” Primary Display Cape to be exact (datasheet here from 4DSystems).

Before doing my tests, I had uninstalled everything related to x11, spi, i2c, etc .. but the driver of the screen had remained somewhere.

If I read correctly page 5 of the above datasheet, pin 12 named PENIRQ of the expansion header (that corresponds to GPIO 17 of the P2 pinout, oh boy) is an interrupt for the touchscreen controller.

I removed it with a simple dpkg -r kernel4dpi and rebooted, and now the callback seems to get triggered correctly along with the "direct" trigger.

So my guess is that even when the screen is not connected, the driver consumes all the epoll events broadcasted by the pin, these events are thus removed from the event queue and never reach anything else. This is a bit confusing since the driver must know that the screen is not here (it definitely can't communicate with it since I removed spi from the system), but eventhough, it still hogs the events from GPIO 17.

PS : I had the same linux image on different B+, with the same driver installed, hence the fact that I had the same behaviour on different stock Pi ...

1
  • Interesting finding! Lesson learned. Thanks for sharing!
    – sanyi
    Nov 2, 2014 at 14:52
0

The code uses the internal pull-down to 0V so shorting it to ground will never make a difference. Connecting it to 3V3 and then disconnecting it from 3V3 should trigger the callback,

The code refers to 17. This is a gpio as you are using BCM mode. gpio17 is brought out to pin P1-11. Pin P1-17 is the 3V3 rail (NOT a gpio).

1
  • Yes I meant between 3V3 and gpio 17 (Pin 1-11) sorry, edited.
    – tchap
    Oct 24, 2014 at 7:38
0
+50

The code works for me, I can see the "Callback trigger" message.

The callback code happens in different thread than the main thread with the wile loop checking restlessly for the GPIO pin. You may have to ease a bit the main loop to give the opportunity for the interrupt thread to print out code.

Try instead the while loop the following code (to simple idle there instead busy waiting):

import time
time.sleep(1000)
5
  • Even on GPIO 17 ? I've tried your solution (time.sleep instead of the while loop) but to no avail. I'm starting to think that all the B+ I've got have a dead GPIO 17 ...
    – tchap
    Oct 27, 2014 at 19:18
  • Yes, I tried your code exactly as it is. Small chance that your GPIO 17 is dead if you are able to correctly test it's input by reading GPIO.input(pin). Maybe something else interferes with your code.
    – sanyi
    Oct 27, 2014 at 19:45
  • But then if it's dead I don't understand why the direct trigger is properly fired and the callback is not. Both should not work then. It's weird.
    – tchap
    Oct 27, 2014 at 19:48
  • It is. The RPi.GPIO module, behind the scenes waits for epoll events on a new thread, you can try to insert some debug code there and see what is actually happening.
    – sanyi
    Oct 27, 2014 at 20:02
  • 1
    PS : bounty goes to you anyway for directing me to the epoll events and trying stuff out ;) Thanks !
    – tchap
    Oct 29, 2014 at 23:05
0

Sorry, but since I don't have enough reputation points to comment, had to add as an answer. I guess sanyi wanted to say that you should add the sleep in the while loop. I guess from your comment you removed the while loop completely and replaced it with time.sleep. Try adding that sleep in the while loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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