Disclaimer: I am not a programmer, the instructions here are for illustration of my procedure. I take no responsibility for the correctness of the individual steps.
The manual was written after the keyboard was in use. It is likely that I do not reproduce all steps correctly.
In this case I ask kindly for feedback.
All files, including the laser cut template, can be downloaded here.
Hardware
For hardware the following was used:
- Raspberry Pi v3 (incl. suitable power supply and SD card)
- Jumper-Cable
- LAN-Cable and loose wire
- 8 Cherry-Switches
- laser cut plate
- USB soundbar
The switches communicate with the Raspberry Pi via its GPIO connection. This is done because the switches can be connected directly to it, no additional hardware or electronic components (like diodes) are needed.
The switches have to be connected to matching GPIO pins on one side and to the 3.3 volt output on the other side.
Important: Do not connect to the 5V output, this could destroy the Raspberry!
Note that the software uses the PIN assignment under “Pin No.”. The color-coded counting method “GPIO18” is not used!
The circuit diagram for the switches in my example looks like this:
The pin assignment (12,16,…37) is quite random. All pins marked yellow in the above layout can be used as input.
Together with the other GPIO pins a total of 26 switches could be connected.
A LAN cable was used as connection from the switches to the GPIO pins. For the ninth wire with the 3.3V another wire was used, because the LAN cable has only eight wires.
The wires were soldered with jumper cables so that they can be easily connected to the Raspberry.
Unfortunately there is no photo of the soldered-on switches, as they were already firmly installed in the table when this manual was written.
Software
- Dietpi
- Logitech Media Server (LMS)
- Squeezelite
- Python3
- own Code
On the Raspberry Pi, dietpi is used. This works great for my applications and is more intuitive for me to use than e.g. Raspian.
The installation instructions can be found here.
Since the device is also used via a web interface for music and pi-hole for blocking ads, a static IP address was used.
After the installation the software Logitech Media Server, squeezelite and python3 must be installed. This is done either via the console directly (apt install….) or via the CLI.
To do this, connect to ssh after restarting the Raspberry after successful installation:
ssh root@192.168.1.11
now we use
dietpi-launcher
to enter the configuration:
in the “DietPi software” tab, search for the Logitech Media Server, squeezelite and python3 software, mark them for installation and then perform the installation.
After installation, the Logitech Media Server can be reached via telnet:
telnet 192.168.1.11 9090
# or, if you work via ssh on the pi
telnet 127.0.0.1 9090
Squeezelite should run directly and be recognized as a player by the server.
It is visible within the web interface of LMS, or in the telnet connection created above via:
player id 0 ?
The player ID should be output there (in my case b8%3A27%3Aeb%3A6d%3A46%3A2f), which we need later.
I created a small bash script for each of the buttons.
A Python script monitors the GPIO pins and executes the respective program when voltage is applied.
So in total there are nine programs directly in /root:
The main program is called “mediainterface.py” and looks like this:
from signal import pause
from time import sleep
import RPi.GPIO as GPIO # Import Raspberry Pi GPIO library
import subprocess
GPIO.setmode(GPIO.BOARD) # Use physical pin numbering
# set GPIO pins as input, use pull_up_down=GPIO.PUD_DOWN so no false positive will be executed
GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(32, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(36, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(38, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(40, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(37, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
while True:
if (GPIO.input(12) == True): # this will happen, if you press key 1 on GPIO 12
print ("Station 1")
print(subprocess.run(["/root/media_sender1.sh"], shell=True))
elif (GPIO.input(16) == True): # this will happen, if you press key 2 on GPIO 16, and so on
print ("Station 2")
print(subprocess.run(["/root/media_sender2.sh"], shell=True))
elif (GPIO.input(22) == True):
print ("Station 3")
print(subprocess.run(["/root/media_sender3.sh"], shell=True))
elif (GPIO.input(32) == True):
print ("Playlist")
print(subprocess.run(["/root/media_sender4.sh"], shell=True))
elif (GPIO.input(36) == True):
print ("next song")
print(subprocess.run(["/root/media_naechste.sh"], shell=True))
elif (GPIO.input(38) == True):
print ("louder")
print(subprocess.run(["/root/media_lauter.sh"], shell=True))
elif (GPIO.input(40) == True):
print ("quieter")
print(subprocess.run(["/root/media_leiser.sh"], shell=True))
elif (GPIO.input(37) == True):
print ("start stop")
print(subprocess.run(["/root/media_startstop.sh"], shell=True))
else: # if no key is pressed print the following message
print ("no key pressed")
sleep(0.05);Das Programm wird später als Dienst beim booten gestartet. Zum debuggen kann es aber auch über
Now the player ID is needed, which we asked for above.
The 8 programs differ only in the command that establishes the telnet connection:
media_sender1.sh
#!/usr/bin/sh
{
# echo player-id and what to do
echo 'b8%3A27%3Aeb%3A6d%3A46%3A2f playlist play http://opml.radiotime.com/Tune.ashx?id=s6814&formats=aac,ogg,mp3,wmpro,wma,wmvoice&partnerId=16&serial=19921792a9beadbc696d127f51ffe697 '
echo exit
} | telnet 127.0.0.1 9090
media_sender2.sh
#!/usr/bin/sh
{
# echo player-id and what to do
echo 'b8%3A27%3Aeb%3A6d%3A46%3A2f playlist play http://opml.radiotime.com/Tune.ashx?id=s297245&formats=aac,ogg,mp3,wmpro,wma,wmvoice&partnerId=16&serial=f44593cefc521f640e09c8e062c682b1 '
echo exit
} | telnet 127.0.0.1 9090
media_sender3.sh
#!/usr/bin/sh
{
# echo player-id and what to do
echo 'b8%3A27%3Aeb%3A6d%3A46%3A2f playlist play http://opml.radiotime.com/Tune.ashx?id=s221296&formats=aac,ogg,mp3,wmpro,wma,wmvoice&partnerId=16&serial=19921792a9beadbc696d127f51ffe697 '
echo exit
} | telnet 127.0.0.1 9090
media_sender4.sh
#!/usr/bin/sh
{
# echo player-id and what to do, in this case a random playlist
echo 'b8%3A27%3Aeb%3A6d%3A46%3A2f randomplay tracks '
echo exit
} | telnet 127.0.0.1 9090
media_naechste.sh
#!/usr/bin/sh
{
# echo player-id and what to do
echo 'b8%3A27%3Aeb%3A6d%3A46%3A2f playlist index +1 '
echo exit
} | telnet 127.0.0.1 9090
media_lauter.sh
#!/usr/bin/sh
{
# echo player-id and what to do
echo 'b8%3A27%3Aeb%3A6d%3A46%3A2f mixer volume +5 '
sleep 0.2 # important, wait 200ms before increasing volume again
echo exit
} | telnet 127.0.0.1 9090
media_leiser.sh
#!/usr/bin/sh
{
# echo player-id and what to do
echo 'b8%3A27%3Aeb%3A6d%3A46%3A2f mixer volume -5 '
sleep 0.2
echo exit
} | telnet 127.0.0.1 9090
media_startstop.sh
#!/usr/bin/sh
{
# echo player-id and what to do
echo 'b8%3A27%3Aeb%3A6d%3A46%3A2f pause '
sleep 1
echo exit
} | telnet 127.0.0.1 9090
After creation all scripts must be marked as executable:
chmod +x media*.sh
The program can now be tested by using the ssh connection via
python3 mediainterface.py
is called.
The terminal should fill with “no key pressed”. When pressing one of the buttons, the message stored in the Python script should appear and the respective program should be started.
In order for the Python script to be started automatically at boot, it must be created as a system service.
systemctl --force --full edit mediainterface.service
add there:
[Unit]
Description=My mediainterface
After=multi-user.target
[Service]
ExecStart=/usr/bin/python3 /root/mediainterface.py
[Install]
WantedBy=multi-user.target
Activate the service:
systemctl daemon-reload
systemctl enable --now mediainterface.service
and finally reboot:
reboot
After this, the keyboard should work.
If you have any questions, you can ask under this Reddit post.