Ricostruiamo l’antichissimo strumento musicale in versione ultra-tecnologica, dove al posto delle corde abbiamo messo dei raggi laser, interrompendo i quali con il passaggio delle dita si producono le note.
L’arpa è uno strumento a corda dal suono tenue, armonioso e rilassante, che ha radici nella storia più remota risalente alle civiltà dei greci e dei latini e forse ancor prima; la ritroviamo anche oggi nelle orchestre sinfoniche ed anche in concerti di musica da camera.
Come tutti gli strumenti a corda, produce il suono pizzicando o tendendo e rilasciando un certo numero di corde con le dita, mantenute in tensione dal telaio in cui sono montate: un telaio normalmente in legno, dalla forma caratteristica quasi triangolare.
Senza nulla eccepire allo strumento classico, abbiamo pensato di rivisitarne la struttura andando a sostituire le corde con qualcosa di futuristico, perché parliamo di raggi laser; è nata così la nostra Arpa Laser, che è uno strumento musicale elettronico e altamente tecnologico, nella cui progettazione abbiamo, per così dire, “tirato dentro” l’immancabile Arduino e il suo seguito di hardware, oltre a un pizzico di fantasia per mettere insieme il telaio, ottenuto da un insieme di particolari in plexiglass opportunamente assemblati.
Per dare un tocco scenografico abbiamo inoltre previsto la possibilità di pilotare, quando l’arpa è in funzione, una macchina del fumo che faccia risaltare i raggi laser rossi, dando corpo e consistenza alle corde e facendole sembrare solide come quelle dell’arpa tradizionale.
Il progetto dell’Arpa Laser
Passiamo subito a vedere come è composto il nostro tecno-strumento, iniziando dall’elettronica; quest’ultima è composta da una board Arduino UNO rev.3 che si interfaccia a un gruppo di sensori a laser utilizzati per capire quando ne interrompiamo il raggio.
Spiegheremo tra poco come funziona il sistema e perché un laser può trasformarsi in una corda virtuale di un’arpa elettronica.
Oltre ad Arduino e alle corde laser, abbiamo uno shield MIDI, che è il generatore di suoni vero e proprio; eh, già, perché l’arpa deve suonare e quindi deve poter generare dei suoni, perciò nel nostro progetto:
• i sensori laser costituiscono i dispositivi di input, ossia di trigger;
• lo shield MIDI genera i suoni richiesti quando riceve il trigger.
In mezzo c’è Arduino, il cui compito è triplice:
• acquisisce gli eventi di trigger dai dispositivi di input, vale a dire i sensori laser;
• sulla base di questi indirizza e comanda lo shield MIDI affinché produca i suoni richiesti;
• attiva la macchina del fumo (opzionale).
Lo shield MIDI produce i suoni disponibili su un connettore jack (per un eventuale amplificatore esterno) e in altoparlante, perché, come spiegheremo tra breve analizzandone lo schema elettrico, a bordo abbiamo messo un amplificatore audio stereo 2×3 watt – codice PAM8403POT.
Ma partiamo spiegando in cosa consistono le corde virtuali, implementate da 10 sensori di passaggio a laser, ognuno dei quali è un dispositivo LASERSENSOR della Futura Elettronica.
Il sensore a laser
Il dispositivo, già descritto nel fascicolo n° 209 di Elettronica In (il progetto era la Barriera a laser), ci permette di rilevare il passaggi delle dita perché funziona rilevando la presenza e l’attraversamento di un oggetto grazie alla combinazione di un diodo laser che emette un raggio di luce e di un fototransistor che rileva quella riflessa (Fig. 1).
Si tratta di una barriera a laser, ma non di tipo a interruzione, dove l’oggetto da rilevare non deve passare tra un emettitore e un fotorivelatore, bensì a riflessione: nel nostro circuito, un laser proietta un raggio di luce concentrata e collimata all’infinito e un oggetto che vi passa davanti ne riflette una porzione, che ritornando viene intercettata da una lente convergente e concentrata sulla superficie sensibile di un componente fotosensibile.
Questo genere di dispositivo presenta il vantaggio di non richiedere il posizionamento a distanza di un sensore, con l’inevitabile cablaggio richiesto, ma di concentrare tutta in un punto l’elettronica richiesta, risultando così l’ideale per sistemi mobili come i robot su ruote o cingoli, ma anche per simulare la corda di uno strumento musicale, che non vibra ma semplicemente rivela il contatto. Così è nella nostra tecno-arpa.
La distanza di rilevamento tipica è di 80 cm ma si può arrivare a un massimo di 1,5 metri ed anche questo fattore ha giocato a favore della realizzazione dell’arpa, perché ci ha permesso di realizzare un telaio abbastanza grande da somigliare a un’arpa vera; la distanza di rilevamento dipende comunque da quanta luce riflette la superficie del corpo da rilevare, ossia da quello che passiamo tra le corde.
Il circuito elettronico impiega un laser come trasmettitore e un modulo optoelettronico basato su fototransistor come ricevitore. Il fascio emesso dal trasmettitore si riflette sulla superficie posta di fronte e colpisce la lente (che serve a concentrare la luce riflessa sul fototransistor) del ricevitore, mandando in conduzione il fototransistor. Il ricevitore rileva solo la luce rossa riflessa ed emessa dal diodo laser, aggirando i disturbi da altre fonti luminose.
Il diodo laser è un piccolo puntatore (cioè un componente che integra un diodo laser raffreddato dall’apposito involucro in alluminio, un regolatore di corrente e una lente collimatrice); il laser viene alimentato attraverso un transistor pilotato da un segnale rettangolare a 180 kHz.
Gli impulsi di luce vengono inviati frontalmente e quando colpiscono un oggetto la cui superficie ne riflette almeno una parte, tornano al circuito, dove parte di essi investe la lente del fototransistor, che li fa convergere sulla giunzione esposta.
Quando il fototransistor viene colpito dalla luce l’uscita DOUT (pin 3) della scheda commuta da 0 a 1 logico, mentre lo stesso contatto, in assenza di luce, assume lo 0 logico. Tale linea viene letta da Arduino per rilevare la presenza del dito o della mano sulla corda virtuale. Il LED rosso presente sulla scheda ripete, invertito, lo stato dell’uscita omonima.
Notate adesso che la scelta di pilotare il diodo laser con una forma d’onda rettangolare invece che con un segnale continuo, nasce dalla necessità di immunizzare nei confronti dei disturbi e della luce nell’ambiente il funzionamento del sensore: infatti se il laser fosse acceso costantemente, DOUT presenterebbe (in caso di luce che arriva sul fototransistor dopo essere stata riflessa) una tensione influenzabile dalla luce ambiente, dato che il fototransistor potrebbe andare in conduzione costantemente se venisse illuminato a sufficienza o colpito da altre radiazioni luminose comprese nel suo spettro di sensibilità.
Invece emettendo degli impulsi luminosi a una certa frequenza possiamo, adottando un modulo ricevitore dotato di filtro, fare in modo che rilevi solo essi, scartando componenti luminose continue.
Il circuito del sensore laser si alimenta con una tensione che può essere compresa fra 2,5 e 12 Vcc, grazie alla presenza di un regolatore switching integrato basato sull’integrato PT1301.
Schema di cablaggio
Lo shield MIDI
Passiamo adesso al cuore dello strumento musicale, che è uno shield basato sull’integrato VS1053B della VLSI, già utilizzato in altri progetti in passato e capace di generare un certo numero di note musicali sintetizzando i suoni di una gran quantità di strumenti musicali sia melodici (tra cui l’arpa e l’organo) sia a percussione, dietro comandi impartiti da un canale dati; i comandi accettati possono essere di vari formati, compreso il popolare MIDI, che è lo standard utilizzato da decenni per interfacciare al PC sintetizzatori musicali e tastiere elettroniche.
Partiamo analizzando lo schema elettrico del circuito, che trovate in queste pagine.
Il tutto ruota intorno all’integrato U1, che è il nostro VS1053B; quest’ultimo è insieme un CODEC/decoder multistandard (contiene codici e memoria dati per i codec Ogg Vorbis, MP3, AAC, WMA e WAV PCM+ADPCM audio decoding) ed un completo sintetizzatore MIDI standard. Grazie a plug-in software, il chip può anche realizzare la decodifica lossless FLAC bene come quella di una registrazione high-quality in formato Ogg Vorbis.
Il tutto si avvale, per la comunicazione con il dispositivo host (il microcontrollore che governa il sintetizzatore) di un’interfaccia seriale, configurabile anche in modalità SPI-bus. In realtà il VS1053B integra un complesso di interfaccia seriale che conta due interfacce: una di controllo (SCI=Serial Command Interface) che serve per comandare il funzionamento del chip e che nel nostro caso è quella attraverso la quale Arduino (ma potrebbe farlo qualsiasi microcontrollore…) impartisce i propri comandi ed una di trasferimento dati (SDI=Serial Data Interface) grazie alla quale il VS1053B può trasferire o acquisire streaming di dati a un altro dispositivo esterno o da esso.
Delle due, quella configurabile per funzionare in modalità seriale TTL (Fig. 2) o SPI è la SCI, cioè l’interfaccia di controllo.
Il sintetizzatore di suoni integrato è basato su un DSP (Digital Signal Processor) proprietario VLSI, chiamato il VS_DSP. I suoni sintetizzati vengono convertiti da un DAC stereo multi-rate, alla cui uscita si trova uno stadio preamplificatore audio e filtro d’uscita stereo.

