Use hardware momentary switches to control moOde - remy1961 - 05-20-2018
Hardware momentary switches can be used to control the play, pause, next, previous functions of moode. They can also be used to power off and to launch a playlist.
On the hardware side, you set your hardware button to connect the ground pin of your RPi with a GPIO pin of your choice. Have a look here to see how to select the gpio pins.
Then you have to open a ssh session.
Create a new directory called "hwbuttons"
Go to the new directory
Open nano text editor
Paste the following python script. This python script include the following buttons:
Toggle play pause: GPIO 12
Previous: GPIO 10
Next: GPIO 11
Volume up: GPIO 20
Volume down: GPIO 26
Power off: GPIO 9
Launch playlist "JAZZ_STREAM": GPIO 16
Launch playlist "MUSIC_STREAM": GPIO 13
It works for radio stations and music files. Make sure no spaces on playlists names.
If you are not interested in a particular button, mark it with # everywhere it appears.
Code: #!/usr/bin/python
#script for moode audio GPIO buttons
#not sure this is needed:
#sudo apt-get update
#sudo apt-get install python-dev
#sudo apt-get install python-rpi.gpio
#on playlist names no spaces
#import
import RPi.GPIO as GPIO
import sys
import time
import os
import subprocess
#set GPIO mode
GPIO.setmode(GPIO.BCM)
#Define your GPIO pins
SW_PREV = 10
SW_NEXT = 11
SW_PLAY = 12
SW_VOLUP = 20
SW_VOLDOWN = 26
SW_POWEROFF = 9
SW_PL1 = 16
SW_PL2 = 13
#code to manage BUTTONS
GPIO.setup(SW_PREV,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_NEXT,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_PLAY,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_VOLUP,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_VOLDOWN,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_POWEROFF,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_PL1,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_PL2,GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
try:
prev_switch = GPIO.input(SW_PREV)
next_switch = GPIO.input(SW_NEXT)
play_switch = GPIO.input(SW_PLAY)
volup_switch = GPIO.input(SW_VOLUP)
voldown_switch = GPIO.input(SW_VOLDOWN)
poweroff_switch = GPIO.input(SW_POWEROFF)
pl1_switch = GPIO.input(SW_PL1)
pl2_switch = GPIO.input(SW_PL2)
if prev_switch == False:
subprocess.call(['mpc', 'prev' ])
print "previous"
elif next_switch == False:
subprocess.call(['mpc', 'next' ])
print "next"
elif poweroff_switch == False:
subprocess.call(['mpc', 'stop' ])
subprocess.call(['sudo', 'poweroff' ])
print "shutting down"
elif volup_switch == False:
subprocess.call(['/var/www/vol.sh','up','2' ])
print "volumeup"
elif voldown_switch == False:
subprocess.call(['/var/www/vol.sh','dn','2' ])
print "volumedown"
elif pl1_switch == False:
subprocess.call(['mpc','clear' ])
subprocess.call(['mpc','load','JAZZ_STREAM' ])
subprocess.call(['mpc','play' ])
elif pl2_switch == False:
subprocess.call(['mpc','clear' ])
subprocess.call(['mpc','load','MUSIC_STREAM' ])
subprocess.call(['mpc','play' ])
elif play_switch == False:
subprocess.call(['mpc', 'toggle' ])
print "play"
time.sleep(0.5)
except KeyboardInterrupt:
print "\nExit"
GPIO.setwarnings(False)
GPIO.cleanup()
sys.exit(0)
#End of program
ctrl-x and save the file as "buttons.py"
To set the script to run every time you launch moode
Code: sudo nano /etc/rc.local
Add the line below just before the exit 0
Code: sudo python /home/pi/hwbuttons/buttons.py &
It works on my moode streamer. I did put this together from information I found on the volumio forum and from help I received from Kent (aka theoldpresbyope). It is possible that some of the lines in the script are not needed.
Remy
RE: Use hardware momentary switches to control moOde - rikardo1979 - 05-20-2018
Very nice. Thank you for share
RE: Use hardware momentary switches to control moOde - rh2018 - 09-26-2018
Hi Remy,
Thanks for your great tutorial. Combined with your lcd/oled pydPiper script it adds very useful operational flexibility to moOde.
Did you need to de-bounce your momentary push-button switches?
I notice that occasionally the "stop"/"play" toggle appears not to respond, jumping to the previous state due I think to contact bounce. Or maybe it's just poor quality switches I'm using for testing.
Any advice would be appreciated.
Regards,
Richard.
RE: Use hardware momentary switches to control moOde - remy1961 - 09-27-2018
Hi Richard,
Sorry for the delay. Since mine is working properly with the same script, the problem might be with the switch. Or the software can be improved by forcing a delay after a command is received and before receiving another one. That is beyond what i am able to do.
Remy
RE: Use hardware momentary switches to control moOde - rh2018 - 09-28-2018
(09-27-2018, 03:49 PM)remy1961 Wrote: Hi Richard,
Sorry for the delay. Since mine is working properly with the same script, the problem might be with the switch. Or the software can be improved by forcing a delay after a command is received and before receiving another one. That is beyond what i am able to do.
Remy
Thanks Remy,
A change of switch minimised the problem.
There is a lot of information on the web about de-bouncing in software but it is beyond me also.
I guess a neat solution would be to insert a schmitt trigger between the swicth and the GPIO pin but with a good switch it's not really worth the effort.
Regards,
Richard.
RE: Use hardware momentary switches to control moOde - Cyanoazimin - 02-24-2019
(05-20-2018, 03:05 PM)remy1961 Wrote: Hardware momentary switches can be used to control the play, pause, next, previous functions of moode. They can also be used to power off and to launch a playlist
... Thank you for the code. It works perfectly, but only if some blanks are removed before
" elif voldown_switch == False:"
RE: Use hardware momentary switches to control moOde - TheOldPresbyope - 02-24-2019
(02-24-2019, 05:14 PM)Cyanoazimin Wrote: (05-20-2018, 03:05 PM)remy1961 Wrote: Hardware momentary switches can be used to control the play, pause, next, previous functions of moode. They can also be used to power off and to launch a playlist
... Thank you for the code. It works perfectly, but only if some blanks are removed before
" elif voldown_switch == False:"
Good catch.
In Python correct indentation is important.
RE: Use hardware momentary switches to control moOde - remy1961 - 02-25-2019
(02-24-2019, 05:14 PM)Cyanoazimin Wrote: (05-20-2018, 03:05 PM)remy1961 Wrote: Hardware momentary switches can be used to control the play, pause, next, previous functions of moode. They can also be used to power off and to launch a playlist
... Thank you for the code. It works perfectly, but only if some blanks are removed before
" elif voldown_switch == False:"
Correction made. Thanks.
Remy
RE: Use hardware momentary switches to control moOde - Cyanoazimin - 03-03-2019
I have changed your code to interrupt and debouncing, as it sometimes did not react fast enough. And added time to track bouncing in the serial monitor. No hardware debouncing needed (no pull resistors, capacitors). Works more smoothly now:
Code: #!/usr/bin/python
#coding: utf8
#script for moode audio GPIO buttons
#on playlist names no spaces
#import
import RPi.GPIO as GPIO
import sys
import time
import datetime
import os
import subprocess
#set GPIO mode instead of GPIO.setmode(GPIO.BOARD) - Zählweise der Pins festlegen
GPIO.setmode(GPIO.BCM)
#Define your GPIO pins
SW_PREV = 10
SW_NEXT = 11
SW_POWEROFF = 9
SW_PLAY = 12
#SW_VOLUP = 20
#SW_VOLDOWN = 26
#SW_PL1 = 16
#SW_PL2 = 13
PRELL = 1000 # Adjust to the button characteristics if necessary
#code to manage BUTTONS
GPIO.setup(SW_PREV,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_NEXT,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_POWEROFF,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_PLAY,GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(SW_VOLUP,GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(SW_VOLDOWN,GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(SW_PL1,GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(SW_PL2,GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Ereignis-Prozedur für SW_PREV
def eSW_PREV(channel):
subprocess.call(['mpc', 'prev' ])
print str(datetime.datetime.now())[:19] + " previous"
def eSW_NEXT(channel):
subprocess.call(['mpc', 'next' ])
print str(datetime.datetime.now())[:19] + " next"
def eSW_POWEROFF(channel):
subprocess.call(['mpc', 'stop' ])
subprocess.call(['sudo', 'poweroff' ])
print str(datetime.datetime.now())[:19] + " shutting down"
def eSW_PLAY(channel):
subprocess.call(['mpc', 'toggle' ])
print str(datetime.datetime.now())[:19] + " play"
# Ereignis deklarieren
GPIO.add_event_detect(SW_PREV, GPIO.RISING, callback = eSW_PREV, bouncetime = PRELL)
GPIO.add_event_detect(SW_NEXT, GPIO.RISING, callback = eSW_NEXT, bouncetime = PRELL)
GPIO.add_event_detect(SW_POWEROFF, GPIO.RISING, callback = eSW_POWEROFF, bouncetime = PRELL)
GPIO.add_event_detect(SW_PLAY, GPIO.RISING, callback = eSW_PLAY, bouncetime = PRELL)
# Eigentlicher Programmablauf
while True:
time.sleep(1)
RE: Use hardware momentary switches to control moOde - cyoops - 03-14-2019
(03-03-2019, 06:29 PM)Cyanoazimin Wrote: I have changed your code to interrupt and debouncing, as it sometimes did not react fast enough. And added time to track bouncing in the serial monitor. No hardware debouncing needed (no pull resistors, capacitors). Works more smoothly now:
Code: #!/usr/bin/python
#coding: utf8
#script for moode audio GPIO buttons
#on playlist names no spaces
#import
import RPi.GPIO as GPIO
import sys
import time
import datetime
import os
import subprocess
#set GPIO mode instead of GPIO.setmode(GPIO.BOARD) - Zählweise der Pins festlegen
GPIO.setmode(GPIO.BCM)
#Define your GPIO pins
SW_PREV = 10
SW_NEXT = 11
SW_POWEROFF = 9
SW_PLAY = 12
#SW_VOLUP = 20
#SW_VOLDOWN = 26
#SW_PL1 = 16
#SW_PL2 = 13
PRELL = 1000 # Adjust to the button characteristics if necessary
#code to manage BUTTONS
GPIO.setup(SW_PREV,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_NEXT,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_POWEROFF,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW_PLAY,GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(SW_VOLUP,GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(SW_VOLDOWN,GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(SW_PL1,GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(SW_PL2,GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Ereignis-Prozedur für SW_PREV
def eSW_PREV(channel):
subprocess.call(['mpc', 'prev' ])
print str(datetime.datetime.now())[:19] + " previous"
def eSW_NEXT(channel):
subprocess.call(['mpc', 'next' ])
print str(datetime.datetime.now())[:19] + " next"
def eSW_POWEROFF(channel):
subprocess.call(['mpc', 'stop' ])
subprocess.call(['sudo', 'poweroff' ])
print str(datetime.datetime.now())[:19] + " shutting down"
def eSW_PLAY(channel):
subprocess.call(['mpc', 'toggle' ])
print str(datetime.datetime.now())[:19] + " play"
# Ereignis deklarieren
GPIO.add_event_detect(SW_PREV, GPIO.RISING, callback = eSW_PREV, bouncetime = PRELL)
GPIO.add_event_detect(SW_NEXT, GPIO.RISING, callback = eSW_NEXT, bouncetime = PRELL)
GPIO.add_event_detect(SW_POWEROFF, GPIO.RISING, callback = eSW_POWEROFF, bouncetime = PRELL)
GPIO.add_event_detect(SW_PLAY, GPIO.RISING, callback = eSW_PLAY, bouncetime = PRELL)
# Eigentlicher Programmablauf
while True:
time.sleep(1)
thanks for sharing, it works perfectly on my pi
|