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.

asked Mar 29, 2020 at 19:52
2
  • I updated the code - sorry for the errors. I wanted to remove irrelevant parts and deleted too much. Commented Mar 29, 2020 at 20:33
  • Try using the GPIOZERO library: gpiozero.readthedocs.io/en/stable/recipes.html#button Commented Mar 30, 2020 at 18:51

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.

WoJ
5432 gold badges6 silver badges15 bronze badges
answered Mar 29, 2020 at 20:06
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. Commented Mar 29, 2020 at 20:33
  • 1
    The code works properly on my Pi. Please add a clear photo of your Pi and connections. Commented Mar 29, 2020 at 21:14
  • Done - see updated question Commented 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.

answered Mar 29, 2020 at 20:43
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;
 }
}
goldilocks
60.4k17 gold badges117 silver badges236 bronze badges
answered Mar 30, 2020 at 18:49
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...

answered Mar 30, 2020 at 19:01
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

answered Mar 30, 2020 at 23:30
-1

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

answered Mar 30, 2020 at 17:12
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? Commented 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. Commented Mar 30, 2020 at 17:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.