1

I am using almost all the GPIO pins on a project so I had to be resourceful when adressing the pins for the buttons.

But I just can’t get it to work. I don't know if something is wrong with the code or the wiring, but the buttons don’t work like I want them to. Does something like this even work or am I missing something?

import RPi.GPIO as GPIO
import board
from signal import pause

def my_callback(l, r):
    if (l == 14 and not(GPIO.input(r))):
        print("Button 1")
    elif (l == 14 and GPIO.input(r)):
        print("Button 2")
    else:
        print("Button 3")
    
try:
    GPIO.setup((14,15), GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.add_event_detect(14, GPIO.FALLING, callback=lambda x : my_callback(14, 15), bouncetime=200)
    GPIO.add_event_detect(15, GPIO.FALLING, callback=lambda x : my_callback(15, 14), bouncetime=200)
    pause()
except KeyboardInterrupt:
    GPIO.cleanup()

Wiring: enter image description here

6
  • You have connected the buttons in parallel so there is no chance it will work. Maybe if you isolated them with diodes you could get it to work. This is an EE question not Pi specific.
    – Milliways
    Commented Apr 11, 2021 at 22:10
  • @Milliways The buttons work though. I tried it on a simpler code. When I pressed Button 2 I'd get a signal for pin 14 and after that for pin 15. Or what do you mean? Commented Apr 11, 2021 at 22:20
  • 1
    The code only confuses the issue. If you press ANY button BOTH inputs will be activated.
    – Milliways
    Commented Apr 11, 2021 at 22:31
  • @Milliways Yeah I see what the problem is... So is there a easy solution to fix this or should I just use 3 pins? Thanks though for helping I have already wasted so much time on this... Commented Apr 11, 2021 at 22:45
  • As I stated you could use diodes to isolate the buttons, but the code still has problems (specifically reading buttons in callbacks is unreliable).
    – Milliways
    Commented Apr 11, 2021 at 23:54

2 Answers 2

2

You could try something like the following - which will at least isolate buttons.

Pushing the centre button will activate both inputs - the others a single input. Strictly no diode is required on the isolated buttons.

schematic

simulate this circuit – Schematic created using CircuitLab

4
  • You said, that there is no need for diodes on the single inputs but your diagram shows 4 diodes. Would that mean, that I only need 2 diodes for 3 buttons or should I do it like your diagram? Commented Apr 12, 2021 at 9:07
  • @MysteriousChallenger I started off with a conventional diode isolation technique (which isolates each button), but after posting realised the other diodes were superfluous, as there is no contention. Simple answer no - only the 2 diodes on the shared pin are necessary. (You will still need to consider your software - it will work if the buttons are held for long enough.)
    – Milliways
    Commented Apr 12, 2021 at 9:34
  • Alright, got it. Thank you very much for the help! I greatly appreciate it! Commented Apr 12, 2021 at 9:40
  • Would a 1N4148 diode be enough for the I/O pins of the PI? Commented Apr 12, 2021 at 16:48
3

Just for reference, there are two well-known approaches for addressing multiple keys with fewer pins: voltage ladder if you have analog pins and key matrix if you have digital pins. The Pi itself has no analog pins, but if you use an ADC, it's possible to use some of its channels for buttons.

Any non-standard wiring schemes are either suboptimal compared to the standard approaches, or only work for specific cases, and since they don't have proper names it will be next to impossible to find code samples for them if you can't write your own code.

For 3 buttons I'd just use 3 pins (plus ground), with trivial logic for reading the state of the buttons, and the possibility to detect simultaneously pressed buttons. If you really want to get creative, you could do with only two pins and no ground:

schematic

simulate this circuit – Schematic created using CircuitLab

Pushing SW1 will copy the signal of any level from GPIO1 to GPIO2 and vice versa. Pushing SW2 will copy the LOW level from GPIO1 to GPIO2. Pushing SW3 will copy the LOW level from GPIO2 to GPIO1.

Assuming you have pullups enabled on both pins, reading the buttons is done by driving GPIO1 LOW and reading GPIO2, and then driving GPIO2 low and reading GPIO1:

  • if you read LOW both times, it's SW1
  • if you read LOW then HIGH, it's SW2
  • if you read HIGH then LOW, it's SW3
  • if you read HIGH both times, no buttons are pressed
4
  • This is a conventional solution BUT it is NOT a solution to the OP's problem because it requires that you implement a scanner to read pins. It will not execute a callback.
    – Milliways
    Commented Apr 12, 2021 at 8:55
  • Thank you very much, this is definitely good to know^^ Commented Apr 12, 2021 at 9:10
  • @MysteriousChallenger Hint: if you want to reply to a particular comment, use the @ notation instead of ^^. Commented Apr 14, 2021 at 7:47
  • 1
    @DmitryGrigoryev Ohhh good to know, I was not aware of that. Commented Apr 14, 2021 at 8:27

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.