Construire une radio Internet Wi-Fi avec Raspberry Pi et Arduino : diffuser des stations mondiales
Composants et fournitures
| Arduino UNO | × | 1 |
| Raspberry Pi 3 Modèle B | × | 1 |
| Shield LCD Keypad SainSmart pour Arduino | × | 1 |
| Alimentation 5 V | × | 1 |
Applications et services en ligne
- Python
À propos de ce projet
Vue d'ensemble
J'adore écouter la radio quand je bricole ou cuisine, mais là où j'habite la réception FM est terrible. Et avec Internet, écouter des stations du monde entier est un plaisir, mais je n'aime pas utiliser mon smartphone pour écouter de la musique. Après beaucoup de recherches, j'ai trouvé plusieurs solutions.
J'ai basé ce projet sur un autre tutoriel : Arduino / Raspberry Pi Internet Radio par akellyirl. Le code est écrit en Python sur le Raspberry Pi et utilise essentiellement le démon lecteur de musique Linux (mpd) et le lecteur (mpc). Il existe une bibliothèque nanpy qui permet à Python de communiquer avec l'Arduino qui contrôle les boutons poussoirs et l'écran LCD.
J'ai utilisé un shield clavier/LCD pour Arduino avec boutons poussoirs : SainSmart LCD Keypad Shield for Arduino, et j'ai ajouté plus tard une bande de 4 boutons récupérée sur un réveil cassé. Au début, j'ai utilisé un Raspberry Pi 2 avec un adaptateur WiFi USB, mais maintenant j'utilise un RP3 qui a le WiFi intégré et n'a pas besoin d'antenne.
La partie la plus difficile a été de trouver les bonnes URL des stations souhaitées. J'ai finalement trouvé ce programme : URL HELPER qui renifle le site sur lequel vous êtes et affiche les URL des médias en cours de lecture. Pour le son, j'ai utilisé une paire d'enceintes actives d'ordinateur également récupérées.
Instructions d'installation
Instructions d'installation pour RP3 (depuis Arduino / Raspberry Pi Internet Radio par akellyirl sur Arduino) :
- Mettez à jour Raspbian vers les derniers paquets :
$ sudo apt-get update - Installez les paquets mpd/mpc :
$ sudo apt-get install mpc mpd
Nous voulons pouvoir parler à l'Arduino depuis Python qui tourne sur le Pi. Pour cela, nous devons installer la bibliothèque nanpy pour Python et le firmware nanpy pour Arduino :
- Installez les paquets Arduino pour construire le firmware nanpy pour Arduino :
$ apt-get install arduino - Récupérez la bibliothèque nanpy pour Python et extrayez-la depuis /home/pi :
$ wget https://pypi.python.org/packages/source/n/nanpy/nanpy-v0.7.tar.gz $ tar xvf nanpy-v0.7.tar.gz - Récupérez setuptools pour Python (dépendance pour nanpy) et extrayez :
$ wget https://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz#md5=7df2a529a074f613b509fb44feefe74e $ tar xvf setuptools-0.6c11.tar.gz - Récupérez pyserial pour Python (dépendance pour nanpy) et extrayez :
$ wget https://pypi.python.org/packages/source/p/pyserial/pyserial-2.6.tar.gz $ tar xvf pyserial-2.6.tar.gz - Allez dans le répertoire setuptools et installez setuptools Python :
$ cd setuptools-0.6c11 $ sudo python setup.py install - Allez dans le répertoire nanpy et installez la bibliothèque Python nanpy :
$ cd ../nanpy $ sudo python setup.py install - Allez dans le répertoire serial et installez la bibliothèque Python serial :
$ cd ../pyserial-2.6 $ sudo python setup.py install
Maintenant nous avons les fichiers nécessaires, mettons le firmware nanpy sur l'Arduino.
Firmware
nanpy permet à un programme Python tournant sur le Raspberry Pi d'opérer l'Arduino en utilisant la syntaxe classique d'un sketch Arduino, par exemple le programme Python pour lire une entrée analogique de l'Arduino pourrait lire :
int val = Arduino.analogRead(14)
Nanpy a deux composants :
- Une bibliothèque pour Python qui permet d'écrire des commandes Arduino dans une syntaxe familière et de communiquer avec l'Arduino ;
- Un firmware qui tourne sur l'Arduino, communiquant avec Python sur le Pi.
Nous avons installé la partie Python de nanpy et téléchargé la partie Arduino de nanpy sur le Pi à l'étape précédente. Maintenant, nous devons téléverser le firmware nanpy sur l'Arduino.
Branchez l'Arduino sur l'USB du Raspberry Pi.
- Allez dans le répertoire firmware de nanpy et téléversez sur l'Arduino :
$ cd ../nanpy/firmware $ export BOARD=uno $ make $ make upload
Si vous obtenez un rapport indiquant que le périphérique n'est pas trouvé sur /dev/ttyACM0, branchez l'Arduino sur l'autre port USB.
J'ai créé un script de playlist et un script Python (publiés dans l'onglet code) et j'ai fait en sorte que le script Python se lance automatiquement au démarrage du Raspberry. J'ai aussi ajouté un autre bouton poussoir pour afficher des options de menu comme l'affichage de l'IP ou le choix de la sortie audio.
Dernière mise à jour : je l'ai refait, ajouté des encodeurs rotatifs pour la sélection et le volume, et imprimé le boîtier en 3D :
Code
- piradio (Python)
- radio_playlist.sh (Script shell)
piradio
Je ne suis pas un programmeur Python (c'est principalement du copier-coller de morceaux trouvés sur Google. Pour l'instant ça marche :) Ce script doit se charger au démarrage sur le Pi, je l'ai ajouté dans une tâche cron.
from datetime import datetime
from subprocess import *
from time import sleep, strftime
from Queue import Queue
from threading import Thread
import os
from nanpy import Arduino, Lcd
import socket
Arduino.pinMode(14, INPUT)
lcd = Lcd([8,9,4,5,6,7],[16,2]) # Configuration broches LCD pour shield SainSmart
lcd.printString("Ruben's RadioZ",0,0)
lcd.printString("Loading" + "."*3,0,1)
sleep(5)
max_trax = 10
x = 1
loop_menu = 1
loop_radio = 1
stations = []
# Ajouté pour afficher le nom de la station quand bouton pressé
stations.append("Ecco 99 ")
stations.append("Galgalaz ")
stations.append("Galaz ")
stations.append("88 FM ")
stations.append("Gimel ")
stations.append("Radios 100fm ")
stations.append("Kol Hamusica ")
stations.append("WQXR New York ")
stations.append("WPR Winsconsin ")
stations.append("BBC world servic")
stations.append("LINN jazz")
stations.append("LINN classical")
def get_local_ip_address(target):
ipaddr = ''
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((target, 8000))
ipaddr = s.getsockname()[0]
s.close()
except:
pass
return ipaddr
print "Raspberry Pi - Local IP Address"
print(get_local_ip_address('10.0.1.1'))
print(get_local_ip_address('google.com'))
# Afficher l'adresse IP
def display_ipaddr():
show_wlan0 = "ip addr show wlan0 | cut -d/ -f1 | awk '/inet/ {printf \"w%15.15s\", $2}'"
show_eth0 = "ip addr show eth0 | cut -d/ -f1 | awk '/inet/ {printf \"e%15.15s\", $2}'"
ipaddr = ''
#ipaddr = run_cmd(show_eth0)
ipaddr = get_local_ip_address('10.0.1.1')
#if ipaddr == "":
# ipaddr = run_cmd(show_wlan0)
lcd.printString('IP Address:',0,0)
lcd.printString(ipaddr,0,1)
sleep(2)
# Menu dans le cinquième bouton
def displaymenu():
if x==1:
lcd.printString("1. Display ",0,0)
lcd.printString(" IP Address ",0,1)
elif x==2:
lcd.printString("2. Audio Output ",0,0)
lcd.printString(" to hdmi Port ",0,1)
elif x==3:
lcd.printString("3. Audio Output ",0,0)
lcd.printString(" to Analog port",0,1)
elif x==4:
lcd.printString("4. Audio Output ",0,0)
lcd.printString(" Auto Sel. Port",0,1)
elif x==5:
lcd.printString("5. Reload the ",0,0)
lcd.printString(" Playlist ",0,1)
elif x==6:
lcd.printString("6. ShutDown ",0,0)
lcd.printString(" the System ",0,1)
else:
lcd.printString("7. Exit to ",0,0)
lcd.printString(" Main Menu ",0,1)
def load_playlist():
output = run_cmd("mpc clear")
output = run_cmd("/home/pi/radio/radio_playlist.sh")
def run_cmd(cmd):
p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
output = p.communicate()[0]
return output
def getKey():
val = Arduino.analogRead(14)
if val == 1023:
return "NONE"
elif val < 100:
return "RIGHT"
elif val < 150:
return "UP"
elif val < 330:
return "DOWN"
elif val < 510:
return "LEFT"
elif val < 750:
return "SEL"
else:
return "KBD_FAULT"
load_playlist()
def getTrack():
L = [S.strip('\n') for S in os.popen('mpc').readlines()]
# Récupère les infos de piste depuis stdout de la commande mpc
output = run_cmd("mpc current")
station = output[0:16]
track = output[-17:-1]
lcd.printString(station + " "*(16 - len(station)), 0, 0)
lcd.printString(track + " "*(16 - len(track)), 0, 1)
track_num = 1
os.system("sudo service mpd restart")
os.system("mpc play " + str(track_num))
while loop_radio == 1:
getTrack()
loop_menu = 1
x = 1
key = getKey()
if key == "UP":
track_num += 1
if track_num > max_trax:
track_num = 1
lcd.printString(stations[track_num-1],0,0)
os.system("sudo service mpd restart")
os.system("mpc play " + str(track_num))
getTrack()
elif key == "DOWN":
track_num -= 1
if track_num < 1:
track_num = max_trax
lcd.printString(stations[track_num-1],0,0)
os.system("sudo service mpd restart")
os.system("mpc play " + str(track_num))
getTrack()
elif key == "LEFT":
os.system("mpc volume +10")
lcd.printString(16*" ", 0, 0)
lcd.printString(16*" ", 0, 1)
output = run_cmd("mpc volume")
lcd.printString("VOLUME UP:", 0, 0)
lcd.printString(output, 5, 1)
sleep(.25)
lcd.printString(16*" ",0,0)
lcd.printString(16*" ",0,1)
elif key == "RIGHT":
os.system("mpc volume -10")
lcd.printString(16*" ",0,0)
lcd.printString(16*" ", 0,1)
output = run_cmd("mpc volume")
lcd.printString("VOLUME DOWN:", 0, 0)
lcd.printString(output, 5, 1)
sleep(.25)
lcd.printString(16*" ",0,0)
lcd.printString(16*" ",0,1)
elif key == "SEL":
while loop_menu == 1:
displaymenu()
key = getKey()
if key == "RIGHT":
os.system("mpc volume +10")
lcd.printString(16*" ", 0, 0)
lcd.printString(16*" ", 0, 1)
output = run_cmd("mpc volume")
lcd.printString("VOLUME UP:", 0, 0)
lcd.printString(output, 5, 1)
sleep(.25)
lcd.printString(16*" ",0,0)
lcd.printString(16*" ",0,1)
elif key == "LEFT":
os.system("mpc volume -10")
lcd.printString(16*" ",0,0)
lcd.printString(16*" ", 0,1)
output = run_cmd("mpc volume")
lcd.printString("VOLUME DOWN:", 0, 0)
lcd.printString(output, 5, 1)
sleep(.25)
lcd.printString(16*" ",0,0)
lcd.printString(16*" ",0,1)
elif key == "UP":
if x <= 1:
x = 7
else:
x = x - 1
elif key == "DOWN":
if x >= 7:
x = 1
else:
x = x + 1
elif key == "SEL":
if x == 1:
display_ipaddr()
sleep(1)
elif x == 2:
output = run_cmd("amixer -q cset numid=3 2")
lcd.printString("Audio OUT-->HDMI", 0, 0)
lcd.printString("output ", 0, 1)
sleep(.5)
elif x == 3:
output = run_cmd("amixer -q cset numid=3 1")
lcd.printString("Audio OUT->Analog", 0, 0)
lcd.printString("output ", 0, 1)
sleep(.5)
elif x == 4:
output = run_cmd("amixer -q cset numid=3 0")
lcd.printString("Audio OUT-> Auto", 0, 0)
lcd.printString("output ", 0, 1)
sleep(.5)
elif x == 5:
load_playlist()
os.system('mpc play 1')
elif x == 6:
lcd.printString("Good Bye ", 0, 0)
lcd.printString("Have a Nice Day ", 0, 1)
output = run_cmd("mpc stop")
# = run_cmd("sudo shutdown now")
quit()
elif x == 7:
loop_menu = 0
getTrack()
break
elif key == "RIGHT":
os.system("mpc volume +2")
lcd.printString(16*" ",0,0)
lcd.printString(16*" ", 0,1)
output = run_cmd("mpc volume")
lcd.printString("VOLUME UP:", 0, 0)
lcd.printString(output, 5, 1)
sleep(.25)
lcd.printString(16*" ",0,0)
lcd.printString(16*" ",0,1)
elif key == "LEFT":
os.system("mpc volume -2")
lcd.printString(16*" ", 0, 0)
lcd.printString(16*" ", 0, 1)
output = run_cmd("mpc volume")
lcd.printString("VOLUME DOWN:", 0, 0)
lcd.printString(output, 5, 1)
sleep(.25)
lcd.printString(16*" ",0,0)
lcd.printString(16*" ",0,1)
radio_playlist.sh
Ceci est ma playlist avec des stations israéliennes
#! /bin/sh
mpc clear 1>/dev/null
#1 ecco99
mpc add https://99.livecdn.biz/99fm_aac
#2 galgalaz
mpc add https://glglzwizzlv.bynetcdn.com/glglz_mp3
#3 galaz
mpc add https://glzwizzlv.bynetcdn.com/glz_mp3
#4 88 fm
mpc add https://ibala.vidnt.com:8000/iba_radio-88fmM
#5 gimel
mpc add https://ibala.vidnt.com:8000/iba_radio-gimelM
#6 radios 100 fm
mpc add https://100fm.streamgates.net/Radios100Fm
#7 kol hamusica
mpc add https://ibala.vidnt.com:8000/iba_radio-kolmusicaM
#8 wqxr
mpc add https://stream.wqxr.org/wqxr
#9 npr current
mpc add https://current.stream.publicradio.org/kcmp.mp3
#10 bbc
mpc add https://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-eieuk
#11 linn jazz
mpc add https://radio.linnrecords.com:8003/autodj
#12 linn classical
mpc add https://radio.linnrecords.com:8004/autodj
Schémas
Processus de fabrication
- Construire une télécommande universelle Raspberry Pi professionnelle avec LIRC
- Conversion RF vers DC avec Raspberry Pi : Construction et dépannage d'un détecteur d'enveloppe
- Cycle Chaser : Transformer votre vélo en spectacle lumineux nocturne avec Raspberry Pi
- Construire un détecteur de voleur basé sur Raspberry Pi – Guide étape par étape
- Construire un moniteur de température domestique avec Raspberry Pi, MCP9808, InfluxDB et Grafana
- Construire un système domotique piloté par Raspberry Pi pour contrôle à distance
- MrRobot : Robot Rapiro piloté par mobile Ubuntu avec interaction voix, toucher et secousse
- Robot DIY inspiré de Wall‑E : Raspberry Pi dans une boîte de CD recyclée
- Construire un robot Raspberry Pi piloté par Bluetooth avec retour audio