Freier Toniebox Klon auf Raspberry Pi Basis
Inhaltsverzeichnis
Dieser Artikel beschreibt den Aufbau eines Tonabspielgerät für Kleinkinder. Vorbild ist das kommerzielle Produkt Toniebox bei der kleine Figuren au ein würfelförmiges Abspielgerät gestellt werden und so die Musikwiedergabe, z.B. von Hörspielen, starten.
Update 2020-03
- Danke an den Podcast Robotik Labor, der meine Box als eine von vier Alternativen zur Toniebox vorstellt!
- Ebenfalls Danke an techstage von heise online, die in ihrem Artikel auch auf meine Box verweisen!
Features
- Gleicher Formfaktor wie das kommerzielle Gerät
- Tasten für Pause, Lauter und Leiser
- Unterstützung von RFID-Karten statt Tonies zur Auswahl der Hörspielen
- Automatischer Sync neuer Hörspiele per Webdav aus einer Nextcloud-Installation
- Hotspot-Modus um neue WLAN-Zugangsdaten zu konfigurieren
Liste der Bauteile
Folgende Bauteile sind zum Einsatz gekommen:
Komponente | Bezeichnung | Preis |
---|---|---|
Systemplatine | Raspberry Pi Zero [2] | 13,58€ |
Soundkarte | Externe soundkarte Virtual Audio USB Sound karte Adapter 7,1 Kanal Für Laptop PC [1] | 1,00€ |
USB-Hub | Mini Micro USB To 4 Port USB OTG Hub For Raspberry Zero ODROID White 2017 [1] | 1,50€ |
Verstärker | 2/4stk PAM8403 Digital Audio Verstärker Lautsprecher Verstärkerplatine 2.5-5V [1] | 1,00€ |
Taster | 6 Stücke Lange Länge Arcade Spiel HAPP Stil Push Button für Mame und Jamma ED [1] | 2,55€ |
Knöpfe | 6x arcade Knöpfe happ druckknopf für jamma mame spiel Neu [1] | 3,59€ |
Gehäuse | Eigenbau aus Sperrholz | 6,69€ |
Stromanschluss | 30cm/50cm Micro USB 2.0 Male to Female Hole Panel Mount Extension Cable Kits Neu [1] | 1,09€ |
Lautsprecher | 3W 4 Ohm Metallgehaeuse Runder Magnet Lautsprecher Lautsprecher 2 Stueck M3G5 [1] | 1,40€ |
RFID-Leser | 125Khz EM4100 USB RFID ID Card Reader Swipe Card Reader Plug and Play With Cable [1] | 3,32€ |
RFID-Karten | 50 Stueck Intelligente Naehe EM4100 125kHz RFID Proximity Karte Eintrag Lee Q4F7 [1] | 8,63€ |
Stabilisierungskondensator | RAD LXZ 16/3K3 [3] | 0,65€ |
45,00€ |
Bezugsquellen: [1]ebay, [2]pimoroni, [3]reichelt
Bilder
Basissystem
Es kommt Void Linux zum Einsatz. Void nutzt Runit als Init-System und startet damit besonders schnell. Zum Starten von Diensten wird die Syntax sv start dienst
verwendet.
Schritte zur Installation
- Download des Basissystems von https://alpha.de.repo.voidlinux.org/live/20171007/void-rpi-musl-20171007.img.xz
- Basissystem auf eine SD-Karte schreiben
- Den RPi Zero mit der SD-Karte starten und per SSH verbinden (root/voidlinux)
- Folgende Befehle ausführen:
bash
loadkeys de
cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOL
ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
eapol_version=1
ap_scan=1
fast_reauth=1
update_config=1
EOL
# replace SSID and PWD with WLAN credentials
# escape characters like '!' with an '\', e.g. password! is password\!
wpa_passphrase $SSID $PWD >> /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
ln -s /etc/sv/dhcpcd /var/service
ln -s /etc/sv/sshd /var/service
ntpd
xbps-install -Su python3 python3-devel python3-pip vlc linux-headers gcc alsa-utils samba hostapd dnsmasq davfs2 rsync alsa-lib-devel
#optional
xbps-install alsa-utils
pip install python-vlc evdev RPi.GPIO pyalsaaudio
echo "majobox" > /etc/hostname
mkdir -p /etc/sv/majobox-control
cat > /etc/sv/majobox-control/run <<EOL
#!/bin/sh
exec python /srv/control/control.py
EOL
chmod +x /etc/sv/majobox-control/run
mkdir -p /etc/sv/majobox-sync
cat > /etc/sv/majobox-syn/run <<EOL
#!/bin/sh
exec bash /srv/control/sync.sh
EOL
chmod +x /etc/sv/majobox-sync/run
ln -s /etc/sv/majobox-sync /var/service
ln -s /etc/sv/majobox-control /var/service
# rename "rw" to "ro"
vi /boot/cmdline.txt
# add "defaults,ro" for / and /boot partitions
vi /etc/fstab
# comment rw-remount
vi /etc/runit/core-services/03-filesystems.sh
ln -s /run/runit/supervise.majobox-control /etc/sv/majobox-control/supervise
ln -s /run/runit/supervise.majobox-sync /etc/sv/majobox-sync/supervise
rm /etc/resolv.conf && ln -s /tmp/resolv.conf /etc/resolv.conf
ln -s /srv/control/change-wifi.sh /root/change-wifi.sh
# create third parition with defaults
fdisk /dev/mmcblk0 // -> create partition primary alle default werte, dann w, dann q
partx -u /dev/mmcblk0
mkfs.ext4 /dev/mmcblk0p3
tune2fs -m 0 /dev/mmcblk0p3
mkdir /srv
mkdir /srv/control /srv/music
mkdir /var/samba
useradd -M user
chown -R user.user /srv
cat >> /etc/fstab <<EOL
/dev/mmcblk0p3 /srv ext4 defaults,ro 0 1
tmpfs /var/log tmpfs defaults 0 0
tmpfs /var/samba tmpfs defaults 0 0
EOL
Skripte
#!/usr/bin/python
#
# Run this before first startup:
# - pip install evdev python-vlc RPi.GPIO
#
import vlc
import time
import string
import os
from evdev import InputDevice
from select import select
import glob
import RPi.GPIO as GPIO
import alsaaudio
mixer = alsaaudio.Mixer(control='Speaker')
Instance = vlc.Instance('--aout alsa')
list_player = Instance.media_list_player_new()
player = vlc.MediaPlayer("/srv/control/startup.mp3")
player.audio_output_device_set("alsa", "hw0:0")
player.play()
keys = "X^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXX"
dev = InputDevice('/dev/input/event1')
GPIO.setmode(GPIO.BOARD)
pin_stop = 40
pin_vol_down = 32
pin_vol_up = 36
volume = 15
mixer.setvolume(volume)
pins = [ pin_stop, pin_vol_down, pin_vol_up ]
GPIO.setup(pins, GPIO.IN, pull_up_down=GPIO.PUD_UP)
for pin in pins:
GPIO.add_event_detect(pin, GPIO.FALLING, bouncetime=1000)
id = ""
while True:
r,w,x = select([dev], [], [], 0.2)
if r:
for event in dev.read():
if event.type==1 and event.value==1:
print( keys[ event.code ] )
if keys[event.code] == 'X':
print("Recognized card with id " + id)
if id == "0016188996":
player = vlc.MediaPlayer("/srv/control/hotspot.mp3")
player.play()
time.sleep(5)
os.system("bash /srv/control/hotspot.sh")
else:
files = glob.glob("/srv/music/*"+id+"*")
player.stop()
list_player.stop()
if len(files) == 0:
player = vlc.MediaPlayer("/srv/control/error.mp3")
player.play()
else:
Media_list = Instance.media_list_new([files[0]])
list_player.set_media_list(Media_list)
list_player.play()
id = ""
else:
id += keys[event.code]
count = 1;
if GPIO.event_detected(pin_stop):
print("Pause\n")
count+= 1
list_player.pause()
if GPIO.event_detected(pin_vol_up):
volume += 4
if volume > 31:
volume = 31
count+= 1
print("Up " + str(volume) + "\n")
mixer.setvolume(volume)
if GPIO.event_detected(pin_vol_down):
volume -= 4
if volume < 3:
volume = 3
count+= 1
print("Down " + str(volume) + "\n")
mixer.setvolume(volume)
# https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
#!/bin/bash
sleep 30
while [ /bin/true ]; do
ntpd -s
mount -o remount,rw /srv
mkdir -p /tmp/dav
mount -t tmpfs none /var/cache/davfs2
sleep 5
mount -t davfs https://nextcloudserver/remote.php/webdav /tmp/dav
rsync -avu --delete /tmp/dav/* /srv
umount /tmp/dav
umount /var/cache/davfs2
mount -o remount,ro /srv
sleep 3600
done
#!/bin/bash
echo "WLAN SSID eingeben:"
read SSID
echo "Passwort eingeben:"
read PWD
mount -o remount,rw /
cat >/etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOL
ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
eapol_version=1
ap_scan=1
fast_reauth=1
update_config=1
EOL
wpa_passphrase $SSID $PWD >> /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
echo "Starte neu. Die Konsole kann geschlossen werden."
reboot
#!/bin/bash
mount -o remount,rw /srv
mount -o remount,rw /
mkdir -p /var/lib/misc
iw dev wlan0 interface add uap0 type __ap
ip link set dev uap0 up
ip addr add 192.168.50.1/24 dev uap0
dnsmasq -k --enable-dbus -u dnsmasq -g dnsmasq &
hostapd /srv/control/hotspot.conf &
interface=uap0
ssid=majobox
#hw_mode=g
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=xxx
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP