Questa scheda controller fa parte del progetto di questa barca radiocomandata,
realizzata nel corso dell'estate 2002. La propulsione della barca è data da un motore
elettrico in corrente continua di tipo 600BB e la scheda controllo stabilisce la velocità
ed il verso (marcia avanti o indietro) del movimento.
Alimentazione e caratteristiche del circuito
Tutta la barca è alimentata da un accumulatore al piombo da 6 V 4.0 Ah. La tensione a batteria
carica è di circa 6,7 Volt e ho quindi inserito, come unica regolazione della tensione, un diodo
in serie, che protegge il circuito da inversioni accidentali di polarità e fa cadere la tensione di
circa 0,7 V. I 6 V massimi risultanti, anche se un pò eccessivi per il PIC 16F84A (che non dovrebbe
eccedere 5,5 V), non danno alcun problema e la scheda funziona perfettamente.
L'oscillatore utilizzato è quello classico per i PIC, con un quarzo da 4 MHz e due condensatori,
per cui si ottiene un tempo di esecuzione per le istruzioni di 1 microsecondo.
La scheda controllo ha le seguenti connessioni e funzioni:
- Connettore di alimentazione (+6V e massa)
- Ingresso radiocomando (4 ingressi TTL dal ricevitore per radiocmando)
- Uscita pwm per motore (va al gruppo di transistor di potenza)
- Uscita per direzione motore (va a due relay da 30 A che invertono al polarità del motore)
- Uscita ausiliaria (pensata per un LED ad alta luminosità)
- Un LED rosso a bordo (per segnalare diverse condizioni)
- Un pulsante a bordo (per test e per eventuali funzioni future)
Misura degli impulsi
La funzione principale del programma che gira sul PIC è quella di misurare gli impulsi che arrivano dal
ricevitore radio, calcolando quindi la velocità desiderata, che viene impostata attraverso adeguati
impulsi pwm (pulse width modulation) sull'alimentazione del motore.
Ma è forse bene ricorda innanzitutto come funziona un radiocomando proporzionale. Se abbiamo a che fare,
come nel mio caso, con un trasmettitore a 4 canali, esso avrà di solito due leve, ognuna con movimento
orizzontale e verticale, per un totale di 4 comandi, appunto. Il trasmettitore legge la posizione di
ogni leva e trasmette di continuo la seguente sequenza:
- Un impulso di almeno 4 millisecondi, per indicare l'inizio della sequenza
- Una pausa di 1 ms
- La posizione della prima leva, codificata come un impulso di lunghezza variabile da 1 ms (min) a 2 ms (max)
- Una pausa di 1 ms
- I passi 3 e 4 sono repetuti altre 3 volte, per inviare tutti e 4 i canali
Un'intera sequenza dura così al massima circa 17 ms e se il trasmettitore non fa pause ulteriori, ciò risulta
in 59 comandi di posizione inviati ogni secondo, direi abbastanza anche per gli aeromodelli più veloci.
Il ricevitore radio demultiplexa i 4 canali su 4 differenti connettori, da dove escono degli impulsi TTL
compresi tra 1 e 2 ms. La scheda è progettata per leggere tutti e 4 i canali, anche in parallelo (anche se
come si vede gli impulsi sono sequenziali), ma per ora il software gestisce il solo canale 2 (controllo
motore).
La maggiore difficoltà nella scrittura del programma di gestione è venuta dal fatto che il 16F84 ha un solo
timer a bordo (escludendo il watchdog, che ha un uso dedicato) e quindi ho dovuto usarlo per tutte le
funzioni, cioè sia per leggere gli impulsi in input che per generare quelli di output (e anche altro!).
Come funziona
Quando arriva l'inizio di un impulso TTL, viene generato un interrupt sulla porta B e la routine di servizio
dell'interrupt si limita a salvare il valore corrente di Timer0. Quanto l'impulso finisce viene generato
un secondo interrupt e questa volta la routine calcola la differenza tra il valore corrente di Timer0 e quello
salvato, la memorizza in una variabile ed attiva un flag di validità.
Nel loop principale del programma, quando viene rivelato il flag di validità per il canale 2 attivato,
una subroutine azzera il flag, legge la durata dell'impulso, la elabora per produrre il valore da
utilizzare per la pwm in output ed inoltre attiva o disattiva il relay che controlla la direzione del
movimento.
Quanto Timer0 va in overflow (ogni circa 4 ms, visto che ho impostato il prescaler a 16x) se il valore
pwm non è zero, il motore è attivato. Quando poi nel loop principale viene rivelato un valore di Timer0
superiore al valore pwm impostato, il motore viene spento. La frequenza degli impulsi pwm è quindi di
250 Hz, forse un valore un po' troppo basso, ma comunque funzionale.
Timer0 viene anche utilizzato per incementare alcuni contatori "lenti", usati in altre parti del programma.
Ad esempio, quando mancano interrupt sulla porta B per circa 1 secondo, ciò indica l'assenza del segnale
dal radiocomando e quindi il motore viene spento. Il programma quindi ricerca nuovi impulsi stabili
e, quando arrivano, viene ripresa la normale elaborazione.
Per pilotare l'uscita motore utilizzo 4 pin della porta B in parallelo, per avere una corrente di 80
mA. Questa corrente va sulla base di un transistor 2N3055, la cui uscita va sulle basi di altri 3
transistor 2N3055 connessi in parallelo. Ho utilizzato questa configurazione super-Darlington semplicemente
perché avevo a disposizione un modulo usato, con 4 2N3055 montati su un dissipatore e quindi
pronti all'uso.
Il bug
La prima versione del programma aveva un difetto piuttosto serio: il motore non era mai completamente
fermo, neanche quando la leva era in posizione perfettamente centrale e c'erano sempre degli impulsi
errati che portavano brevemente il motore al massimo dei giri. Tutti i controlli sul programma furono
assolutamente inutili, finché non pensai bene di andarmi a rileggere i manuali Microchip, sul funzionamento
degli interrupt della porta B. Mi resi così conto che quando modificavo lo stato del motore, scrivendo
sulla porta B, facevo partire degli interrupt errati, perché la scrittura sulle porte di I/O implica
anche una loro lettura automatica!
Purtroppo avevo già costruito e testato il circuito, altrimenti probabilmente avrei utilizzato un pin
della porta A e un transistor, come output. E' bastato però modificare in modo adeguato il programma,
sostituendo alla semplice istruzione clrf PORTB per fermare il motore, il seguente blocco:
bcf INTCON,RBIE ; disabilita interrupt su PORTB
clrf PORTB ; ferma motore
movf PORTB,f ; rilegge PORTB per eliminare discordanza dei pin
bcf INTCON,RBIF ; azzera PORTB interrupt flag, nel caso si sia attivato
bsf INTCON,RBIE ; abilita di nuovo interrupt su PORTB
Lo stesso metodo è utilizzato quanto il motore viene attivato. Più economico di un transistor, direi.
Oltre al giusto modo di manipolare la porta B ho anche aggiunto dei filtri sulla durata degli impulsi,
soprattutto nel caso che si utilizzi un radiocmando diverso da quello che ho attualmente. Così gli
impulsi più corti di 0,9 ms o più lunghi di 2,1 ms sono ignorati, mentre quelli di 0,9-1,0 ms
sono normalizzati ad 1 ms e quelli di 2,0-2,1 ms sono normalizzati a 2 ms.
Sviluppi futuri
Ci sono molte possibilità, se uno vuole veramente complicarsi la vita:
- Migliore copertura, dello stesso colore della barca, ed uno strumento per misurare
la tensione della batteria (in preparazione)
- Un LED ad alta luminosità (o più), come faro della barca
- Una fotocamera digitale tipo carta di credito, per scattare foto di animali, del fondo, ecc.
(come pilotare la porta USB?)
- Sensori di tensione e temperatura, per evitare di bruciare i transistor (velocità massima per tempi molto
lunghi) o per non vedere la batteria scarica al centro di un lago...
- Qualcuno mi ha persino suggerito un sistema di cavi per recuperare la barca in caso di affondamento,
ma sono piuttosto ottimista, dopo aver visto come naviga bene!
Il circuito
Lista dei componenti
- 1x Microchip PIC 16F84 (o 16F84A), 18 pin DIP
- 1x zoccolo da 18 pin per integrati
- 1x transistor 2N5320 (o simile)
- 1x diodo 1N4002
- 1x LED rosso
- 1x LED bianco ad alta luminosità
- 1x quarzo da 4 MHz
- 2x condensatori da 27 pF
- 1x resistenza 56 Ohm, 1/4 W
- 1x resistenza 62 Ohm, 1/2 W
- 1x resistenza 470 Ohm, 1/4 W
- 1x resistenza 810 Ohm, 1/4 W
- 1x resistenza 4.7 KOhm, 1/4 W
- 2x resistenze 100 KOhm 1/4 W
- 9x punti di connessione
Al di fuori della scheda di controllo
- 4x transistor 2N3055, montati su un dissipatore
- 1x relay 30 A a due scambi (ho usato due relay separati da 10 A, 3 scambi)
- 1x diodo 1N5406
Collegamenti
Questa pagina è disponibile anche in lingua inglese (in English)
|