0

When running the following simple code, I would expect the [while True] to return an endless stream of 1 and 0, relating to the pir motion sensor state. However, once triggered, I only get 1s, even once motion has ended. If I do the opposite (ie, put the loop into a when_no_motion), I get a string of 0s... It seems that the pir.value is not updating.

Any clues?

Thanks in advance!

from signal import pause
from gpiozero import MotionSensor

pir = MotionSensor(4, queue_len=1)

def do_motion_detected():
  while True:
    print(pir.value)

pir.when_motion = do_motion_detected

pause()

It might also be worth noting that, when I try this with GPIOZero Button instead of MotionSensor, it works fine, giving me a stream of 1s and 0s, correlating to the Button value...

from signal import pause
from gpiozero import Button

clicker = Button(4)

def do_press_detected():
  while True:
    print(clicker.value)

clicker.when_pressed = do_press_detected

pause()
MofX
  • 1,569
  • 12
  • 22

1 Answers1

0

I never worked with this library so take it with reserve

1) From reading the DOCs, you should use 'motion_detected' instead of 'value' as 'value' is also connected to 'queue_len' and essentially it does not return you bool motion/non-motion but average of all values in the queue.

(https://gpiozero.readthedocs.io/en/stable/api_input.html#gpiozero.MotionSensor)

2) Your problem may not be connected with programming at all but it can be wrong wiring. Maybe you didnt use pull-up/down resistor and as a result, you have only noise on your wire resulting in eternal 0 value. This is called 'floating'. In other words, your program works, but signal on your pin is floating, so you are reading noise.

(https://grantwinney.com/using-pullup-and-pulldown-resistors-on-the-raspberry-pi/)

3) I suggest you use standard GPIO library and get closer to the metal. Once you become familiar with it, you can use higher level frameworks for controlling I/O.

Extra Notes:

Dont use:

while True:
    print('something')

This will only steal CPU from your raspberry pi. What you should do instead is check sampling frequency -(the one you need or the one your library provides) and put sleep at the end of the loop

import time
sampling_frequency = 50
while True:
    print('read from sensor')
    time.sleep( 1./(sampling_frequency*2))

#I multiply sampling_frequency by 2 due to Shannon frequency theorem

Extra Notes 2:

function when_motion is callback/event handler. That means if there is a motion, some function which you define is triggered. What you have doesnt really make sense.

Something like this makes more sense

...
def initialize_locking_doors():
    print('Motion was detected. Locking doors')
    #lock_doors....
    #leave the function

pir.when_motion = initialize_locking_doors
...
Martin
  • 3,333
  • 2
  • 18
  • 39
  • This is a great answer! Thank you for taking the time, especially considering this isn't a library you have used! ☺ – Vince_email Aug 07 '19 at 07:06