Fig. 2 Il relè a comando TTL.
L’integrato supporta anche la codifica audio PCM/ADPCM, utilizzando come stadio d’ingresso un amplificatore microfonico (per chi desidera utilizzare un microfono) o prelevando il segnale da un ingresso di linea e inviandolo a un A/D converter stereo. Nello schema vediamo che Arduino gestisce il VS1053B attraverso la porta seriale utilizzata come UART, che nell’U1 fa capo ai pin 26 (RX) e 27 (TX) connessi rispettivamente ai pin digitali D3 e D2 di Arduino; quest’ultima gestisce anche il reset dell’U1, tramite D4, così da predisporlo a ricevere i comandi.
Le tre linee in questione sono dotate di pull-up sul lato del VS1053 e vengono comandate dai pin di Arduino tramite resistori in serie; tre jumper (JRX, JTX e JRST) sul circuito stampato dello shield consentono di sconnetterle all’occorrenza, per esempio se si opta per una differente forma di controllo, come ad esempio la SPI.
In ogni caso le linee sono tre anche per consentire l’interfacciamento su SPI, giacché una fa da canale dati, una da reset e l’altra da clock; basta scrivere opportunamente il firmware.
Lo shield prende alimentazione da Arduino attraverso il pin 5V e la GND; con i 5 volt funziona il modulo amplificatore PAM8043, mentre al resto provvedono i regolatori lineari LDO U2 (MIC5504-1.8YM5-TR) ed U3: quest’ultimo (è un MIC5504-3.3YM5-TR) ricava, partendo dai 5 volt prelevati da Arduino, una tensione di 3,3 volt con cui alimentare i piedini dell’alimentazione analogica del VS1053 (AVDD1, AVDD2 e AVDD3) e U2, il quale dai 3,3V ricava gli 1,8V che occorrono al funzionamento del core dell’U1, sui piedini CVDD (core VDD) e IOV1, IOV2, IOV3. I condensatori sulle linee di alimentazione filtrano le relative tensioni da disturbi ed eventuale ripple.
L’integrato VS1053B dispone di un’uscita audio stereo localizzata sui pin 39 (canale R) e 46 (canale L) riferiti al comune pin 42 (GBUF) che non è collegato alla massa analogica, ma anch’esso accoppiato, come le linee di segnale, tramite reti R/C.
Le uscite dell’U1 audio raggiungono una presa jack stereo da circuito stampato cui è possibile collegare una cuffia, giacché le stesse fanno capo a un amplificatore BF di piccola potenza con uscite a bassa impedenza.
Le stesse linee R ed L raggiungono gli input del modulo amplificatore U4, che eleva il livello del segnale quanto basta a pilotare una coppia di altoparlanti da 3 watt e 4 ohm d’impedenza ciascuno; il modulo U4 è il PAM8403, basato sull’omonimo integrato già dotato di tutti i componenti esterni di cui necessita e del potenziometro per il controllo del volume.
L’integrato VS1053B funziona sincronizzato dal proprio oscillatore interno, che per la temporizzazione si basa sul quarzo da 12,88 MHz collegato tra i piedini 17 (X1) e 18 (X2).
Nello schema, notate il pulsante RST, collegato alla linea di reset degli header è utile a replicare quello di Arduino quando la board viene coperta dallo shield.
Schema elettrico
Piano di montaggio
Elenco componenti
R1: 1 Mohm (0603) R2÷R5: 100 kohm (0603) R6, R7: 22 ohm (0603) R8: 1 kohm (0603) R9: 22 ohm (0603) R10÷R12: 100 kohm (0603) R13, R14:1 kohm (0603) C1÷C5: 100 nF ceramico (0603) C6: 100 µF 6,3 VL elettrolitico (Ø 4mm) C7, C8: 22 pF ceramico (0603) C9: 1 µF ceramico (0603) C10, C11: 10 nF ceramico (0603) C12: 47 nF ceramico (0603) C13: 100 µF 6,3 VL elettrolitico (Ø 4mm) RST: Microswitch U1: VS1053B U2: MIC5504-1.8YM5-TR U3: MIC5504-3.3YM5-TR U4: Modulo amplificatore PAM8403 SPK: Presa Jack 3.5mm Q1: Quarzo 12.288 MHz Varie: - Morsetto 2 vie passo 5mm (2 pz.) - Pin Strip Arduino 6 vie - Pin Strip Arduino 8 vie (2 pz.) - Pin Strip Arduino 10 vie - Pin Strip Arduino 2x3 vie - Circuito stampato S1414 (69x55 mm)
Come funziona
Vediamo adesso come funziona l’insieme, premettendo che ad ogni sensore laser corrisponde una nota suonata e che i sensori vengono letti ciascuno da una linea di Arduino, secondo queste impostazioni:
pinMode(smoke, OUTPUT);
pinMode(6, INPUT);
pinMode(5, INPUT);
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
pinMode(13, INPUT);
pinMode(A5, INPUT);
pinMode(A4, INPUT);
I pin A4 e A5 di Arduino, pur essendo nativamente analogici, li abbiamo assegnati come digitali, essendoci questa possibilità e non avendo, altrimenti, abbastanza pin digitali.
Il pin smoke (pin 7 di Arduino) è l’unico impostato come uscita, dovendo attivare il relè della macchina del fumo. La prima nota in ordine di frequenza e quindi, se ci trovassimo sulla tastiera di un pianoforte, partendo da sinistra, è quella correlata con il pin digitale 6 e la più acuta è quella relativa all’input analogico 4.
Quindi la sequenza delle note eseguibili è Fa#, Sol, Sol#, La, La#, Si, Do, Do#, Re e Re# dell’ottava superiore; se volete conoscere la corrispondenza con tutte le note eseguibili dal sintetizzatore integrato nel VS1053B consultate la Tabella 1.

