3

So, I'm trying to set up my raspberry pi to take input from a PIR sensor in order to automatically turn on a monitor when it detects motion. If no motion has been detected in 60 seconds, the monitor is turned off until motion is again detected. I also have it set so that between 7-10am and 5-8pm the monitor will just stay on.

In testing though, I've noticed a peculiar thing happening: Every x seconds or y seconds (the number of seconds seems to vary whenever I restart the pi or change sensors, but it always occurs at two different amounts), I detect a false positive (despite there being no motion at all). Now, the PIR I'm using (HC-SR501) has configurable sensitivity and time delay. I've tried changing both and there seems to be no effect.

I've tried four different sensors now, and all four give this false positive very consistently.

Below you can see my (python) code. If anyone can help me out with why this may be happening and how to fix it, I'd appreciate it.

#!/usr/bin/env python

import sys
import time
import RPi.GPIO as io
import subprocess

io.setmode(io.BCM)
SHUTOFF_DELAY = 60    # seconds
PIR_PIN = 25          # 22 on the board

def main():
    io.setup(PIR_PIN, io.IN, pull_up_down=io.PUD_DOWN)
    turned_off = False
    previous_state = False
    last_motion_time = time.time()

    while True:
        currentHour = time.localtime().tm_hour

        # if it's 7-10am or 5-8pm, turn the screen on and poll less often
        if ((7 <= currentHour < 10) or (17 <= currentHour < 20)):
            print 'The current hour is {}, screen should remain on'.format(currentHour)
            sys.stdout.flush()
            if turned_off:
                turned_off = False
                turn_on()
            time.sleep(60)

        # if it's not during one of our 'busy hours', look for motion
        else:
            if io.input(PIR_PIN) and previous_state == False:
                print "It's been {} seconds since the last motion\n".format(time.time()-last_motion_time)
                sys.stdout.flush()
                last_motion_time = time.time()
                previous_state = True
                if turned_off:
                    turned_off = False
                    turn_on()

            elif previous_state == true:
                if not turned_off and time.time() > (last_motion_time + SHUTOFF_DELAY):
                    turned_off = True
                    turn_off()
                previous_state = False

            time.sleep(.1)

def turn_on():
    subprocess.call("sh /home/pi/MotionSensor/monitor_on.sh", shell = True)

def turn_off():
    subprocess.call("sh /home/pi/MotionSensor/monitor_off.sh", shell = True)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        io.cleanup()
  • 1
    Could you show a picture of your wiring? – Andy Lamb Apr 17 '16 at 6:24
  • @AndyLamb An actual picture, or a diagram? It's only three wires, one from pin 4 (5v) to the +power pin of the PIR, one from pin 20 (GND) to the GND pin of the PIR, and one from pin 22 (GPIO 25) to the High/Low Output pin of the PIR. I've also tried using GPIO 14, 23, and 24 (pins 8, 16, and 18 respectively) for the input, and pins 14 and 20 for the ground. – Doc Apr 17 '16 at 6:43
  • What environment is this set in? – Bex Apr 17 '16 at 9:44
  • @Bex Running Raspbian Jessie on a Raspberry Pi 3 – Doc Apr 17 '16 at 18:15
  • No, sorry, I mean physical environment. – Bex Apr 18 '16 at 5:52
1

I would say that there are three things that could have gone wrong:

The environment

The IR sensor can "see" things that you can't. It can detect movement that is invisible to the human eye. If there is anything rotating that casts a reflection of heat into the sensor, the sensor will probably interpret that as movement. Check the environment and check it again. If possible, bring up a representation of what the IR sensor "sees" onto a screen. If your sensor can't do that, consider using a Pi NoIR camera. If you like, you can actually implement the sensor using the camera.

The wiring

It would be valuable to know if what the settings of the PIR sensor are, how the jumper is set, and how it is wired to the pi. Whithout knowing this I can only speculate that if the x and y you mention in the post are both in the range of 5s to 300s, and the jumper is set to H-mode, the "same" movement is causing the retriggering you are referring to.

The code

First of all, it looks to me like if you are polling the pin, rather than reacting to an event. This means that you will miss things that don't occur in the exact moment you are checking the pin. You want to have a look at the edge detection methods and procedures in https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/ Arguably, the most elegant way to do this would probably be to use the add_event_detect callback framework, but that might require some synchronization of your other variables.

  • I've actually updated the code (several times) since I posted the question, trying to track down the issue. Currently, I'm using the add_event_detect callback instead of polling. I've also tried using both H and L mode on the PIR sensor, and adjusted the time delay to see if any of those settings would prevent the issue (they don't). – Doc Apr 19 '16 at 14:13
3

This may sound really stupid, but I too was having the same issue, and it turned out that I had my ground and voltage wires reversed. As soon as I switched those wires, it worked! Double check the wiring.

  • Not stupid at all. I think some of the cheap knockoffs had their pinouts reversed from the originals. – deltaray Dec 9 '18 at 21:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.