3

I set up a simple curcuit and tried a pullup and a pulldown scenario, but both lead to a lot of "false positives". Currently I ended up with the circuit you can see in the image. I have no button attached, but jumpingwires i connect and disconnect to a breadboard. Even when I don't connect it there is a level increase.

enter image description here

This is the code I used for the setting:

import RPi.GPIO as GPIO
import time
AmountMotionsDetected = 0
PIRinPin = 17

def setup_gpio():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(PIRinPin, GPIO.IN, GPIO.PUD_DOWN) #  Set pin to be an input pin and set initial value to be pulled low (off)
    GPIO.add_event_detect(PIRinPin, GPIO.RISING, callback = MotionDetectedCallback, bouncetime = 300)


def MotionDetectedCallback(channel):

    global AmountMotionsDetected
    print ("We have {} motions detected ".format(str(AmountMotionsDetected)))
    AmountMotionsDetected = AmountMotionsDetected + 1

def endprogram():
    GPIO.cleanup()


if __name__ == '__main__':

    setup_gpio()

    try:
        while True:
            button_state = GPIO.input(PIRinPin)
            if button_state == GPIO.HIGH:
                print ("HIGH")
            else:
                print ("LOW")
            time.sleep(1)

    except KeyboardInterrupt:
        print ('keyboard interrupt detected')
        endprogram()

Here is a photo of the setup (I use the orange jumoing wire to simulate the switch)

enter image description here

Update 2: I found a hint why there might be a problem. Therefor I had to modify the script a little bit as you can see above. When I now run the script and connect/disconnect the jumping wire periodically, I see that sometimes (but not always) there is false "rising" detection when I disconnect the wire. This seems to be a common issue since 2014?

If that's true, that function would be useless.

2

6 Answers 6

4

There are numerous errors in the script.

  1. time module is not imported
  2. PIRinPin is not defined.
  3. AmountMotionsDetected is not defined, set as a global, or incremented.

Once those errors are corrected the script works properly.

Therefore you have connected to the wrong GPIO or you are using very long wires.

3
  • Thanks for pointing that out. I updated the code - sorry for the errors. I wanted to remove irrelevant parts and deleted too much. It still has the issue. The problem is that "Motion detected" is printed on the console even if I do not connect the jumping wires.
    – Wolfgang
    Mar 29, 2020 at 20:33
  • 1
    The code works properly on my Pi. Please add a clear photo of your Pi and connections.
    – joan
    Mar 29, 2020 at 21:14
  • Done - see updated question
    – Wolfgang
    Mar 30, 2020 at 17:31
3

I would start by debugging this on the command line using gpio. gpio readall can tell you if the pin gets configured correctly, and whether it changes the state. See if the pin changes state when you pull it to 3.3V / GND via a resistor. When that works, get back to your code and see how it behaves. Once it works, switch to an internal pulldown.

2

Your problem seems to be related to "electrical bounce" which is caused by electrons arching from one wire to another as your contact wires (or switch contacts) come close together. Basically, your computer reads multiple "contacts" before your subroutine has a chance to finish executing.

The way to get around this is by stopping the loop that waits for a positive contact before the subroutine starts and the restarting that same loop once all of your commands have been executed.

I code in a different language for different hardware but the concept is the same. this is only to show the concept. In pseudo code it would look like something like this:

_global waitForButtonContact = true;
While(waitForButtonContact){
   buttonIsPressed = gpioCheckButton();
   If(buttonIsPressed){
       doSomething();
   }
}

Function doSomething (){
     //Do stuff here
     waitForButtonContact = true;
     Return;
}

Function gpioCheckButton(){
    if(//weDetectedTheButtonWasPressed){
       waitForButtonContact = false;
       Return true;
    }
Else{
      Return false;
   }

}

0

@Marko was pointing me in the right direction. I updated my question and added some links to my research about this issue and came up with the following workaround:

if not GPIO.input(PIRinPin) == GPIO.HIGH:
    return

The complete code looks as follows:

import RPi.GPIO as GPIO
import time
AmountMotionsDetected = 0
PIRinPin = 17

def setup_gpio():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(PIRinPin, GPIO.IN, GPIO.PUD_DOWN) #  Set pin to be an input pin and set initial value to be pulled low (off)
    GPIO.add_event_detect(PIRinPin, GPIO.RISING, callback = MotionDetectedCallback, bouncetime = 300)


def MotionDetectedCallback(channel):
    global AmountMotionsDetected
    if not GPIO.input(PIRinPin) == GPIO.HIGH:
        return

    AmountMotionsDetected = AmountMotionsDetected + 1
    print ("We have {} motions detected ".format(str(AmountMotionsDetected)))

def endprogram():
    GPIO.cleanup()


if __name__ == '__main__':

    setup_gpio()

    try:
        while True:
            time.sleep(1)

    except KeyboardInterrupt:
        print ('keyboard interrupt detected')
        endprogram()

Maybe someone comes across this issue in future, and can give me a correct solution - for me this basically means that the interrupt processing is very buggy...

0

Been in the electronics 30 years, never saw a so poorly designed input circuit. First thing first, never bring vcc (regardless it is 3.3 or 5v) to a input jumper ! Your jumper should be between ground and input. With a pullup, and use a 10khoms pullup not 220R !

Also debounce input reading algorithm goes like this (low level) 1. Read state 2. Compare previous state 3. No change ? Reset counter to whatever 4. Change ? Memorise new state, decrement counter 5. Only when counter reach 0 (reading it n times SAME state) then proceed with piece of code

-1

Your pull up connection is wrong in the image you can see the correct connectionenter image description here

2
  • 1
    Why do you use 5V instead of 3V? Why is the resistor not placed in front of the switch? What does ENTRADA 5V mean? Ist it +5V -> GPIO?
    – Wolfgang
    Mar 30, 2020 at 17:27
  • 2
    If you look at the code carefully, you will see the OP is using the internal pull-down. Your schematic is a 100% Pi killer. Mar 30, 2020 at 17:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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