How to stop repeat on button press/hold - Python

315 Views Asked by At

I was hoping someone might have some insight on how to stop a script from continuing to repeat if a button is held (or in my case pressed longer than a second)?

Basically i've a button setup on the breadboard, and I have it coded to play an audio file when the button is pressed. This works, however if the button isn't very quickly tapped, then the audio will repeat itself until button is fully released. Also if the button is pressed and held, the audio file will just repeat indefinitely.

I've recorded a quick recording to demonstrate the issue if its helpful, here: https://streamable.com/esvoy6

I should also note that I am very new to python (coding in general actually), so its most likely something simple that I just haven't been able to find yet. I am using gpiozero for my library.

Any help or insight is greatly appreciated!


Here is what my code looks like right now:

from gpiozero import LED, Button
import vlc
import time
import sys
def sleep_minute(minutes):
    sleep(minutes * 60)


# GPIO Pins of Green LED
greenLight = LED(17)
greenButton = Button(27)


# Green Button Pressed Definition
def green_btn_pressed():
    print("Green Button Pressed")
    greenButton.when_pressed = greenLight.on
    greenButton.when_released = greenLight.on

# Executed Script
while True:
    if greenButton.is_pressed:
        green_btn_pressed()
        time.sleep(.1)
        print("Game Audio Start")
        p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
        p.play()
2

There are 2 best solutions below

0
On

So from a brief look at it, it seems that 'time.sleep(.1)' is not doing what you are expecting. Ie. it is obviously interrupted by button presses. This is not abnormal behaviour as button presses on Ardiuno and raspPi (guessing here) would be processed as interrupts. The script itself does not contain any prevention from double pressing or press and hold etc.

Have you put in any debug lines to see what is executing when you press the button? I would start there and make adjustments based on what you are seeing.

I am not familiar with this gpiozero, so I can't give any insight about what it may be doing, but looking at the code and given the issue you are having, I would start with some debug lines in both functions to confirm what is happening.

Thinking about it for a minute though, could you not just change the check to 'if greenButton.is_released:'? As then you know the button has already been pressed, and the amount of time it is held in for becomes irrelevant. May also want to put in a check for if the file is already playing to stop it and start it again, or ignore and continue playing (if that is the desired behaviour).

Further suggestions:

For this section of code:

# Executed Script
while True:
    if greenButton.is_pressed:
        green_btn_pressed()
        time.sleep(.1)
        print("Game Audio Start")
        p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
        p.play()

You want to change this to something along these lines:

alreadyPlaying = 0
# Executed Script
while True:
    if greenButton.is_pressed:
        green_btn_pressed()

        #Check if already playing file.
        if alreadyPlaying == 1:
   
            # Do check to see if file is still playing (google this, not sure off the top of head how to do this easiest).
            # If file still playing do nothing, 
            #else set 'alreadyPlaying' back to '0'
            break


        #Check if already playing file.
        if alreadyPlaying == 0:
            time.sleep(.1)
            print("Game Audio Start")
            p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
            p.play()
            alreadyPlaying = 1

Hopefully you get the idea of what I am saying. Best of luck!

0
On

i think you have to write something like this in your loop:

import time, vlc

def Sound(sound):
    vlc_instance = vlc.Instance()
    player = vlc_instance.media_player_new()
    media = vlc_instance.media_new(sound)
    player.set_media(media)
    player.play()
    time.sleep(1.5)
    duration = player.get_length() / 1000
    time.sleep(duration)