Reputation: 27
I'm having trouble programming the logic of 2 PIR sensors to print a message in console whenever a user place both hands on the PIR sensors.I have managed to successfully attach the PIR sensors to the raspberry pi using GPIO,GND and 5v port. The code that I currently have does print out a message in console whenever someone waves there hand across one but i'm having difficulty modifying the code to print an error message out when someone waves their hand on both the PIR sensors.
https://i.sstatic.net/3kURK.png
We can read input from the sensor using GP4 and GP17
import RPi.GPIO as GPIO
import time
sensor = 4
sensor2 = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(sensor, GPIO.IN, GPIO.PUD_DOWN)
previous_state = False
current_state = False
while True:
time.sleep(0.1)
previous_state = current_state
current_state = GPIO.input(sensor)
if current_state(TRUE) != previous_state(FALSE):
new_state = "HIGH" if current_state else "LOW"
print("GPIO pin %s is %s" % (sensor, new_state))
The program is pretty simple. The Raspberry Pi GPIO pins to allow us to use pin 4 as an input; it can then detect when the PIR module sends power. The pin continually check for any changes, uses a while True loop for this. This is an infinite loop so the program will run continuously unless we stop it manually with Ctrl + C.
Then use two Boolean variables (True or False) for the previous and current states of the pin, the previous state being what the current state was the preceding time around the loop.
Inside the loop we compare the previous state to the current state to detect when they're different. We don't want to keep displaying a message if there has been no change.
Upvotes: 0
Views: 1446
Reputation: 4010
I haven't checked the code for syntax errors and don't have access to a Pi at the moment, but it's an example of what I was referring to in this comment:
"Use RPi.GPIO's add_event_detect interrupt driven callbacks instead. Then you can eliminate the infinite loop entirely and let the script do other stuff while still reacting to the sensors. You can use the time difference between rising edges to define what "simultaneously" means to you (a max difference of 1 second between sensor 1 and sensor 2 being triggered, for instance)"
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, GPIO.PUD_DOWN)
GPIO.setup(4, GPIO.IN, GPIO.PUD_DOWN)
pir1_last = pir2_last = time.time()
def callback_func(pin):
global pir1_last
global pir2_last
t_now = time.time()
if GPIO.input(17):
pir1_last = t_now
if GPIO.input(4):
pir2_last = t_now
t_diff = abs(pir1_last - pir2_last)
if t_diff < 0.5:
print "it's been less than 0.5 seconds since both PIRs were activated"
# change GPIO.RISING to GPIO.FALIING if your PIRs are active low
GPIO.add_event_detect(17, GPIO.RISING, callback=callback_func)
GPIO.add_event_detect(4, GPIO.RISING, callback=callback_func)
def main():
while True:
print "Not blocking! You're free to do other stuff here"
time.sleep(10)
I'm not completely sure that it's actually the pin number that's passed to the callback (that's why I'm also doing a reading of the pin states in the callback to make sure). If you add print(pin)
to the callback function and it prints a pin number, there's no reason to do a reading and you can replace the callback with this:
def callback_func(pin):
global pir1_last
global pir2_last
t_now = time.time()
if pin == 17:
pir1_last = t_now
if pin == 4:
pir2_last = t_now
t_diff = abs(pir1_last - pir2_last)
if t_diff < 0.5:
print "it's been less than 0.5 seconds since both PIRs were activated"
Upvotes: 0
Reputation: 7553
You definde a second set of state variables for the second sensor for example
previous_state_sensor2 = False
current_state_sensor2 = False
and set them exactly like for the first sensor. Then you add a if condition like this:
if (current_state(TRUE) and current_state_sensor2(TRUE)) and
(previous_state(FALSE) or previous_state_sensor2(FALSE)):
print "both sensors detected something"
(I am not sure about the exact syntax since I am not familiar with this way of evaluating booleans: current_state(TRUE)
. But the idea should be the same.)
Upvotes: 0