Tabella 1 Le note generate dal sintetizzatore integrato nel VS1053B.
Ogni volta che Arduino rileva il livello logico alto su una delle predette linee, costruisce la stringa di comando seriale del sintetizzatore contenuto nel VS1053B e la invia all’integrato, il quale produce la nota desiderata, con il registro (strumento) impostato nel comando stesso; nel nostro caso il registro è fissato nello sketch ed è lo stesso per tutte e 10 le note.
Lo strumento riprodotto è il 9 del banco GM1 (Celesta) come si evince dalla Tabella 2.

Tabella 2 I registri del banco di strumenti GM1 (strumenti melodici).
Per quanto riguarda la macchina del fumo, ne abbiamo modificata una di quelle reperibili dalla Futura Elettronica (cod. HQSM10001) collegando in parallelo al pulsante di comando del getto di fumo lo scambio di un relè su breakout board, pilotato dal pin 7 digitale di Arduino. L’uscita si attiva (porta a livello logico alto) per 400 ms e poi viene inibita per 10 secondi, in modo da evitare di saturare l’ambiente nel caso si suonino note continuativamente.
I tempi possono essere cambiati a piacimento dallo sketch. Il modulo relé è del tipo ad 1 canale con comando TTL ed è il RELAY1CH della Futura Elettronica.
Lo schema di cablaggio mostrato in queste pagine spiega bene come si devono interconnettere gli elementi del circuito.
Per quanto riguarda il formato dei comandi diretti da Arduino al VS1053B, la stringa di impostazione del sintetizzatore è di questo tipo:
• 0x51: set tempo
• 0x01: master volume
• 0x80: note off
• 0x90: note on
• 0xc0: program
• 0xe0: pitch wheel
• 0xb0: parameter channel message
• 0x00: bank select (0 is default, 0x78 and 0x7f is drums, 0x79 melodic)
• 0x06: RPN MSB: 0 = bend range,
2 = coarse tune
• 0x07: channel volume
• 0x0a: pan control
• 0x0b: expression (changes volume)
• 0x0c: effect control 1 (sets global reverb decay)
• 0x26: RPN LSB: 0 = bend range
• 0x40: hold1
• 0x42: sustenuto
• 0x5b effects level (channel reverb level)
• 0x62,0x63,0x64,0x65: NRPN and RPN selects
• 0x78: all sound off
• 0x79: reset all controllers
• 0x7b, 0x7c, 0x7d: all notes off
I parametri permettono di stabilire il funzionamento del sintetizzatore, vale a dire lo strumento (registro) da suonare e di quale banco, l’eventuale applicazione di effetti come il sustain, il range del pitch bend se utilizzato, ecc.
Infine vale la pena di evidenziare una particolarità del VS1053B, riguardante lo stadio di uscita per la cuffia, nel quale è implementata una parametrizzazione dell’elaborazione audio in quattro modalità selezionabili; il tutto allo scopo di restituire la spazialità che nell’ascolto in cuffia tipicamente non si ottiene.
Le quattro modalità applicabili sono:
• Off: nessuna correzione della spazialità, utile se si ascolta l’audio in altoparlante, giacché il suono nello spazio circostante acquisisce spazialità di suo; tale modalità si applica anche nell’ascolto in cuffia se l’audio che deve essere riprodotto deriva non dal sintetizzatore ma dal decoder e contiene già una preprocessing binaurale;
• minimal: pensato per l’ascolto in cuffia di brani caratterizzati da pochi strumenti e da una minima correzione spaziale;
• normal: adatta all’ascolto di brani in cuffia spostando la sorgente audio percepita in maniera minima da un padiglione all’altro;
• extreme: adatta alla riproduzione di registrazioni vecchie o asciutte, oppure quando l’audio riprodotto è quello generato dal sintetizzatore MIDI.
Il firmware dell’Arpa Laser
Codice per Arpa Laser
Bene, completiamo la descrizione dell’arpa laser con l’analisi del firmware; di esso, nel Listato 1 riportiamo la parte di sketch che associa le note alle “corde” toccate.
Listato 1
void readTouchInputs()
{
touchStates[1]= !digitalRead(6);
touchStates[2]= !digitalRead(5);
touchStates[3]= !digitalRead(8);
touchStates[4]= !digitalRead(9);
touchStates[5]= !digitalRead(10);
touchStates[6]= !digitalRead(11);
touchStates[7]= !digitalRead(12);
touchStates[8]= !digitalRead(13);
touchStates[9]= !digitalRead(A5);
touchStates[10]=!digitalRead(A4);
for (int i=1; i<10; i++)
{
Serial.print(touchStates[i]);
}
Serial.println();
}
void Play()
{
int note=30;
for (int i=1; i<10; i++)
{
if ((touchStates[i]==1) && (touchPres[i]==false))
{
noteOn(0, note, 127);
touchPres[i]=true;
//ho premuto una corda
if (fumoinib==0){
timefumoon=millis();
fumoinib=1;
}
}
if ((touchStates[i]==0) && (touchPres[i]==true))
{
noteOff(0, note, 127);
touchPres[i]=false;
}
note++;
}
delay(100);
}
Dopo l’assegnazione dei pin di I/O, si imposta lo strumento desiderato con l’istruzione:
const int STRUMENTO1=9;
Chi volesse potrà modificare lo strumento intervenendo in questa area del codice. Abbiamo poi la porzione di sketch che riguarda l’impostazione della comunicazione seriale per il controllo da parte di Arduino dove potete notare che la velocità di comunicazione è impostata in 31.250 bps:
#if USE_SERIAL_MIDI
midiSerial.begin(31250);
#endif
E veniamo alla parte dello sketch riguardante il comando finalizzato alla generazione delle note, che è la seguente:
void talkMIDI(byte cmd, byte data1, byte data2) {
#if USE_SPI_MIDI
// Wait for chip to be ready
while (!digitalRead(VS_DREQ))
;
digitalWrite(VS_XDCS, LOW);
#endif
sendMIDI(cmd);
//Some commands only have one data byte.
if( (cmd & 0xF0) <= 0xB0 || (cmd & 0xF0) >= 0xE0) {
sendMIDI(data1);
sendMIDI(data2);
} else {
sendMIDI(data1);
}
#if USE_SPI_MIDI
digitalWrite(VS_XDCS, HIGH);
#endif
}
//Send a MIDI note-on message.
//Like pressing a piano key
//channel ranges from 0-15
void noteOn(byte channel, byte note,
byte attack_velocity) {
talkMIDI( (0x90 | channel), note, attack_velocity);
}
//Send a MIDI note-off message.
//Like releasing a piano key
void noteOff(byte channel, byte note,
byte release_velocity) {
talkMIDI( (0x80 | channel), note, release_velocity);
}
I comandi, come vedete, impostano la nota, il registro, il tempo, le modalità di attack e decay (progressione del suono e decadimento) e via di seguito, inviando poi al MIDI la stringa di comando corrispondente.
Per quanto riguarda il comando della macchina del fumo, i parametri sono i seguenti:
unsigned long timefumoon=0;
int timespruzzo=400;
int timefumoinib=10000;
boolean fumoinib=0;
unsigned long timestartinib=0;
Qui vediamo che il comando al relé che chiuderà in cortocircuito il pulsante di comando della macchina dura 0,4 secondi, cui seguirà un tempo di inibizione di 10 secondi (tutti i tempi sono espressi in millisecondi).
La parte di codice contenuta nel Listato 1 vede la funzione void readTouchInputs() con le variabili associate ai 10 sensori: quando una touchStates passa da 0 a 1 si avvia un ciclo for che produce la stampa su seriale della nota suonata, ai fini di debug.
Segue la funzione void Play() in cui un ciclo for esegue la nota associata a touchStates, a partire dalla 30, che è la più grave; per ogni touchStates che cambia di stato si somma 1 nota, quindi se a commutare è touchStates[5] il parametro note vale 30+4, quindi viene eseguita la nota 34. Insieme all’esecuzione della nota parte l’attivazione della macchina del fumo.
Naturalmente chi se la sente può modificare i vari parametri in modo da disattivare il comando della macchina del fumo (basta mettere a zero int timespruzzo) personalizzare le note e, volendo, modificare il suono dello strumento.
Bene, ciò detto abbiamo concluso: non ci resta che augurarvi buon lavoro e soprattutto buon divertimento con la vostra arpa digitale con la quale stupirete chi vedrà suonarla.







