-
-
Notifications
You must be signed in to change notification settings - Fork 146
add_interrupt_callback error #31
Comments
93 # workaround |
Thank you for helping. I hope I have understood what you intended and have implemented it correctly, but it is not working for me. I am getting an error that the RPIO module does not have an attribute called 'channel_to_gpio': Traceback (most recent call last): I changed my program to use BCM pin numbering throughout to avoid needing to change back and forward, and the relevant parts now read: import RPi.GPIO as IO P0 = 17 new_P0= IO.channel_to_gpio(P0) # doorbell push new_P1= IO.channel_to_gpio(P1) # magnetic contact new_P2= IO.channel_to_gpio(P2) # PIR My overall aim is to have 3 different possible triggers (interrupts), each with a different callback. And if there are multiple interrupts, I want the callbacks to run sequentially. |
Looking at the source to add_interrupt_callback, I can see that the gpio id passed in is run through channel_to_gpio to handle the mapping for the current mode (BOARD or BCM). When in BOARD mode, the gpio_id is mapped from pin number to GPIO number. add_interrupt_callback then calls other functions such as gpio_function passing this mapped gpio_id. Those functions also call channel_to_gpio with that id, so the GPIO id mapping is applied twice, leading to incorrect values and the resulting behaviour. In the best scenario, this will be the 'invalid channel' exception - in the worst scenario, this could map to another GPIO altogether... I suspect add_interrupt_callback has had insufficient testing in BOARD mode :) |
I have a fix for the issue in my own fork (https://github.com/dozencrows/RPIO/tree/dc-dev) and have made a pull request for it (#42) |
I now have my interrupt threading working, such that interrupt handling code for the first interrupt runs to completion before the second interrupt is handled etc. BUT I have a new problem in that my routines using RPIO detect events (triggers) that are not actually present - even if I disconnect all wires from the trigger pins, events are detected and interrupts called.. Apart from being unable to control threading, my hardware works properly with RPi.GPIO, with no unexpected interrupts occurring. So what is wrong? My full code using RPIO is below, followed by the equivalent version for RPi.GPIO. Non-working RPIO version: on = 1 This is not needed for RPIO # RPIO.setmode(RPIO.BCM) # This version set to use BCM (Broadcom, the processor chip) GPIO$
RPIO.setwarnings(False) # Turn off warning messages (occur when run program after 1st time) Set up pin numberingThese are tested and found to be correctright side, top to bottomP0 = 17 # BCM 17 left side, top to bottomCE1 = 7 # BCM 7 Set P0 to P3 as inputs with pull up resistors on P0 and P1RPIO.setup(P0, RPIO.IN, pull_up_down=RPIO.PUD_UP) # Doorbell push; pressing will ground this pin set P4 to P7 as outputs to relays etcRPIO.setup(P4, RPIO.OUT) Set output P4 LOW (for Piezo sounder)set all other outputs HIGH ( = relay off)RPIO.output(P4, off) # Piezo sounder time.sleep(1) # pause to allow inputs to settle before enabling interrupts P1 is magnetic contact. Pulled UP. Normally pin is connected to GROUNDWhen magnet removed, switch opens, pull up causes HIGHP2 is PIR. Requires power of +5v, but output is 3v (RPi 3v3 compatible)Output goes ON when movement detectedTrimmers adjust (a) sensitivity and (b) ON duration after detectionP3 Sound Detector. Requires power of 3-20v; we are using 3.3v.Digital Output goes OFF and LED lights when sound detectedTurn resistor ANTICLOCKWISE for greater sensitivityBecause there are multiple triggers, cannot use "Wait for edge"Define "Events" for each trigger and generate a "Callback" whenever that event occursFirst define the actions to take for each triggerThen IO.add_event_detect(pin,IO.RISING,callback=name,bouncetime=1000)def flash(pin, ontime, offtime, count, first):
def incident (pin, dummyvar): # something has caused an alarm; needs a 2nd parameter
If I change all threaded_callback to True, all the outputs run on top of each other. With False, only 1 runs at a timeSo False is what I wantRPIO.add_interrupt_callback(P0, incident, edge='falling', threaded_callback=False, debounce_timeout_ms=3000) # ignore repeat doorbell presses within 3000mSec (3 sec) RPIO.add_interrupt_callback(P1, incident, edge='rising', threaded_callback=False, debounce_timeout_ms=3000) # magnetic contact. Switch normally grounds P1; when magnet removed, pull- up causes HIGH RPIO.add_interrupt_callback(P2, incident, edge='rising', threaded_callback=False, debounce_timeout_ms=15000) # PIR ignore repeats within 15 sec RPIO.add_interrupt_callback(P3, incident, edge='falling', threaded_callback=False, debounce_timeout_ms=30000) # sound detector ignore repats within 30 sec try:
except KeyboardInterrupt: RPIO.cleanup() Working (apart from threading) RPi.GPIO version: on = 1 IO.setmode(IO.BCM) # This version set to use BCM (Broadcom, the processor chip) GPIO numbers IO.setwarnings(False) # Turn off warning messages (occur when run program after 1st time) Set up pin numberingThese are tested and found to be correctright side, top to bottomP0 = 17 # BCM 17 left side, top to bottomCE1 = 7 # BCM 7 Set P0 to P3 as inputs with pull down resistors.P1 has PULL UP (magnetic contact)IO.setup(P0,IO.IN,pull_up_down=IO.PUD_UP) # Doorbell push set P4 to P7 as outputs to relays etcIO.setup(P4,IO.OUT) Set output P4 LOW (for Piezo sounder)set all other outputs HIGH ( = relay off)IO.output(P4,off) # Piezo sounder First define the actions to take for each triggerThen IO.add_event_detect(pin, IO.RISING, callback=name, bouncetime=1000)def flash(pin, ontime, offtime, count, first):
def incident (pin): # something has caused an alarm
IO.add_event_detect(P0,IO.RISING, callback=incident, bouncetime=3000) # ignore doorbell presses within 3000mSec (3 sec) IO.add_event_detect(P1,IO.RISING, callback=incident, bouncetime=3000) # magnetic contact. With temp switch, detects RELEASING button (but no matter) IO.add_event_detect(P2,IO.RISING, callback=incident, bouncetime=15000) # PIR ignore repeats within 15 sec IO.add_event_detect(P3,IO.FALLING, callback=incident, bouncetime=30000) # sound detector ignore repats within 30 sec try: except KeyboardInterrupt: IO.cleanup() |
I am getting an error with add_interrupt_callback.
I am using BOARD pin numbering with P0 set to 11 (ie BCM 18)
I can set up and read inputs (and setup and write outputs) OK. And my previous code with RPi.GPIO worked OK (except that I want to control the threading)
But when I try to set an interrupt with:
RPIO.add_interrupt_callback(P0, bellpush, edge='rising', threaded_callback=False, debounce_timeout_ms=3000)
I get a 'not valid pin on Raspberry Pi' error, as follows:
Traceback (most recent call last):
File "alarmv3.py", line 106, in
IO.add_interrupt_callback(P0, bellpush, edge='rising', threaded_callback=False, debounce_timeout_ms=3000)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/init.py", line 217, in add_interrupt_callback
threaded_callback, debounce_timeout_ms)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 139, in add_interrupt_callback
if RPIO.gpio_function(int(gpio_id)) == RPIO.IN:
RPIO.Exceptions.InvalidChannelException: The channel sent is invalid on a Raspberry Pi (not a valid pin)
I tried using values for RPi pins and BCM pins instead of the variable P0, but all give the same error. Am I doing something wrong, or is there a bug?
The text was updated successfully, but these errors were encountered: