Controller radio per effetti sonori - Ricevitore

Una volta costruito il trasmettitore, occorre costruire il ricevitore che decodifichi il segnale radio e inoltri il comando al PC. Per prima cosa, dovendosi collegare al PC, bisogna scegliere quale porta usare per connettere il dispositivo:

  • Scartiamo subito la parallela LPT a 25 pin perchè neanche i computer più vecchi in circolazione la hanno ancora;
  • La più diffusa per questo genere di cose è la porta seriale a 9 pin, ma è vecchia anche lei, e a parte il fatto che i computer non la hanno più e occorrerebbe un (costoso) convertitore USB-seriale, non mi piace fare le cose obsolete sul nascere;
  • La porta USB sembra perfetta! E' molto veloce, presente ovunque, fornisce anche alimentazione eliminando la necessità di trasformatori o batterie. L'unico problema è la difficoltà di utilizzo, ma basta documentarsi un po' e fare un po' di pratica senza scoraggiarsi.

Il ricevitore è inserito in una piccola scatola di plastica nera reperita su ebay al cui interno sono alloggiati:

  • Un PIC18F2550, microcontrollore a 28 pin dotato di modulo USB, il "cervello" dell'intero circuito;
  • Radio ricevitore Qam-rx2 operante a 433.92 MHz (notare che anche in questo caso la sigla Qam è la sigla del produttore Quasar seguita dal tipo di modulazione AM, non indica il tipo di modulazione di ampiezza/fase QAM);
  • Un comparatore rapido LM311 utilizzato nel modo descritto in precedenza per la ricezione del segnale radio assieme al rivelatore a diodo.

Schema elettrico

Prima di spiegarvi uno per uno i componenti di questo circuito ritengo opportuno fornirvi lo schema elettrico completo:

