Hello everyone,
I’d like to build a standalone, disconnected sound box with a Raspberry Pi (for example, to present elements of a work of art or a model). The idea is to play a file (.wav, .mp3, etc.) on the SD card when buttons connected to the GPIOs are pressed. Has anyone else done this before?
Hi @Olivier2704
You need to be a bit more specific.
- You want to play/stop/pause by a button press? Look at plugin GPIO-Buttons.
- You want to play a track, depending on which button you press?
Hello @Wheaten ,
Thank you for this quick response.
I’d like to read a file based on the button pressed. Perhaps there’s a script (Python) to run in the background ?
This is just a scribble, successfully tested. It might give you a start: I don’t teach Python.
import gpiod
import requests
import time
# Define GPIO chip and line
CHIP_NAME = "/dev/gpiochip0" # Default chip on Raspberry Pi 4 and 5
BUTTON_LINE = 5 # Change to your actual GPIO pin number
# Volumio API URL
VOLUMIO_URL = "http://127.0.0.1:3000/api/v1/replaceAndPlay"
# Track URL or playlist
TRACK_URI = "NAS/QNAP/AC-DC/(1983) - Flick Of The Switch/0103 - AC-DC - Flick of the switch.flac" # Change this to the actual track URI
def play_track():
"""Sends command to Volumio to play a track"""
payload = {
"uri": TRACK_URI
}
try:
response = requests.post(VOLUMIO_URL, json=payload)
print(f"Track play command sent, response: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"Error sending request: {e}")
# Setup GPIO
chip = gpiod.Chip(CHIP_NAME)
button = chip.get_line(BUTTON_LINE)
button.request(consumer="volumio_button", type=gpiod.LINE_REQ_DIR_IN)
print("Listening for button press...")
try:
while True:
if button.get_value() == 0: # Button pressed (falling edge)
play_track()
time.sleep(0.3) # Debounce delay
time.sleep(0.1) # Polling interval
except KeyboardInterrupt:
print("Exiting...")
finally:
button.release()
May 19 08:31:09 rpi4-ws800 volumio[1377]: info: Preload queue cleared
May 19 08:31:09 rpi4-ws800 volumio[1377]: info: Adding Item to queue: mnt/NAS/QNAP/AC-DC/(1983) - Flick Of The Switch/0103 - AC-DC - Flick of the switch.flac
May 19 08:31:09 rpi4-ws800 volumio[1377]: info: Exploding uri mnt/NAS/QNAP/AC-DC/(1983) - Flick Of The Switch/0103 - AC-DC - Flick of the switch.flac in service mpd
Same script in bash:
#!/bin/bash
# Define GPIO chip and line
CHIP_NAME="/dev/gpiochip0" # Default chip on Raspberry Pi 4 and 5
BUTTON_LINE=5 # Change to your actual GPIO pin number
# Volumio API URL
VOLUMIO_URL="http://127.0.0.1:3000/api/v1/replaceAndPlay"
# Track URL or playlist
TRACK_URI="NAS/QNAP/AC-DC/(1983) - Flick Of The Switch/0103 - AC-DC - Flick of the switch.flac"
# Function to send command to Volumio to play a track
play_track() {
curl -X POST -H "Content-Type: application/json" -d "{\"uri\":\"$TRACK_URI\"}" "$VOLUMIO_URL"
echo "Track play command sent"
}
echo "Listening for button press..."
while true; do
BUTTON_STATE=$(gpioget $CHIP_NAME $BUTTON_LINE)
if [ "$BUTTON_STATE" -eq 0 ]; then
play_track
sleep 0.3 # Debounce delay
fi
sleep 0.1 # Polling interval
done
Hello, @Wheaten
Thank you very much for your valuable help, I will test this as soon as I can.
Have a nice day!
final contribution for multiple buttons (GPIO needs a default High):
sudo apt-get install gpiod
#!/bin/bash
# Define GPIO chip and button lines
CHIP_NAME="/dev/gpiochip0" # Default chip on Raspberry Pi 4 and 5
BUTTON_LINES=(2 5 6 7 8) # GPIO pins for buttons
# Volumio API URL
VOLUMIO_URL="http://127.0.0.1:3000/api/v1/replaceAndPlay"
# Track URIs corresponding to each button
TRACK_URIS=(
"track_01.flac"
"track_02.flac"
"track_03.flac"
"track_04.flac"
"track_05.flac"
)
# Function to send command to Volumio to play a track
play_track() {
local track_uri=$1
curl -X POST -H "Content-Type: application/json" -d "{\"uri\":\"$track_uri\"}" "$VOLUMIO_URL"
echo "Track play command sent: $track_uri"
}
# Initialize all GPIO buttons to `1`
echo "Initializing GPIO pins..."
for gpio in "${BUTTON_LINES[@]}"; do
gpioset $CHIP_NAME $gpio=1
done
echo "Listening for button presses..."
while true; do
for i in "${!BUTTON_LINES[@]}"; do
BUTTON_STATE=$(gpioget $CHIP_NAME "${BUTTON_LINES[$i]}")
if [ "$BUTTON_STATE" -eq 0 ]; then
play_track "${TRACK_URIS[$i]}"
sleep 0.3 # Debounce delay
fi
done
sleep 0.1 # Polling interval
done
Service:
sudo nano /lib/systemd/system/play_track.service
Copy/paste:
[Unit]
Description=Play Track By Button
[Service]
ExecStart=/bin/bash /home/volumio/scripts/play_track02.sh
[Install]
WantedBy=multi-user.target
ctrl+o => Enter => ctrl+x
sudo chmod 644 /lib/systemd/system/play_track.service
sudo systemctl daemon-reload && sudo systemctl enable play_track.service && sudo systemctl start play_track.service
Wow !
Thank you so much @Wheaten for this final, detailed contribution !
1 Like