1

I can't seem to find a solution of doing this using GPIO Zero. I've done it using rpi.gpio with add_event_detect and call back to change state but I was under the impression GPIO Zero is much simpler.

This link https://projects.raspberrypi.org/en/projects/physical-computing/9 basically says a switch would turn the LED on with a press and release, then turn it off with another press and release, but it doesn't actually show how to do this.

    from gpio import LEDBoard, Button
    
    button = Button(5, pull_up=True, bounce_time=200)
    leds = LEDBoard(26, 19, 13, 6)
    
    def on():
    leds.on()
    print('On...')

    def off():
    leds.off()
    print('off...')

    button.when_pressed = on
    button.when_released = off

It doesn't even turn off when released. Is that due to the pull_up = True? I thought this code would turn it on when pressed and off when released but it just turns on and stays on.

11
  • You are asking us to guess how your button is wired up.
    – joan
    Commented May 7, 2019 at 10:05
  • @joan Oh, I'm sorry! didn't think it was relevent. Honestly thought this was just a python issue. The button is connected to ground pin and gpio5 pin, leds are connected to ground and 4 gpio pins.
    – user100971
    Commented May 7, 2019 at 10:19
  • ...and by gpio5 pin you mean pin 29? See pinout.xyz
    – joan
    Commented May 7, 2019 at 10:25
  • @joan Apologies, I meant BCM 5 not pin 5! Ok. Do you have everything you need to help me now? :)
    – user100971
    Commented May 7, 2019 at 10:27
  • 1
    In that configuration the button will normally read high (1) because of the pull-up to 3V3. When you press the button it is connected to ground and the button will read low (0). When you release the button it will again read high.
    – joan
    Commented May 7, 2019 at 10:30

4 Answers 4

0

Question

How to toggle a button ... ?

Answer

Well, the OP's "question" is not a question,so I can give no answer. But I can explain why the OP's "question" is not a question.

  1. A human can press a button and then release the button. This is not a "toggle". Let us say if the human presses button and then releases, and after some time, the human presses the button again and releases. Now there are two sequences of press event and release event, or if you like, one sequence of four events: press, release, press, release. No "toggling" happened ever.

  2. Now the LED. Python can "toggle" a LED, ie, if the LED is on, then turn it off, and vice versa. This is the meaning of "toggling" a LED.

In other words, python can toggle a LED, but never a button, because only a human can change the status of a button: being pressed, being released. I know it is confusing. Perhaps a picture helps.

led toggle

The picture below tells (1) how to toggle LED, and (2) how to read button.

button and led

3
  • 1
    @tifong01: Ok. My terminology has been a bit off. I meant how do I turn a button into a switch? So I need 2 sequences to turn it off and on. Can you help me? the picture didn't help. button.wait_for_press() then led.toggle sleep(0.5). button.wait_for_press() `led.off(). That just turns the Leds on and they stay on. At the very least it should toggle?
    – user100971
    Commented May 7, 2019 at 13:33
  • Well,let you show you a switch.
    – tlfong01
    Commented May 7, 2019 at 14:04
  • I have shown the led and button picture. See you tomorrow.
    – tlfong01
    Commented May 7, 2019 at 14:36
0

Are you asking to have the LED on when the button is pressed and off when the button is unpressed? If so, this section from the gpiozero docs explains how to do so:

"Turn on an LED when a Button is pressed:

from gpiozero import LED, Button 
from signal import pause 

led = LED(17) 
button = Button(2)

button.when_pressed = led.on
button.when_released = led.off 

pause()

Alternatively:

from gpiozero import LED, Button 
from signal import pause 

led = LED(17) 
button = Button(2) 

led.source = button 

pause()
0

There is a toggle function in GPIO zero. So if you want a single LED on pin 26 to change state every time a button on pin 5 is pressed:

from gpiozero import LED, Button
from time import sleep

led = LED(26)
button = Button(5)

while True:
    if button.is_pressed:
        led.toggle()
        sleep(0.5)

(The sleep is needed, otherwise it changes state while you're pressing the button, and all you get is a strobing LED when you push the button)

0

I meant how do I turn a button into a switch?

from gpiozero import LED, Button

led = LED(25)
button = Button(2)

while True : # otherwise the script will only work once
        button.wait_for_press()
        led.toggle()
        button.wait_for_release()

So I need 2 sequences to turn it off and on

Example 1: toggle state with functions (stays on or off)

from gpiozero import LED, Button

led = LED(25) # GPIO 25
ledState= 0
button = Button(2) # GPIO 2

def on():
    led.on() # Since Python doesn't have function-enclosing parentheses, here are 4 spacebars to assign the contents to the function.

def off():
    led.off()


while True : # otherwise the script will only work once
        button.wait_for_press()
        if ledState == 0:
            on()
            ledState = 1
            button.wait_for_release()   # wait or otherwise the script will trigger again while the button is still pressed
            continue        # stop the current loop iteration here and start again
        if ledState == 1:   # alternative: if not ledState == 0: or else: 
             off()
             ledState = 0
             button.wait_for_release()

Example 2: toggle state with functions (led is on, only while button is pressed)

from gpiozero import LED, Button

led = LED(25) # GPIO 25
ledState= 0
button = Button(2) # GPIO 2

def on():
    led.on() # Since Python doesn't have function-enclosing parentheses, here are 4 spacebars to assign the contents to the function.

def off():
    led.off()


while True : # otherwise the script will only work once
    button.wait_for_press()
    on()
    button.wait_for_release()
    off()

Example 3 using functions and "when_pressed" && "when_released"

Useful link: https://gpiozero.readthedocs.io/en/stable/faq.html

from gpiozero import LED, Button
from signal import pause

led = LED(25) # GPIO 25
button = Button(2) # GPIO 2

def on():
    led.on() # Since Python doesn't have function-enclosing parentheses, here are 4 spacebars to assign the contents to the function.

def off():
    led.off()

button.when_pressed = on # Contrary to expectations, there should be no parentheses after the function call
button.when_released = off

pause() # prevents the script from stopping after it read through everything. The pause function enables the script to keep on listening for button presses

Your Answer

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