(clicca sull'immagine per vederla più grande)

(Errata corrige: non posso modificare subito lo schema, per cui correggo testualmente: al rivelatore d'inviluppo non va il pin 7 del 311 ma il pin 6, il pin 7 va in realtà a massa).

Innanzitutto, si nota la presenza del connettore USB in basso, i cui pin di dati D+ e D- sono connessi al PIC e da cui preleviamo anche l'alimentazione (ho predisposto un jumper per poter eventualmente utilizzare un alimentatore esterno).

Sul PIC non c'è molto da dire, il clock viene fornito da un quarzo da 12 MHz (il PLL 4x interno lo porta a 48 MHz, necessari per la porta USB) con i due condensatori da 22 pF annessi. Il condensatore sul pin denominato Vusb è indispensabile per il corretto funzionamento del modulo USB, anche se il valore non è critico.

In alto a destra è presente il ricevitore radio, con i due pin di uscita TEST e OUT. TEST è il pin di output digitale (uscita del comparatore) di cui abbiamo già parlato, mentre OUT è il pin di uscita del segnale rigenerato. Da questo pin (ignorate il jumper, era lì per dei test che ho condotto sul modulo) preleviamo il segnale che mandiamo all'ingresso del comparatore LM311 (la resistenza R6 è stata inserita perchè ho sperimentalmente osservato che veniva utile).
Il 311 compara questo segnale con una soglia fissa impostabile sul trimmer da 10kOhm. Sullo stesso pin è presente un condensatore per stabilizzare questo valore di tensione, ciò è necessario perchè senza quel condensatore la tensione sul pin invertente fa dei brutti scherzi (picchi vari a seconda del segnale in ingresso).

Vi rimando al capitolo precedente per una spiegazione approfondita del processo di demodulazione e decodifica.

La resistenza R3 in uscita è necessaria come pull-up perchè l'uscita del 311 è open collector. All'uscita del comparatore è presente il rivelatore di inviluppo di cui abbiamo già parlato, dopo cui troviamo finalmente l'ingresso nel PIC.

Un ultimo dettaglio da notare è la presenza di due led bicolore rosso-verde a tre terminali denominati STATUS e DATA led. Il primo è rosso appena il dispositivo è acceso e diventa verde quando è collegato al software sul PC. Il secondo viene gestito durante la ricezione di dati per poter verificare se il PIC sta ricevendo i comandi correttamente o sta ricevendo interferenze.


Codice Sorgente

Il codice sorgente è scritto in C (ambiente mikroC), il che semplifica notevolmente la scrittura del programma soprattutto data la presenza delle librerie per l'impostazione della porta USB e di esempi a riguardo.
Inoltre, pur rimanendo indiscussa la superiorità dell'assembly, i PIC della serie 18F sono ottimizzati per eseguire codice compilato dal C.

Per permettere il corretto funzionamento del programma, i fuses vanno impostati nel modo seguente:

(clicca sull'immagine per vederla più grande)

E tutti i vari code-protect vanno disabilitati (o abilitati, come preferite, è indifferente).

Il codice non è eccessivamente semplice, è costruito utilizzando il modello proposto negli esempi delle librerie di mikroC aggiungendovi (molto) codice personalizzato e alcune funzioni utili.

Innanzitutto, la comunicazione USB avviene scambiandosi pacchetti di n byte, dove n è un numero deciso al momento della compilazione. Io ho optato per il numero minimo che è 64, tanto i byte da inviare sono pochi. Ciò significa che ogni volta che il PC o il PIC riceveranno dei dati, avranno ricevuto un pacchetto di 64 byte.

Per fare sì che il ricevitore e il programma per PC sapessero se quello che gli arrivava era un messaggio testuale, un codice ricevuto o un comando di sistema (tipo "disconnetti") ho optato per un sistema in cui il primo byte di ogni pacchetto inviato definisce il tipo di dato ricevuto. Questa tabella fa chiarezza su questo sistema:

(clicca sull'immagine per vederla più grande)

Dalla tabella si capisce che quando il PIC vuole inviare un messaggio testuale al PC, imposta il primo byte a 12 e i seguenti con i caratteri del messaggio. Quando il PC riceverà il pacchetto, leggerà il primo byte e capirà che quello che segue è un messaggio.

Per comunicare al PC di aver ricevuto un comando, il primo byte va impostato a 15 e i seguenti tre col codice del comando. Perchè tre byte con lo stesso codice? Perchè, nel caso il dispositivo venisse posizionato lontano dal PC per avere una migliore ricezione del segnale (ad esempio con una prolunga USB da 5 metri), la distanza elevata potrebbe fare sì che un byte venisse letto male perchè degenerato durante la trasmissione. In questo modo, se il PC legge tre byte uguali non c'è problema. Se legge due byte uguali e uno diverso, applica il codice di correzione d'errore a maggioranza, interpretando il comando corretto come quello presente due volte. Nel caso leggesse tre byte uguali, purtroppo non ci sarebbe nulla da fare, ma questo è praticamente impossibile.

I tre codici rimanenti sono utilizzati come "comandi di sistema" soprattutto per la procedura di autenticazione. Questa procedura è necessaria alla connessione del dispositivo. Se questa procedura non viene effettuata, i comandi ricevuti vengono ignorati. Potrebbe sembrare una complicazione inutile, ma è necessaria per evitare che il dispositivo, danneggiandosi per qualche motivo, invii codici errati al PC. Richiedendo l'invio di codici ben determinati in una sequenza ben determinata, si può essere certi del corretto funzionamento sia del PIC che del PC.

Questa procedura è comunque semplice, quando il dispositivo viene attaccato al PC si preme il tasto "connetti" sul programma lato PC. Premendo questo tasto, il PC invia il codice 11-12 per richiedere la connessione. Se il PIC riceve ed è ben funzionante, risponde con il codice 10 così che entrambi i dispositivi validino la connessione. Il comando 25-28 può essere inviato dal PC al PIC in qualsiasi momento premendo il tasto "disconnetti", ma viene anche inviato automaticamente all'accensione del programma sul PC. Questo perchè nel caso il programma venisse spento e riacceso senza che il dispositivo venisse scollegato, quest'ultimo conterebbe ancora la connessione come valida ma per il PC non sarebbe lo stesso. Inviando il codice di disconnessione all'avvio, si è certi che il dispositivo sarà sempre in uno stato noto.

Tornando al codice sorgente per il PIC, all'inizio vi è la solita impostazione delle porte e dei registri interni. Poi vi è l'inizializzazione del modulo usb, chè è una routine bloccante (il codice non prosegue finchè il PC non riconosce con successo il dispositivo). A questo punto viene gestita la procedura di autenticazione, attendendo il codice 11-12 e inviando il codice 10 una volta che si è ricevuto.

Terminata la procedura di autenticazione, vi è il ciclo principale in cui si controlla in polling lo stato del pin di input (B0) e, nel caso sia alto, si inizia a leggere e decodificare il segnale secondo le modalità descritte in precedenza. Terminata la lettura del segnale, il codice ricevuto viene inviato al PC nel modo che abbiamo appena visto.

All'interno di questo ciclo principale viene anche controllata l'eventuale ricezione di un comando di disconnessione. Nel caso venga ricevuto, si torna con un goto (non me ne vogliano i buoni conoscitori del linguaggio C, non piace neanche a me ma in questo caso ci voleva...) all'inizio della procedura di autenticazione.

Per quanto riguarda il ricevitore è tutto. Qua di seguito trovate i link per scaricare il codice sorgente e il file hex già compilato. Potrei aver dimenticato qualcosa, nel caso potete mandarmi una email per richiedere eventuali altre spiegazioni.


Termino questo capitolo con alcune foto del dispositivo pronto:

Vista del circuito interno:

(clicca sulle immagini per vederle più grandi)

Vista esterna e dispositivo chiuso:

(clicca sulle immagini per vederle più grandi)