You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.
I initially added this to Issue #31, but on reflection it is actually a different problem so I now add it separately here.
I have been converting a program from using RPi.GPIO to use RPIO because I need to control the interrupt threading. 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?
I think it must be something simple with the add_interrupt_callbacks near the end, but I can't work out what.
My full code using RPIO (which triggers interrupts repeatedly) is below, followed by the equivalent version for RPi.GPIO (which works except for being unable to control threading)
What might be wrong?
PS: I know I have a logic flaw with the "don't respond to sounds if the piezo is sounding" handling. I will deal with that later.
Non-working RPIO version:
'''
import RPIO as RPIO
import time
on = 1
off = 0
sounder = off
This is not needed for RPIO # RPIO.setmode(RPIO.BCM) # This version set to use BCM (Broadcom, the processor chip) GPIO$
Therefore this program will work only with Rev 2 Raspberry Pis
RPIO.setwarnings(False) # Turn off warning messages (occur when run program after 1st time)
Set P0 to P3 as inputs with pull up resistors on P0 and P1
RPIO.setup(P0, RPIO.IN, pull_up_down=RPIO.PUD_UP) # Doorbell push; pressing will ground this pin
RPIO.setup(P1, RPIO.IN, pull_up_down=RPIO.PUD_UP) # Magnetic contact; normally grounded; removing magnet lets it go high
RPIO.setup(P2, RPIO.IN) # PIR; goes ON with movement detected
RPIO.setup(P3, RPIO.IN) # Sound detector; goes OFF when sound detected
RPIO.output(P4, off) # Piezo sounder
RPIO.output(P5, on) # For relay, set ON as this leaves relay quiescent to save power
RPIO.output(P6, on) # Relay
RPIO.output(P7, on) # Relay
time.sleep(1) # pause to allow inputs to settle before enabling interrupts
P1 is magnetic contact. Pulled UP. Normally pin is connected to GROUND
When magnet removed, switch opens, pull up causes HIGH
P2 is PIR. Requires power of +5v, but output is 3v (RPi 3v3 compatible)
Output goes ON when movement detected
Trimmers adjust (a) sensitivity and (b) ON duration after detection
P3 Sound Detector. Requires power of 3-20v; we are using 3.3v.
Digital Output goes OFF and LED lights when sound detected
Turn resistor ANTICLOCKWISE for greater sensitivity
Because there are multiple triggers, cannot use "Wait for edge"
Define "Events" for each trigger and generate a "Callback" whenever that event occurs
First define the actions to take for each trigger
Then IO.add_event_detect(pin,IO.RISING,callback=name,bouncetime=1000)
def flash(pin, ontime, offtime, count, first):
first = state to send first. Set it to on or off.
global on
global off
second = 1 - first # second state is opposite to the first one
for i in range (1, count+1): # needs +1 so it loops the correct number of times ?why
RPIO.output (pin, first)
time.sleep(ontime)
RPIO.output(pin, second)
if i <> count: # this is to avoid a wait at the end
time.sleep(offtime)
def incident (pin, dummyvar): # something has caused an alarm; needs a 2nd parameter
global on
global off
global sounder
print(' ')
print('Incident detected - now decode what it was. Pin '+str(pin)+'; Value '+str(dummyvar))
if pin == P0: # doorbell
print('Doorbell pushed - sound piezo and flash light')
sounder = on # set flag to ignore sound detection
RPIO.output(P4, on) # piezo on
flash(P7, 0.5, 0.5, 3, off) # pulse relay 3x 0.5 sec
RPIO.output(P4, off) # Piezo off
sounder = off
print('Ended doorbell actions')
elif pin == P3: # Sound detected
if sounder == off: # only react to sound detection if piezo is not sounding !!
print ('Sound detected - turn light on whilst playing 4 bleeps')
RPIO.output(P7,off) # turn light on
sounder = on # set flag to ignore sound detection
flash(P4, 1, 1, 4, on) # sound piezo 4x for 1 second
sounder = off
RPIO.output(P7,on) # turn light back off
print('Ended sound detected actions')
else: # No actions if piezo is sounding
print('Ignoring sound detected as Piezo is sounding')
try:
print('Monitoring started ...')
print('Press CTRL-C to exit')
RPIO.wait_for_interrupts(threaded=False) # False make the main prog stop here - then the following loop is not needed
while True: # just wait forever ...
time.sleep(10000)
IO.output(P4,off) # Piezo sounder
IO.output(P5,on) # For relay, set ON as this leaves relay quiescent to save power
IO.output(P6,on) # Relay
IO.output(P7,on) # Relay
First define the actions to take for each trigger
Then IO.add_event_detect(pin, IO.RISING, callback=name, bouncetime=1000)
def flash(pin, ontime, offtime, count, first):
first = state to send first. Set it to on or off.
global on
global off
second = 1 - first # second state is opposite to the first one
for i in range (1, count+1): # needs +1 so it loops the correct number of times ?why
IO.output (pin, first)
time.sleep(ontime)
IO.output(pin, second)
if i <> count: # this is to avoid a wait at the end
time.sleep(offtime)
def incident (pin): # something has caused an alarm
global on
global off
global sounder
print(' ')
print('Incident detected - now decode what it was. Pin '+str(pin))
if pin == P0: # doorbell
print('Doorbell pushed - sound piezo and flash light')
IO.output(P4, on) # piezo on
sounder = on # set flag to ignore sound detection
flash(P7, 0.5, 0.5, 3, off) # pulse relay 3x 0.5 sec
IO.output(P4, off) # Piezo off
sounder = off
print('Ended doorbell actions')
elif pin == P3: # Sound detected
if sounder == off: # only raect to sound detection if piezo is not sounding !!
print ('Sound detected - turn light on whilst playing 4 bleeps')
IO.output(P7,off) # turn light on
sounder = on # set flag to ignore sound detection
flash(P4, 1, 1, 4, on) # sound piezo 4x for 1 second
sounder = off
IO.output(P7,on) # turn light back off
print('Ended sound detected actions')
else: # No actions if piezo is sounding
print('Ignoring sound detected as Piezo is sounding')
I initially added this to Issue #31, but on reflection it is actually a different problem so I now add it separately here.
I have been converting a program from using RPi.GPIO to use RPIO because I need to control the interrupt threading. 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?
I think it must be something simple with the add_interrupt_callbacks near the end, but I can't work out what.
My full code using RPIO (which triggers interrupts repeatedly) is below, followed by the equivalent version for RPi.GPIO (which works except for being unable to control threading)
What might be wrong?
PS: I know I have a logic flaw with the "don't respond to sounds if the piezo is sounding" handling. I will deal with that later.
Non-working RPIO version:
'''
import RPIO as RPIO
import time
on = 1
off = 0
sounder = off
This is not needed for RPIO # RPIO.setmode(RPIO.BCM) # This version set to use BCM (Broadcom, the processor chip) GPIO$
Therefore this program will work only with Rev 2 Raspberry Pis
RPIO.setwarnings(False) # Turn off warning messages (occur when run program after 1st time)
Set up pin numbering
These are tested and found to be correct
right side, top to bottom
P0 = 17 # BCM 17
P1 = 18 # BCM 18
P2 = 27 # BCM 27 (21 on Revision 1)
P3 = 22 # BCM 22
P4 = 23 # BCM 23
P5 = 24 # BCM 24
P6 = 25 # BCM 25
P7 = 4 # BCM 4
left side, top to bottom
CE1 = 7 # BCM 7
CE0 = 8 # BCM 8
SCLK = 11 # BCM 11
MISO = 9 # BCM 9
MOSI = 10 # BCM 10
RXD = 15 # BCM 15
TXD = 14 # BCM 14
SCL = 3 # BCM 3 (would be 1 on Revision 1)
SDA = 2 # BCM 2 (would be 0 on revision 1)
Set P0 to P3 as inputs with pull up resistors on P0 and P1
RPIO.setup(P0, RPIO.IN, pull_up_down=RPIO.PUD_UP) # Doorbell push; pressing will ground this pin
RPIO.setup(P1, RPIO.IN, pull_up_down=RPIO.PUD_UP) # Magnetic contact; normally grounded; removing magnet lets it go high
RPIO.setup(P2, RPIO.IN) # PIR; goes ON with movement detected
RPIO.setup(P3, RPIO.IN) # Sound detector; goes OFF when sound detected
set P4 to P7 as outputs to relays etc
RPIO.setup(P4, RPIO.OUT)
RPIO.setup(P5, RPIO.OUT)
RPIO.setup(P6, RPIO.OUT)
RPIO.setup(P7, RPIO.OUT)
Set output P4 LOW (for Piezo sounder)
set all other outputs HIGH ( = relay off)
RPIO.output(P4, off) # Piezo sounder
RPIO.output(P5, on) # For relay, set ON as this leaves relay quiescent to save power
RPIO.output(P6, on) # Relay
RPIO.output(P7, on) # Relay
time.sleep(1) # pause to allow inputs to settle before enabling interrupts
P1 is magnetic contact. Pulled UP. Normally pin is connected to GROUND
When magnet removed, switch opens, pull up causes HIGH
P2 is PIR. Requires power of +5v, but output is 3v (RPi 3v3 compatible)
Output goes ON when movement detected
Trimmers adjust (a) sensitivity and (b) ON duration after detection
P3 Sound Detector. Requires power of 3-20v; we are using 3.3v.
Digital Output goes OFF and LED lights when sound detected
Turn resistor ANTICLOCKWISE for greater sensitivity
Because there are multiple triggers, cannot use "Wait for edge"
Define "Events" for each trigger and generate a "Callback" whenever that event occurs
First define the actions to take for each trigger
Then IO.add_event_detect(pin,IO.RISING,callback=name,bouncetime=1000)
def flash(pin, ontime, offtime, count, first):
first = state to send first. Set it to on or off.
global on
global off
second = 1 - first # second state is opposite to the first one
for i in range (1, count+1): # needs +1 so it loops the correct number of times ?why
RPIO.output (pin, first)
time.sleep(ontime)
RPIO.output(pin, second)
if i <> count: # this is to avoid a wait at the end
time.sleep(offtime)
def incident (pin, dummyvar): # something has caused an alarm; needs a 2nd parameter
global on
global off
global sounder
print(' ')
print('Incident detected - now decode what it was. Pin '+str(pin)+'; Value '+str(dummyvar))
if pin == P0: # doorbell
print('Doorbell pushed - sound piezo and flash light')
sounder = on # set flag to ignore sound detection
RPIO.output(P4, on) # piezo on
flash(P7, 0.5, 0.5, 3, off) # pulse relay 3x 0.5 sec
RPIO.output(P4, off) # Piezo off
sounder = off
print('Ended doorbell actions')
elif pin == P1: # Magnetic contact, Magnet removed
print('Magnet removed - flash light')
flash(P7, 1, 0.5, 5, off) # pulse relay
print('Ended magnet removed actions')
elif pin == P2: # PIR detected motion
print('Motion detected - flicker light')
flash(P7, 2, 0.2, 3, off) # flicker relay
print('Ended Motion detected actions')
elif pin == P3: # Sound detected
if sounder == off: # only react to sound detection if piezo is not sounding !!
print ('Sound detected - turn light on whilst playing 4 bleeps')
RPIO.output(P7,off) # turn light on
sounder = on # set flag to ignore sound detection
flash(P4, 1, 1, 4, on) # sound piezo 4x for 1 second
sounder = off
RPIO.output(P7,on) # turn light back off
print('Ended sound detected actions')
else: # unknown trigger
print ('Unidentified trigger')
If I change all threaded_callback to True, all the outputs run on top of each other. With False, only 1 runs at a time
So False is what I want
RPIO.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:
print('Monitoring started ...')
print('Press CTRL-C to exit')
RPIO.wait_for_interrupts(threaded=False) # False make the main prog stop here - then the following loop is not needed
while True: # just wait forever ...
time.sleep(10000)
RPIO.cleanup()
except KeyboardInterrupt:
print ('Ending monitoring')
RPIO.cleanup() # Cleanup on CTRL-C
RPIO.cleanup()
'''
Working (apart from threading) RPi.GPIO version:
'''
import RPi.GPIO as IO
import time
on = 1
off = 0
sounder = off
IO.setmode(IO.BCM) # This version set to use BCM (Broadcom, the processor chip) GPIO numbers
Therefore this program will work only with Rev 2 Raspberry Pis
IO.setwarnings(False) # Turn off warning messages (occur when run program after 1st time)
Set up pin numbering
These are tested and found to be correct
right side, top to bottom
P0 = 17 # BCM 17
P1 = 18 # BCM 18
P2 = 27 # BCM 27 (21 on Revision 1)
P3 = 22 # BCM 22
P4 = 23 # BCM 23
P5 = 24 # BCM 24
P6 = 25 # BCM 25
P7 = 4 # BCM 4
left side, top to bottom
CE1 = 7 # BCM 7
CE0 = 8 # BCM 8
SCLK = 11 # BCM 11
MISO = 9 # BCM 9
MOSI = 10 # BCM 10
RXD = 15 # BCM 15
TXD = 14 # BCM 14
SCL = 3 # BCM 3 (would be 1 on Revision 1)
SDA = 2 # BCM 2 (would be 0 on revision 1)
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
IO.setup(P1,IO.IN,pull_up_down=IO.PUD_UP) # Magnetic contact
IO.setup(P2,IO.IN) # PIR
IO.setup(P3,IO.IN) # Sound detector
set P4 to P7 as outputs to relays etc
IO.setup(P4,IO.OUT)
IO.setup(P5,IO.OUT)
IO.setup(P6,IO.OUT)
IO.setup(P7,IO.OUT)
Set output P4 LOW (for Piezo sounder)
set all other outputs HIGH ( = relay off)
IO.output(P4,off) # Piezo sounder
IO.output(P5,on) # For relay, set ON as this leaves relay quiescent to save power
IO.output(P6,on) # Relay
IO.output(P7,on) # Relay
First define the actions to take for each trigger
Then IO.add_event_detect(pin, IO.RISING, callback=name, bouncetime=1000)
def flash(pin, ontime, offtime, count, first):
first = state to send first. Set it to on or off.
global on
global off
second = 1 - first # second state is opposite to the first one
for i in range (1, count+1): # needs +1 so it loops the correct number of times ?why
IO.output (pin, first)
time.sleep(ontime)
IO.output(pin, second)
if i <> count: # this is to avoid a wait at the end
time.sleep(offtime)
def incident (pin): # something has caused an alarm
global on
global off
global sounder
print(' ')
print('Incident detected - now decode what it was. Pin '+str(pin))
if pin == P0: # doorbell
print('Doorbell pushed - sound piezo and flash light')
IO.output(P4, on) # piezo on
sounder = on # set flag to ignore sound detection
flash(P7, 0.5, 0.5, 3, off) # pulse relay 3x 0.5 sec
IO.output(P4, off) # Piezo off
sounder = off
print('Ended doorbell actions')
elif pin == P1: # Magnetic contact, Magnet removed
print('Magnet removed - flash light')
flash(P7, 1, 0.5, 5, off) # pulse relay
print('Ended magnet removed actions')
elif pin == P2: # PIR detected motion
print('Motion detected - flicker light')
flash(P7, 2, 0.2, 3, off) # flicker relay
print('Ended Motion detected actions')
elif pin == P3: # Sound detected
if sounder == off: # only raect to sound detection if piezo is not sounding !!
print ('Sound detected - turn light on whilst playing 4 bleeps')
IO.output(P7,off) # turn light on
sounder = on # set flag to ignore sound detection
flash(P4, 1, 1, 4, on) # sound piezo 4x for 1 second
sounder = off
IO.output(P7,on) # turn light back off
print('Ended sound detected actions')
else: # unknown trigger
print ('Unidentified trigger')
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:
print('Monitoring started ...')
print('Press CTRL-C to exit')
while True: # just wait forever ...
time.sleep(10000)
except KeyboardInterrupt:
print ('Ending monitoring')
IO.cleanup() # Cleanup on CTRL-C
IO.cleanup()
The text was updated successfully, but these errors were encountered: