Reputation: 542
I'm programming an alarm system from the ground up for my project in python3-6, using an raspberry pi 3 and some alarm components (PIR, REED, etc) To recieve alarms from the components I use the RPi.GPIO library which already has inbuilt Interrupt functionality. Here is the code I wrote so far: UPDATED 31.10.2017 15:44
#Library Imports
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
time_stamp = time.time()
def PIRcallback(channel):
print ('Alarm detected: ' + PIR.Name + '\nMotion!')
def REEDcallback(channel):
print ('Alarm detected: ' + REED.Name + '\nDoor!')
def VIBRcallback(channel):
print ('Alarm detected: ' + VIBR.Name + '\nWindow!')
class Alarm:
def __init__(self, IO, pin, Name, cb_var):
self.IO = IO
self.pin = pin
self.Name = Name
self.callback_func = cb_var
if (IO == 'input'):
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
elif (IO == 'output'):
GPIO.setup(pin, GPIO.OUT)
else:
print ('Error: No input/output declared')
self.addEvent('Up', 500)
def addEvent(self, UpDown, btime):
if (UpDown == 'Up'):
UpDown = GPIO.RISING
elif (UpDown == 'Down'):
UpDown = GPIO.FALLING
GPIO.add_event_detect(self.pin, UpDown, callback=self.cb, bouncetime=btime)
def getPin(self):
return self.pin
def cb(self):
global time_stamp
time_now = time.time()
print (time_now)
if (time_now - time_stamp) >= 0.4:
print (time_stamp)
time_stamp = time_now
self.callback_func()
#Testing Class Init
REED = Alarm('input', 37, "REED", REEDcallback)
PIR = Alarm('input', 36, "PIR", PIRcallback)
VIBR = Alarm('input', 38, "VIBR", VIBRcallback)
try:
while True:
time.sleep(0.5)
except KeyboardInterrupt:
print ("Terminating program...")
time.sleep(1)
finally:
GPIO.cleanup()
print ("Cleaned GPIO!")
Thanks for helping!
Upvotes: 2
Views: 1781
Reputation: 8605
In Python, functions are first-class variables themselves, and can be passed around like any other variable. In this case, you should simply pass the callback function directly to your Alarm
constructor, rather than the name:
class Alarm:
def __init__(self, IO, pin, callback):
self.IO = IO
self.pin = pin
self.callback_func = callback
if (IO == 'input'):
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
elif (IO == 'output'):
GPIO.setup(pin, GPIO.OUT)
else:
print ('Error: No input/output declared')
self.addEvent('Up', self.callback, 500)
[...]
def callback(self):
global time_stamp
time_now = time.time()
if (time_now - time_stamp) >= 0.3:
time_stamp = time_now
return self.callback_func() # <- Don't forget the parentheses here
#Testing Class Init
REED = Alarm('input', 37, REEDcallback)
PIR = Alarm('input', 36, PIRcallback)
VIBR = Alarm('input', 38, VIBRcallback)
# This bit is now done in the constructor:
# VIBR.addEvent('Up', VIBR.callback, 500)
# PIR.addEvent('Up', PIR.callback, 500)
# REED.addEvent('Up', REED.callback, 500)
Upvotes: 1