Progetti - PIC

 

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:

  1. 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.
  2. 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.
  3. 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:

0000   

1111  

1010    0101   

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.


 

 

         

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 09/11/17.