-1

I have two buttons connected to pins 16 and 20. The one going to pin 20 works well, actually too well. Sometimes when I press it, it records the press two times. The other button which is connected to pin 16 sometimes works and sometimes doesn't. I checked the wiring and connections and that's not it. I have a script that helps me check functionality, and the button is literally just not getting registered every other press or so. Sometimes I can press it 5 times in a row and it will see it, and then I click and click and nothing for 3-4 seconds.

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def print_msg(x):
    print("Button {} was pushed!".format(x))


while True:
    input_01 = GPIO.input(16)
    input_02 = GPIO.input(20)
    input_03 = GPIO.input(21)

    if input_01 == False:
        print_msg(1)
        time.sleep(0.2)
    
    if input_02 == False:
        print_msg(2)
        time.sleep(0.2)
        
    if input_03 == False:
        print_msg(3)
        time.sleep(0.2)

enter image description here

9
  • If your objective is to write a program with unpredictable outcomes you have succeeded. What are you actually trying to do?
    – Milliways
    Commented Dec 8, 2022 at 11:19
  • Run piscope. That will show you what is happening.
    – joan
    Commented Dec 8, 2022 at 11:29
  • 1
    Maybe you need some kind of debouncing. You can do that with software (see for example docs.arduino.cc/built-in-examples/digital/Debounce) or, maybe, with a bit of hardware (just a capacitor and a resistor will help, see raspberrypi.stackexchange.com/questions/118349/…)
    – Rmano
    Commented Dec 8, 2022 at 19:37
  • 1
    The fundamental problem is that you are reading switch states every microsecond or so. Normal human reaction time is ~200mS so reading more frequently is futile. These switches are notorious for bouncing so will produce dozens of transactions each press and release. Trying to read multiple inputs in a tight loop (apart from being inefficient) is unreliable. If you want to use RPi.GPIO you need to explicitly program for these. Gpiozero can do this and only detect transitions.
    – Milliways
    Commented Dec 8, 2022 at 21:54
  • 1
    Recording multiple transitions when pressing the button might be the result of bouncing. Recording no button press might result from a faulty switch. You could add a LED and resistor to see if the switch actually connects the pins.
    – Bodo
    Commented Dec 9, 2022 at 11:19

1 Answer 1

0

Ah, the good old days of "It's a hardware problem ... No it's a software problem!" Often correct software logic bumps up against the reality of physical limitations and side effects. What to do ... what to do?

Pullup Resistors

Pullup resistors are to force the switch logic to a known state (True|False) but the reality is that it speeds-the-return to minimize the floating or Maybe state, it does not eliminate it.

Your sleep delays are tied to your detection and print. Nothing wrong with the logic in principle but you are re-reading the switch states very very fast and the state transitions are not instantaneous, there is a Maybe. What's more, reading does affect the output somewhat; hopefully an insignificant amount but repeated high speed pounding might make a difference. As a first step, pull your three sleeps out of the conditionals and put one after the last switch read to slow down your re-reads.

You are invoking the RaspberryPi programmable pullup resistors with pull_up_down=GPIO.PUD_UP. This is an internal pullup resistor of around 50K ohms. As a second step, it might be beneficial to put a physical 20K pullup on the breadboard between the switch and 3.3V power. This will reduce the maybe time a bit and eliminate questions as to the RPi internal pullup logic.

A third step might be to hold a past read (red) state. If the intent is discrete button presses, don't process a new read (reed) if the state is the same as previously read (red). Conversely, don't process a new state unless you read it twice (3?) in a row. If the intent is to handle press duration, require n (2?) new states to acknowledge end.

Good Luck and let us know how you make out!

Your Answer

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

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