Trasmettere a distanza più
segnali.
|
Una applicazione con intenti didattici.
Può essere necessario trasmettere a distanza la situazione di spie di
segnalazione o comandi in uscita da un dispositivo di controllo e, dove la distanza è consistente, l' uso di cavi
multipolari può
essere economicamente e praticamente poco conveniente.
Prendiamo il caso dove sia necessario remotare alcune segnalazioni: casi
comuni sono segnapunti, remotazione di indicatori, remotazione di azionamenti,
ecc.
|
Se abbiamo, ad esempio, 4 segnali, occorrerà disporre di
un cavo a 5 conduttori (4 segnali + il comune).
Se la distanza supera qualche metro, il costo e l' ingombro di questo
cavo possono essere inaccettabili. |
Ideale è la possibilità di inviare l'informazione su un numero più basso
possibile di conduttori, ovvero, al limite, il classico doppino.
|
Dal punto di vista elettrico abbiamo ad un estremo un certo numero di segnali
che arrivano in parallelo e che dobbiamo serializzare questi dati,
inviandoli uno alla volta sul conduttore; in sostanza, la funzione richiesta è
quella di un registro PISO (Parallel Input - Serial Output).
All' arrivo è necessario che i dati seriali vengano riconvertiti in forma
parallela, quindi un registro SIPO (Serial Input- Parallel Output).
|
Queste funzioni, dal punto di vista elettronico, sono facilmente realizzabili in
molti modi. Però, se una costruzione con classici componenti delle logiche CMOS è sempre
possibile, essa è del tutto obsoleta di fronte alle possibilità offerte anche dai più
piccoli microcontroller, che possono svolgere queste azioni di codifica, invio,
ricezione seriale e
decodifica in modo molto elastico e funzionale.
Scegliamo quindi un microcontroller dotato del sufficiente numero di
ingressi/uscite per costruire trasmettitore e ricevitore, cosa che vedremo
subito essere per nulla complessa.
Se la parte logica è facilmente risolvibile, si pone il problema del media di trasmissione dei dati. Comunicazioni seriali
sono da tempo ben standardizzate, sia per quanto riguarda il protocollo che per
il supporto hardware. Le possiamo dividere in due
famiglie: trasmissioni sincrone e trasmissioni asincrone.
|
Le trasmissioni sincrone utilizzano una linea dati ed una linea di clock, per
cui trasmittente e ricevente operano con lo stesso clock. I dati presenti sulla
loro linea sono validi solamente in coincidenza con un preciso stato della linea
di clock; questo fa si che trasmettitore e ricevitore possano funzionare con
frequenze di clock interno del tutto differenti, dato che la sincronizzazione
dati/clock è quella che ne determina la validità. |
Da notare che una trasmissione del genere non ha nè un obbligo di lunghezza
fissa dei dati trasmessi: poichè ogni
dato è validato dal relativo impulso di clock, possono essere trasmessi di
seguito bit in numero illimitato, dipendente solo dalle capacità del ricevitore
di elaborarli, anche se nella pratica si finisce per utilizzare dati raccolti in
blocchi logici (bytes) essenzialmente perchè questo dipende dall' ampiezza dei
registri dell' elettronica di controllo.
Inoltre, la linea potrà rimanere inattiva per tempo indeterminato
anche durante la trasmissione di un blocco di dati perchè la presenza di un
dato valido è determinata da relativo impulso di clock. In questo senso una
trasmissione sincrona è possible anche al minimo livello di priorità delle
azioni svolte dal processore.
Dal punto di vista fisico, però, il sistema richiede al minimo la presenza di due
conduttori attivi, che, con la massa comune, diventano tre conduttori.
Esempi di questo modo di trasmettere dati sono SPI e I2C, solitamente
utilizzati per distanze brevi, dell' ordine delle decine di centimetri.
Questo è facilmente spiegabile con il fatto che, per superare distanze
elevate, occorre fare i conti con le caratteristiche di resistenza e impedenza
dei conduttori, che non possono essere collegati direttamente agli I/O logici se
non per lunghezze inferiori al metro, pena l'arrivo al ricevitore di segnali con
transizioni di livello lente e fronti deformati da sovra oscillazioni, tanto
più sensibili quanto si aumenta la frequenza degli impulsi trasmessi. Inoltre
una lunga linea tra trasmettitore e ricevitore sarà soggetta a captare disturbi
indotti, con la possibilità di errori nella ricezione dei dati.
Occorre porre tra linea e trasmettitore/ricevitore un qualche dispositivo di
interfaccia che permetta al segnale di superare indenne il cavo di connessione:
è necessario un elemento addizionale, un driver, che ha a che fare più con
il conduttore di collegamento che con la logica della trasmissione. Ne sono
esempi RS-232, dove si utilizza una tensione bipolare, RS-485, dove si utilizza
un segnale differenziale, ecc.
Altra soluzione è quella di modulare non la
tensione, ma la corrente, come nel caso dei Current Loop. Con queste interfacce
il segnale logico può essere trasportato a distanze di 400 metri e più.
Ovviamente, minore è il numero di segnali da spostare, minore sarà la
complessità e il costo dell' interfaccia, dato che per ogni conduttore si
richiede un driver di linea di trasmissione ed uno in ricezione.
Rispetto alla trasmissione sincrona, che richiede due segnali, dati e clock,
la trasmissione asincrona permette
di risparmiare una linea, dato che il segnale porta con se gli elementi di
temporizzazione necessari ad una ricezione corretta.
In una trasmissione asincrona che opera con la sola emissione di dati, il
ricevitore non riceve alcuna validazione del dato attraverso un clock
esterno, ma deve derivarla dalla struttura della trasmissione. Questo richiede
alcune condizioni stringenti.
-
In primo luogo, la quantità dei dati trasmessi deve essere pre fissata; ovvero,
se la trasmissione comporta dati da 8 bit, non sarà possibile trasmettere dati
da 4 o 10 bit. I dati sono quindi pacchetti non per obblighi derivati dalla
struttura dei registri, ma dalla natura stessa della trasmissione.
- In secondo luogo, la lunghezza di ogni dato sarà pure rigidamente pre fissata,
dato che questa è il mezzo per far si che il ricevitore possa
"sincronizzarsi".
-
E, a questo scopo, è necessaria una terza condizione, ovvero che la stringa dei
dati seriali sia preceduta da un bit di start che avverta il ricevitore dell'
arrivo di un pacchetto di dati.
Vediamo di chiarire meglio la situazione: vogliamo ad esempio trasmettere il
dato binario 10111001
|
Nella trasmissione sincrona, non ha importanza ne la lunghezza dei dati, nè
quella degli impulsi di clock, ma solo il fatto che il ricevitore identifica un
dato valido in base alla presenza del relativo impulso di clock (anche se si
avrà normalmente la tendenza ad avere un clock di frequenza definita e
costante). |
Non c'è neppure una stretta necessità di avere dati in pacchetti fissi,
poichè dati validi sono quelli in coincidenza con il clock (anche se, come
detto, la tendenza è quella di inviare dati in formati definiti, come ad
esempio 1 byte).
Non serve neppure un elemento che indichi al ricevitore la presenza dei dati,
dato che questa funzione spetta al clock, solitamente con un sincronismo su uno
dei fronti dell' impulso.
Il ricevitore sincrono resta in attesa del
fronte di un impulso del clock e a questo associa il livello della linea
dati.
Da notare che una funzione comune degli I/O digitali nei microcontroller
è quella di rilevare la variazione dello stato, per cui la linea del
clock può essere verificata sia con un polling che con interrupt,
rendendo possibile la ricezione nelle situazioni più diverse.
|
Nella trasmissione asincrona, occorre necessariamente che gli impulsi dei dati
siano di lunghezza perfettamente costante e che siano in numero ben definito.
Questo deriva da come il ricevitore opera per distinguere il valore dei dati. |
E, per questa ragione, si rende necessaria l' introduzione di un elemento,
detto bit di start, che indichi al ricevitore che sta arrivando un pacchetto di
dati.
|
Ne risulta un pacchetto formato da uno stato iniziale
solitamente pari alla metà della durata di un impulso di dato.
|
Questo perchè il ricevitore, nella forma più semplice, opera come segue:
- All'arrivo del bit di start (a), il ricevitore si predispone e
genera internamente un ritardo pari alla durata di un impulso dati
(1t)
- Poichè la durata dell' impulso di start è 1/2t, il ricevitore
andrà a campionare la linea dati a metà del successivo impulso
dati e ne preleverà il valore (b)
- Quindi ricaricherà il timer per un altro tempo 1t ed effettuerà
un nuovo campionamento (c) prelevando il secondo dato
- La cosa si ripete (d,e,f,g,h,i) per tutti i dati trasmessi
E' evidente che ricevitore e trasmettitore devono avere un clock quanto più
possibile identico per poter calcolare e generare le stesse temporizzazioni.
Inoltre il pacchetto dati dovrà essere preventivamente fissato e costante, dato
che il termine della ricezione è determinata.
Dato che abbiamo a che fare con componenti
elettronici e linee di trasmissione reali, al termine del pacchetto trasmesso, solitamente
si introduce un ulteriore elemento di tempo (bit di stop) che permetta al
ricevitore l' elaborazione dei dati ricevuti prima dell' arrivo del pacchetto
seguente. E, per ridurre i possibili problemi nella discriminazione del dato, si
può anche aggiungere uno o più bit di controllo (parità). Questi elementi non fanno strettamente parte
degli obblighi della trasmissione, ma sono da considerare quando si voglia
elevarne la sicurezza.
E' ovvio che l' aggiunta di elementi non-dato, come i bit di start, stop ed
eventuale parità riduce l' efficienza della trasmissione perchè determina un rapporto
elevato tra i gli elementi trasmessi che contengono informazione e quelli
che sono aggiunti per permettere la trasmissione stessa. Ma questo è un fatto
che si rende necessario in ogni genere di comunicazione.
Possiamo aggiungere anche la considerazione ovvia che minore sarà il tempo
di durata di un impulso, maggiore dovrà essere la precisa coincidenza delle
frequenze di ricezione e trasmissione. E maggiore sarà il numero di bit
trasmessi in un pacchetto, maggiore dovrà essere questa precisione.
Ne deriva che un modo semplice per ridurre gli effetti negativi dovuti ad
eventuali differenze di clock del
microcontroller che trasmette rispetto a quello che riceve si potrà
implementare
facilmente con una velocità di trasmissione "lenta" e con un quantitativo di bit
limitato in ogni pacchetto.
Il secondo elemento è comunemente risolto dal fatto che si trasmettono solitamente caratteri genere
ASCII, codificati su 8 bit; in particolare, nel caso che esemplifichiamo basteranno solo 4 bit, ognuno relativo allo stato di una segnalazione.
Per quanto riguarda il clock, è da osservare che tutti i
microcontroller più recenti sono dotati di oscillatore interno che, a
specifiche, garantisce una precisione della frequenza generata attorno all' 1%. Quindi, se
scegliamo un tempo di durata di ogni bit alquanto maggiore del periodo del clock
potremo facilmente evitare la necessità di utilizzare oscillatori quarzati,
mentre l' effetto del cavo, data la bassa frequenza di trasmissione, sarà
minimizzato.
Il progetto.
Dato che si volevano spostare 4 bit di dati, sono stati utilizzati
microcontroller minimali, per l' esattezza PIC della famiglia Baseline, in
package a 8 pin.
Si tratta di elementi economicissimi e i sei I/O a disposizione sono più che
sufficienti.
# |
funzione |
1 |
dato 1 |
2 |
dato 2 |
3 |
dato 3 |
4 |
dato 4 |
5 |
linea trasmissione |
6 |
segnalazione di stato |
E' stato scritto un firmware quanto più possibile semplice: non utilizza
interrupt, non utilizza UART, non utilizza istruzioni nè risorse particolari.
Per queste sue
caratteristiche è trasportabile con estrema facilità su qualsiasi PIC di
qualsiasi famiglia e su qualsiasi altra famiglia di microcontroller di altri
costruttori senza
particolari problemi.
Per quanto riguarda la precisione del clock, questo è stato
risolto semplicemente utilizzando tempi di trasmissione molto lunghi. E' comune
nei Baseline un clock interno da 4MHz, ovvero con un ciclo istruzione di 1us e
la precisione dichiarata dell' 1%, ma in ogni caso abbiamo usato un pacchetto composto da:
- un bit di start da 500us
- 4 bit di dati da 1ms ciascuno
- un bit di stop/controllo da 1ms
Tra un pacchetto ed il successivo intercorrono 100ms, ottenendo così una
trasmissione alla cadenza di 10Hz circa.
Con questi tempi è possibile una sensibile differenza tra i clock dei
trasmettitore e del ricevitore senza perdita di dato e il tempo di idle della
linea permette anche una complessa elaborazione dei dati tra un pacchetto e l'
altro.
Utilizzando una interfaccia fisica genere RS-485 si
possono ottenere distanze di oltre 400m, mentre su un singolo conduttore guidato
in open collector o current loop si arriva tranquillamente a 100m. Una
connessione diretta tra ricevitore e trasmettitore è stata provata
positivamente fino a metri.
Ovviamente i tempi indicati sono molto "abbondanti" e possono
essere anche drasticamente ridotti senza particolari problemi, mentre il tempo di attesa tra
due pacchetti può essere ridotto anche di un fattore 10, ottenendo una
trasmissione a qualche centinaio di hertz. Frequenze superiori sono ben possibili, ma
non sono necessarie data la funzione del dispositivo. Il trasmettitore invia in linea in continuazione i
pacchetti di dati ed è quindi il refresh di questi che dipende da questa
cadenza: nella trasmissione di segnalazioni o stato di interruttori difficilmente sono
necessarie frequenze maggiori; dove rischiesto sarà opportuno ricorre ad un
sistema più sofisticato.
Dal punto di vista pratico, il trasmettitore è molto semplice: verifica il livello dei pin di
ingresso, impacchetta i dati in forma seriale e li invia senza sosta sulla
linea.
Il ricevitore è leggermente più sofisticato: il microcontroller attende il
presentarsi di un livello alto al pin di ricezione, il che corrisponde al bit di
start. Dopo di che sorveglia l'ingresso seriale a cadenza di 1ms e estrae il
valore del bit trasmesso, che poi trasferisce sui pin di uscita.
In una struttura così semplificata sarebbero possibili diverse tipologie di
errore, di cui le principali sono:
- se il ricevitore entra in linea in un momento in cui il trasmettitore ha
già iniziato l' invio di un pacchetto, potrà capitare che venga rilevato
il livello alto del bit di strat alla sua fine, creando possibili errori di
ricezione per una differenza sensibile dei clock.
- se il ricevitore entra in linea in un momento in cui il trasmettitore ha
già iniziato l' invio di un pacchetto, potrà capitare che venga rilevato
il livello alto non del bit di start, ma di uno qualsiasi dei bit inviati a
livello alto, originando la ricezione per un dato errato.
- se il trasmettitore si blocca a livello alto o basso durante la
trasmissione o la linea si interrompe, il ricevitore, una volta
sincronizzato, non ha la possibilità di rilevare questo e i dati ricevuti
sono errati
Allo scopo di evitare queste condizioni è stato aggiunto ai dati un bit di "stop"
che ha funzioni di controllo, anche se molto semplificate: si tratta
di accodate un bit che sia di valore opposto all' ultimo trasmesso. In questo
modo si potrà evitare gli errori derivati dal terzo caso.
Per il primo caso si è utilizzato un sistema molto semplicistico, ma
efficace: il ricevitore, una volta acquisito un primo livello alto, cessa la
ricezione per un tempo pari alla lunghezza del pacchetto dati e attende, dopo un
ritardo dt quasi pari al tempo di attesa tra i pacchetti, l' arrivo di un nuovo
bit di start.
Questo evita gli errori dovuti ai primi due casi e garantisce la massima
sincronizzazione tra il ricevitore e il pacchetto dati in arrivo.
A questo è stata aggiunta una trappola costituita dal conteggio del Timer0
che viene avviato al momento del termine del tempo dt: se entro l' overflow del
timer non viene ricevuto uno start, il programma si riposiziona come se si
trattasse del primo dato in assoluto, quello che sarà scartato. Questo previene
errori dovuti alla caduta della linea o al guasto del trasmettitore, che, come
abbiamo detto, deve trasmettere in continuazione.
L' hardware.
Il programma sorgente è scritto per
poter essere utilizzato immediatamente su 12F508/509/510/519. Con cambi che
interessano solamente il config e l' eliminazione di eventuali analogiche o
comparatori dai pin di I/O usati, è trasferibile così come sta su qualsiasi
altro PIC, dai 16F a 18F.
|
Si tratta di un hardware extra semplice, dato che sia il trasmettitore che il
ricevitore consistono in un solo chip a 8 pin ed al relativo condensatore di
stabilizzazione sull' alimentazione e poco altro.
Il trasmettitore riceve 4 segnali in ingresso e li serializza sulla
linea di comunicazione.
Un LED viene utilizzato come indicatore di stato. |
|
Il ricevitore ha l'ingresso il segnale dalla linea e
rende 4 uscite parallele.
Il microcontroller può comandare direttamente carichi fino a 25mA.
Se occorrono correnti maggiori si farà seguire un buffer adeguato.
Anche qui un LED ha funzione di indicatore di stato. |
I dati in arrivo posso provenire da interruttori, stati logici e qualsiasi
altra sorgente adeguata ad essere introdotta nei pin di I/O del microcntroller.
Lo stato degli ingressi è scandito ogni 100ms e questo vuol dire che variazioni
all'interno di questo tempo non saranno considerate. Se si utilizzano
interruttori o pulsanti con rimbalzi sensibili, può essere opportuno inserire
un sistema di debounce hardware o software.
|
Il ricevitore è del tutto analogo: ha in ingresso il
segnale dalla linea e rende 4 uscite parallele.
Il microcontroller può comandare direttamente carichi fino a 25mA.
Se occorrono correnti maggiori si farà seguire un buffer adeguato.
Anche qui un LED ha funzione di indicatore di stato che lampeggia
diversamente a seconda delle condizioni. |
Sono state realizzate due piccolissime schede pcb :
|
Il trasmettitore è semplice.
Il connettore E$7 riporta l' alimentazione e il segnale di linea. La
presenza dell' alimentazione sia sul connettore di uscita che su quello
di ingresso è utili per concatenare moduli addizionali, come quelli di
interfaccia.
Il connettore E$10 permette di innestare un array di resistenze di
pull-up o pull-down, se fosse necessario.
Il connettore E$2 consente di collegare l' alimentazione e le quattro
linee di ingresso. |
|
Il ricevitore ha in ingresso il connettore E$20, analogo a
quello del trasmettitore e in uscita il connettore E$8 che riporta le
quattro linee dati e l' alimentazione.
Sono stati aggiunti 4 LED per una immediata visualizzazione del dato
ricevuto. |
Nel reale, la foto seguente presenta il trasmettitore collegato ad una
scheda di interruttori con debounce hardware e che comunica con il ricevitore con una linea
diretta. La scheda in alto con i due accumulatori NiMH è l'
alimentatore.
e un ingrandimento delle schede: in primo piano il trasmettitore.
Alle uscite sono collegabili ovviamente ogni genere di carichi, interponendo
buffer adeguati. Ad esempio, con un piccolo MOSFET (logic level)o un transistor
darlington singolo o in array si potranno collegare lampadine di segnalazione o
relè a tensione elevata e con correnti consistenti.
Il programma.
Il programma sorgente è scritto in Assembly per
poter essere utilizzato immediatamente su 12F508/509/510/519. Con cambi che
interessano solamente il config e l' eliminazione di eventuali analogiche o
comparatori dai pi n di I/O usati, è trasferibile così come sta su qualsiasi
altro PIC, dai 16F a 18F.
Se bastano solo tre segnali si potrà usare uno dei micro PIC a sei pin (10F2xx). Se occorrono più segnali si
potrà utilizzare un PIC con un numero maggiore di pin. Vedremo più avanti una
applicazione per comandare un display a sette segmenti con un PIC a 14 pin.
L' estrema semplicità e un dettagliato commento di ogni linea permettono di
comprendere con facilità la sequenza delle istruzioni.
Potrebbe essere utile portare all'attenzione alcuni punti.
In primo luogo il meccanismo di scelta del processore: basandosi su una stretta
somiglianza dei componenti Baseline, è possibile scrivere un sorgente auto
compilante a seconda del processore scelto. Questo viene svolto dalla funzione #ifdef:
; scelta del processore
#ifdef __12F509
LIST p=12F509
#include <p12F509.inc>
#endif
#ifdef __12F508
LIST p=12F508
#include <p12F508.inc>
#endif
#ifdef __12F510
LIST p=12F510
#include <p12F510.inc>
#endif
#ifdef __12F519
LIST p=12F519
#include <p12F519.inc>
#endif |
Il parametro relativo al processore viene prelevato dal compilatore dalla
lista dei simboli ed è stabilito nel progetto MPLAB nella sua creazione o
modificato dal menu Configure-> Select Device
Ad esempio, se è stato selezionato 12F509, il parametro corrispondente
definito sarà __12F510, per cui la catena degli #ifdef
sarà valida solo per questo e sarà incluso e listato il file .inc adeguato:
; scelta del processore
#ifdef __12F509
LIST p=12F509
#include <p12F509.inc>
#endif
#ifdef __12F508
LIST p=12F508
#include <p12F508.inc>
#endif
#ifdef __12F510
LIST p=12F510
#include <p12F510.inc>
#endif
#ifdef __12F519
LIST p=12F519
#include <p12F519.inc>
#endif |
La stessa operazione è eseguita per il config, sia per le diverse
risorse dei processori, sia anche perchè si deve notare, purtroppo, che esiste
una certa confusione nei parametri che indicano una medesima scelta; così
abbiamo simboli diversi a seconda del processore, ad esempio _IOSCFS_OFF per l'
oscillatore a 4MHz di 12F510, che diventa _IOSCFS_4MHz per
12F519. Questi
pasticcetti permangono nonostante esistano molti alias nei file .inc
dei processori e sono noiosa fonte di errori (peraltro facilmente risolvibili)
durante al compilazione.
Analogo è il caso di dover adattare la compilazione ad una struttura di I/O
differente; nel nostro caso, 12F510 dispone di comparatore e di ADC, che gli
altri non hanno e quindi è necessario disabilitarlo se si vuole accedere alla
semplice funzione di I/O digitale.
#ifdef __12F510
; disabilita comparatore
movlw b'11110111'
movwf CM1CON0
; disabilita analogica
movlw b'00000000'
movwf ADCON0
#endif |
E' pure necessario agire sul registro OPTION per disabilitare la funzione
T0CKI che altrimenti renderebbe il pin relativo inutile per il nostro scopo.
;Option_Reg - disabilita T0CKI e prescaler a Timer0
movlw b'11010111'
; no pullup, presc.256
OPTION |
Per il trasmettitore non importa la configurazione di Timer0, mentre questa
periferica è usata nel ricevitore.
La trasmissione avviene semplicemente serializzando un bit di start da 500us,
seguito dai 4 bit di dati da 1ms e da un bit da 1ms di valore opposto all'
ultimo emesso, in modo da consentire al ricevitore di verificare un blocco della
linea.
Lo stato degli ingressi viene scandito ogni 100ms. Non sono previsti sistemi di
debug, che per la trasmissione di indicazioni con LED o lampadine non sono
essenziali; inoltre si crea un debounce "naturale" proprio dovuto alla
distanza di tempo da un campionamento al successivo. Se però si devono
comandare carichi diversi, come ad esempio relè , potrebbe essere molto utile
implementare un loop di debounce prima di inviare i dati.
Nel trasmettitore il LED pulsa alla frequenza della trasmissione, indicando che
il programma sta operando.
Alcuni esempi delle forme d'onda generate dalla trasmissione:
Notiamo il bit di start e il bit finale di segno opposto al precedente. Una
analisi più precisa:
|
Viene trasmesso il dato 1010.
Lo start si estende per 500us, mentre i successivi 4 bit di dati sono
sostenuti ognuno per 1ms.
Il bit di stop-controllo dura anch' esso 1ms ed è di valore opposto
al bit che lo precede.
La linea è mantenuta a livello 0 quando non c'è trasmissione. E'
ovviamente possibile anche invertire i livelli, se necessario,
semplicemente agendo sullo stato imposto al pin che comanda la linea.
|
Nel ricevitore, immediatamente dopo l' accensione, viene rilevato lo stato
alto della linea di ricezione, ma viene introdotto un ritardo tale da
"perdere" l' eventuale pacchetto: questo serve ad evitare che il
ricevitore sia in linea mentre il trasmettitore sta già inviando pacchetti di
dati, con il rischio di sincronizzare erroneamente uno stato alto diverso dal
bit di start.
Il ricevitore ora è in attesa per un tempo di 80ms. Questo lo porta molto
vicino all' inizio del prossimo pacchetto dati.
Per ovviare al problema di una caduta della linea o guasto al trasmettitore,
viene avviato un timer da 65ms: se entro questo tempo non viene rilevato il bit
di start, il programma si riposiziona nella situazione iniziale. Da notare che
in questi PIC privi di interrupt, è possibile comunque intercettare in polling
la fine del conteggio del timer quando sia inserito un prescaler abbastanza
grande da contenere le istruzioni del loop di polling. Nel nostro caso è
impostato il presclaer massimo, che avanza il conteggio ogni 256 colpi di clock.
Se il bit di star viene ricevuto, la linea è campionata a intervalli di 1ms
e i dati sono raccolti in un buffer. Occorre ora che il bit di controllo sia di
valore opposto all' ultimo ricevuto per far si che i dati siano passati sulle
uscite. Questa precauzione impedisce una ricezione scorretta se la linea si
blocca a livello alto.
La scrittura del dato in uscita avviene per mezzo di una shadow, che evita il
problema R-M-W così tipico dei PIC privi di registro LAT.
Il LED lampeggia con la ricezione dei dati. Se è spento non sta avvenendo
alcuna ricezione. Se lampeggia con tre impulsi lunghi, si è verificato un
errore di ricezione e non c'è stato aggiornamento dei dati.
Le routines di tempo sono le solite tratte dall'applet del sito http://www.golovchenko.org/cgi-bin/delay.
Il sorgente Assembly del trasmettitore e del ricevitore sono scaricabili qui.
Media.
Se si desidera raggiungere distanze elevate, una coppia di ricetrasmettitori
RS-485 può essere collegata tra PIC e linea, che sarà
costituita da un doppino, meglio se schermato, con i dovuti terminatori. In
queste condizioni sono stati raggiunti 400m di distanza tra le due unità.
Nel caso di linee molto lunghe e con possibilità di induzione di
sovratensioni, è utile un qualche sistema di protezione:
|
Anche se lo schema riporta un MAX481, è possibile
evidentemente utilizzare qualsiasi rtx per RS-485, anche perchè la gran
parte ha la stessa piedinatura.
Quindi MAX485, LTC486, UA9638, MAX253, ecc. |
Per distanze minori (15-50m) si potrà utilizzare una linea RS-232. Driver
del genere dei vecchi 1488/1489 sono ideali, con alimentazione a +/-12V o più.
Data la bassa frequenza di trasmissione è probabilmente possibile superare la
cinquantina di metri senza problemi.
Si potranno altresì usare loop di corrente, che sono anche facilmente
optoisolabili: la trasmissione è lenta e unidirezionale e quindi non ci
sono problemi anche su distanze elevate.
Anche linee comandate da un open collector, molto usate in domotica, sono adatte a trasmissioni fino a un
centinaio di metri; se si utilizza una tensione più alta per la linea, ad
esempio 12v, si ottiene una buona reiezione ai disturbi.
|
Un collegamento diretto tra ricevitore e trasmettitore è consigliabile solo per
distanze brevi e in ambiente non particolarmente disturbato.
Però, da prove fatte con
una coppia di un cavetto FTP schermato lungo 10 metri, non ci sono problemi
particolari (è stata messa in serie al segnale una resistenza da 56 ohm
sul lato trasmettitore).
Questi sono i rilevi oscilloscopici alla partenza e all' arrivo, da
cui si suppone che sia possibile raggiungere anche distanze maggiori,
data la trascurabile differenza tra le forma d' onda e la mancanza di
sovra oscillazioni. |
Il software.
Sorgenti
del trasmettitore e del ricevitore.
Vediamo ulteriori applicazioni.
|