peter pan
peter pan

Reputation: 27

2 PIR motion sensors to detect human presence

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

Answers (2)

jDo
jDo

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

sietschie
sietschie

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

Related Questions