Pi Zero è una piccola scheda – parte della famiglia Raspberry – pensata per applicazioni embedded. Il suo bassissimo costo (circa 10€ per la versione W, con connettività wifi) e la capacità di eseguire diversi sistemi operativi la rende la scelta ideale per diverse applicazioni (media center, datalogger…).
La scheda Pi Zero purtroppo non offre un connettore audio dedicato: normalmente infatti l’output audio avviene tramite il connettore HDMI:
Sebbene tale scelta vada benissimo per utilizzi quali media center (audio e video sono riprodotti dal televisore collegato via HDMI), non è comoda per applicazioni embedded che hanno la necessità di riprodurre solo file audio (ad esempio per una voce guida…). Anche se esistono dei dispositivi in grado di estrarre il flusso audio dallo stream HDMI, tali dispositivi sono spesso costosi e di grandi dimensioni.
Una soluzione molto semplice, spiegata benissimo in un tutorial di Adafruit, è quella di generare il segnale audio utilizzando due pin PWM (Pulse Width Modulation) e un filtro passa-basso realizzato con alcuni componenti passivi. Questa soluzione ha il vantaggio di essere economica e di facile realizzazione; di contro la qualità dell’audio prodotto non è elevatissima.
Nel tutorial di oggi voglio invece mostrarvi come ottenere un segnale audio di alta qualità utilizzando il bus I2S.
I2S
I2S è un bus seriale per collegare diversi dispositivi audio tra loro e trasferire, in formato digitale, dei flussi audio.
Le specifiche di tale bus sono state definite da Philips nel 1986. Il bus è formato da almeno 3 linee:
- clock (indicato come SCK – serial clock o anche come BCLK – bit clock)
- word select (WS, a volte definito anche LRCLK – left/right clock)
- serial data (SD, o anche SDATA…)
Possiamo sfruttare il bus I2S per far comunicare il nostro Pi Zero con un amplificatore che accetti in ingresso un segnale digitale su tale bus:
Cosa serve
Ho scelto di utilizzare un amplificatore I2S basato sul chip MAX98357 di Maxim. Questo chip offre in uscita 3.2W e consente di collegare direttamente un piccolo altoparlante da 4 ohm. Sia la breakout board con il chip Maxim sia l’altoparlante sono di Adafruit:
Ho acquistato entrambi da un rivenditore italiano, melopero:
La breakout board viene venduta con una morsettiera a due contatti (per il collegamento con l’altoparlante) e con una serie di pin per alimentazione e bus I2S; entrambi da saldare alla scheda:
L’altoparlante viene venduto con un connettore JST che ho eliminato per poterlo collegare alla morsettiera:
Collegamenti e configurazione
Il collegamento tra Raspberry e la scheda con l’amplificatore MAX98357 richiede 5 fili:
[checklist]
- 5V Raspberry -> Vin
- GND Raspberry -> GND
- PIN18 Raspberry -> BCLK
- PIN19 Raspberry -> LRC
- PIN21 Raspberry -> DIN
[/checklist]
Ecco un paio di fotografie che illustrano i collegamenti indicati sopra
Procediamo ora alla configurazione software, partendo da una versione recente della distribuzione Raspbian.
Apriamo con un editor di testo (ad esempio nano) il file /boot/config.txt
sudo nano /boot/config.txt
commentiamo (aggiungendo un # ad inizio riga) la voce dtparam=audio=on e inseriamo due nuove voci – dtoverlay=hifiberry-dac e dtoverlay=i2s-mmap:
creiamo quindi il nuovo file /etc/asound.conf
sudo nano /etc/asound.conf
e inseriamo il contenuto mostrato nello screenshot seguente:
Come ultimo passo, riavviamo il nostro Raspberry.
Test e mps-youtube
Proviamo a riprodurre un file audio di esempio con il comando:
speaker-test -c2 --test=wav -w /usr/share/sounds/alsa/Front_Center.wav
Se configurazione e collegamenti sono ok, dovremmo sentire una voce pronunciare “front – center” in loop; possiamo terminare la riproduzione con CTRL-C.
Per poter riprodurre dei files mp3, abbiamo bisogno di un player. Ho scelto di utilizzare mpv:
sudo apt-get install mpv
Risentiamo la frase storica di Neil Armstrong – One small step for men, one giant leap for mainking – direttamente dal sito della Nasa:
mpv http://www.nasa.gov/mp3/590331main_ringtone_smallStep.mp3
Vi voglio mostrare infine l’utilizzo di un programma, mps-youtube, che consente di riprodurre tracce audio da Youtube tramite una interfaccia a riga di comando. Essendo scritto in Python3, dobbiamo installare questa versione e uno dei suoi package manager, pip:
sudo apt-get install python3 python3-pip
Possiamo quindi installare mps-youtube e le sue dipendenze con:
sudo pip3 install youtube-dl mps-youtube
Eseguiamo il programma con mpsyt. Per prima cosa dobbiamo indicare il player che vogliamo utilizzare (mpv):
Quindi possiamo cercare un video, digitando la stringa di ricerca preceduta da /. In alternativa se già conosciamo l’URL di un video, possiamo riprodurlo con il comando playurl <url>:
Disturbi nel cambio traccia
E’ possibile che nel cambio traccia o comunque all’inizio di una nuova riproduzione sentiate dei disturbi. Il motivo è ben spiegato in questo thread del forum di Adafruit (thread al quale anch’io ho contribuito): tutto è causato dal cambio di frequenza del segnale di clock del bus I2S.
Il modo più semplice per risolvere è riprodurre continuamente un segnale a frequenza fissa (es. 48KHz) di completo silenzio:
aplay -t raw -r 48000 -c 2 -f S16_LE /dev/zero &
Lanciate il comando sopra prima di eseguire mpv o qualsiasi altro player e vedrete che i disturbi scompariranno!
Demo
Ecco un filmato che mostra mps-youtube all’opera (è in lingua inglese ma sono disponibili i sottotitoli in italiano):
I have been trying to do the same thing with the Raspberry pi 3 B with the April release and Jessie interface. Have you tried the RPi 3? I went through the Adafruit tutorial and I have all the commands correct. On Jessie I’m getting a red X and when I go into the audio settings I get that an ALSA device is not available. Any ideas would be appreciated.
Hi Darren, unfortunately I don’t own a Pi3 so I cannot test it…
Hi Luca, Thanks for the nice demo and the instructions. I followed them and everything worked nicely except volume. The sound is very, very low and not adjustable with alsamixer. I’m running the rpi-z headless, so that’s all I’ve got. Have you encountered this before? When I run AlsaMixer it says “This sound device does not have any controls”
Hi Dan! Unfortunately no, I did’t find any problems related to volume control… but I found on the official Raspi forum this thread that may help… let me know if it solves your problem!
Hi Luca,
I have the same problem as Dan Powell has. All setting went OK, but the sound is indead very, very low. Get also the same text “This sound device does not have any controls” Tried the volume control setting from the thread you posted, but didn’t get it to work. Do you have some other thoughts what to try?
running on py zero.
Just to add:
I got the alsamixer back working. Look on this page https://learn.adafruit.com/adafruit-speaker-bonnet-for-raspberry-pi?view=all#raspberry-pi-test.
I got it in sync and it works. But still the audio is very, very low. Put it on 100% whit alsamixer. The ITEM in alsamixer is now PCM, i don’t see the gain.
Ciao, giusto per capire, l’amplificatore che usi, l'”Adafruit I2S 3W Class D Amplifier Breakout – MAX98357A” può gestire solo piccole casse o il segnale emesso può essere utilizzato come segnale di linea per pilotare anche casse attive (con amplificatore integrato) o indirizzato verso un impianto di amplificazione?
ciao, è possibile collegare il suo output a casse attive o amplificatori esterni
ciao Luca grazie per il tutorial, sono + o – riuscito ad assemblare questo prototipo sulla base di un modello adafruit
https://drive.google.com/file/d/1gozgOLMnTxU7ViXapGLShEmLIAFW4kRq/view?usp=sharing
ho seguito il tuo tutorial, ma non sentivo niente, purtroppo ho solamente i pin liberi che vedi , non ho potuto utilizzare quelli del tuo schema, ho provato anche la guida :
https://learn.adafruit.com/adafruit-max98357-i2s-class-d-mono-amp/raspberry-pi-wiring
sembra abbia installato il tutto dandomi esito positivo, ma non sento niente.
non so veramente cosa fare ? si possono usare i pin che ho messo io? esiste uno script autoconfigurante? Sono disposto a pagare se possibile configurarlo a distanza.
grazie
Alessio
Ciao Luca , la famosa frase non era “One small step for men, one giant leap for mainking” bensì’ “That’s one small step for a man, one giant leap for mankind.”.
Per il resto , complimenti per il sito , i tutorial e gli articoli.
grazie mille per la precisazione!