Newsgroup: it.hobby.elettronica.digitale
Titolo: RS485 multimaster

Ho una connessione RS485 a 4 fili tra 10 schede.
Su una coppia ho un master che trasmette (il suo driver è sempre
attivo) e tutti gli altri ricevono. Ovviamente su questa coppia di
fili non ho problemi.
Sull'altra coppia il master riceve e gli altri trasmettono.
Ovviamente, solo uno può trasmettere in un certo istante per evitare
la corruzione dei dati.
Il protocollo è attualmente half-duplex: il master inizia sempre una
comunicazione con un solo slave inviando un pacchetto di richiesta
dati, con un indirizzo di destinazione. Solo lo slave interrogato
risponde. Questo meccanismo funziona egregiamente.
Vorrei però cambiare il sistema per permettere dei messaggi spontanei
asincroni da parte degli slave. A tutti gli effetti si tratta di
implementare un protocollo multimaster sulla RS485. Avete avuto
esperienze in merito?
Ovviamente ci sarebbero diverse possibilità.
Lo slave, visto che è sempre in ascolto, potrebbe sapere quando il bus
si libera e trasmettere solo in questo caso. Però non potrei evitare
conflitti di messaggi asincroni che vengono inviati nello stesso
momento.
Una soluzione semplice potrebbe essere quella di aspettare un ACK da
parte del master (l'unico che riceve dagli slave). Nel caso di
conflitto tra due o più pacchetti, nessuno viene ricevuto
correttamente dal master (grazie ad un meccanismo di framing e
checksum) e quindi nessun ACK viene tornato in risposta. Lo slave,
dopo un tempo casuale, potrebbe ritrasmettere il messaggio asincrono
nel caso di mancanza di ACK.
Oppure, mettendo in corto le due coppie (quindi facendo in effetti una
RS485 a due fili), lo slave potrebbe ricevere quello che trasmette e,
nel caso non coincidesse (ovviamente per conflitto), fermarsi e
riprovare dopo un tempo casuale. Naturalmente questo meccanismo
potrebbe andare insieme all'ACK che comunque mi sembra più sicuro.
Sarebbe solo un po' più efficiente perchè lo slave potrebbe accorgersi
subito del conflitto.
Avete qualche altra idea? Avete qualche implementazione già fatta e
funzionante o esiste qualcosa del genere in giro?

 funzionante o esiste qualcosa del genere in giro?
Credo che una variante della token-ring (token-bus) eviterebbe
complicati protocolli.
Le periferiche si passano il "gettone" e se qualcuna ha qualcosa da
dire lo dice quando è il suo turno.
Il master è colui che inizia il ciclo e governa l'eventuale assenza di
una periferica per evitare che il gettone venga inviato a stazioni
spente o inesistenti.
Se prevedi frame completi di alcuni millisecondi, puoi determinare un
time-out dopo il quale il master interviene per regolare il normale
flusso dei dati.
Ad esempio, il master pogtrebbe dare inizio al ciclo inviando cercando
di determinare quali periferiche sono connesse (emissione in
broadcast) attendendo le risposte dalle medesime in tempi
differenziati in base ai singoli ID.
Poi, assegna ad ogni periferica l'ID al quale deve rilanciare il
gettone (la 01 alla 02, la 02 alla 05 se le 03 e 04 mancano
all'appello, la 05 alla 06, ecc).
Se il traffico manca per spegnimento di una periferica, il master
interviene e riassegna i rilanci.
E' solo un'idea...  :-|
Viaggia egregiamente su un solo doppino.
Piccio.

 E' solo un'idea...  :-|
Certo, di idee ce ne sono veramente tante.
Avrei preferito un multimaster, ma a quanto pare sembra non banale su
una
RS485...

 per fare l'autoset degli indirizzi, magari pilotato dal master?
In RS485 necessariamente ci deve essere un solo Master,
gestire eventi asincroni e' un problema perche' potresti
avere conflitti in linea, a meno di definire un protocollo
tipo token ring.
Puoi gestire in modo 'asincrono' il bus se in hardware puoi
ricevere l' eco di quello che trasmetti (ovvero, se puoi mantenere 
abilitato il receiver in tutti i nodi sempre).
In questo caso puoi fare una specie di carrier-sense/collision-detection:
- Sei sempre in ascolto
- Trasmetti solo se il bus è libero
- Devi controllare che il carattere trasmesso sia
   ricevuto inalterato.
- Puoi usare come header di un frame un paio di caratteri
   di SYNC, ad esempio FF,FF ...
- se l' echo del dato trasmesso non corrisponde, hai una
   collisione: le stazioni che rilevano una collisione fanno
   un delay dipendende da una priorita' assegnata e poi ritentano.
Bisognerebbe anche stabilire delle regole per ridurre le possibilita'
di collisione al minimo.
In modo 'sincrono' invece ci deve essere un solo master.
Se gli slave possono connettersi alla rete in modo dinamico,
necessariamente il master deve eseguire un polling.
Un 'autoset' e' possibile, ma in ogni caso gli slave devono
disporre di un meccanismo di identificazione univoca, ad
esempio un numero di serie impostato in eeprom... pero'
se puoi assegnare un numero di serie univoco, potresti anche
dare un indirizzo univoco ... vero che magari gli indirizzi
di rete sono in un range limitato, di solito 8bit, mentre un
numero di serie puo' essere molto piu' lungo, ma davvero hai
di queste necessita?
Aa.

 di queste necessita?
La rete è formata da pochi nodi. Ogni slave ha una EEPROM, ma
quando e come dare l'indirizzo, non avendo una interfaccia utente?
Vorrei poter prendere dallo scaffale una scheda slave, collegarla
alla rete e vedere che comunica senza fare altro.
Sarebbe bello poter implementare un metodo di autoconfigurazione
o autoindirizzamento.
Tempo fa avevo letto qualcosa riguardo la possibilità di
autoindirizzare
gli slave, ma non ricordo la strategia.

 o autoindirizzamento.
Sorgono due problemi:
1. Le tue schede possono avere un identificatore univoco
    ad esempio un numero di serie in EEPROM
2. Le tue schede sono vergini e quindi totalmente
    indifferenziabili l' una dall' altra.
Nel caso 1, ci sono varie soluzioni, una semplice prevede
che al master siano noti i numeri seriali degli slave
della rete: il master può eseguire una scansione per i numeri
seriali noti dei dispositivi connessi, assegnando a ogni nodo
un indirizzo di rete univoco. Se il dispositivo manca,
lo slave e' in errore, guasto o spento.
Oppure i nodi senza indirizzo si pongono in ascolto
e quando il master libera il bus per la modalità
'asincrona', cercano di inviare il loro messaggio
contenenente il seriale, von verica di collisione etc. .
Il master colleziona tutti i seriali e dopo un tempo
ragionevole , torna in modo 'sincrono'.
A questo punto il master assegna un indirizzo di rete
ad ogni singolo nodo collezionato usando il seriale come
identificativo.
Al termine, torna in modalita' asincrona e gli eventuali
slave ancora senza indirizzo ripetono la sequenza
precedente...
Il master ripete fino a che non trovera' piu' nodi senza
indirizzo...
Nel caso 2, se non hai un numero univoco, ogni nodo
deve costruirsi un identificatore utilizzando
un valore random (celle di memoria non inizializzate,
valore di timer o altro): unica complicazione, deve
verificare anche che non ci siano identificatori
uguali costruiti da altri nodi: in questo caso provvede
a costruirsene un altro...
In ogni caso, non è una cosa semplicissima da gestire...
detto tra noi, tutti i problemi sparirebbero utilizzando
una rete in CAN bus.
Bye
A.

 asincroni da parte degli slave.
Il CAN č fatto apposta. Lo puoi facilmente emulare con una RS-485. Basta
trasmettere il proprio indirizzo via software, in modo da poter monitorare
se un bit recessivo č andato in collisione con uno dominante.

 se un bit recessivo è andato in collisione con uno dominante.
Come faresti a trasmettere un bit recessivo o dominante su una RS485?
Immagino andando a disabilitare il driver nel caso di bit recessivo (1) 
e ad abilitare il driver nel caso di bit dominante (0).
A questo punto l'indirizzo più basso dovrebbe arrivare a destinazione 
senza problemi. Quello più alto non arriva.
Il nodo con indirizzo più alto (quello che non arriva) dovrebbe comunque 
fermare la propria comunicazione se il proprio indirizzo è stato 
superato da un altro. Come potrebbe fare? Come al solito, cioè leggendo 
quello che trasmette?
Peccato che in questo caso mi tocca comunque fare modifiche hw alle 
schede, visto che dovrei collegare il TX della UART all'enable del 
driver del transceiver.

 una rete in CAN bus.
Sì sì, lo so. Ma l'hw RS485 ce l'ho già.
Ma sul CAN il problema dell'indirizzamento rimane... o no?
Strano che non esista nessuno standard (visto che ce ne sono una 
caterva) o implementazione che risolva tutti questi problemi su una RS485.

 driver del transceiver.
Già. Devi anche considerare che velocità ti serve e quanto overhead sul bus
e sui processori puoi permetterti.
Un piccolo appunto su quanto scritto da aa: è vero che il nodo, in teoria,
potrebbe generare il proprio indirizzo, ma in pratica servono algoritmi
ingombranti e che potrebbero comunque fallire. Insomma, in pratica non è
una buona idea, soprattutto con schede identiche.
L'avere un indirizzo fisso non implica necessariamente che bisogni
programmarlo, basta accendere le schede slave una per volta e fargli
asegnare l'indirizzo dal master.

 caterva) o implementazione che risolva tutti questi problemi su una RS485.
Perche' e' molto piu' semplice predefinire la topologia
di una rete a priori, come fa il PROFIBUS, oppure
avere gli slave con indirizzo di nodo letto da dip-switch
e quindi precablato, cosi il master fa solo uno scan...
Una gestione 'dinamica' come vuoi fare tu e' appunto
una eccezione, casi particolari che vengono risulti
per l' applicazione puntuale e stop.
A.

asegnare l'indirizzo dal master.
Oppure puoi mettere delle costanti di tempo abbastanza lunghe sul Reset, in modo
che la partenza sia differente per ogni periferica, basta che sia diversa per
pochi mSec che hai il tempo di assegnare dinamicamente l'indirizzo.
Attenzione in questo caso alla qualità degli elettrolitici, in una partita
sfigata c'erano dei 47 µF che dopo un po' avevano una corrente di perdita di
qualche µA e con una resistenza in serie da 220k non arrivavano neppure alla
soglia del Reset, cosa tra l'altro difficile da scoprire perchè succedeva con
determinate temperature, qui funzionavano e in sudamerica no.
--
ciao
  Stefano

 massimi per messaggio, piu' i 29 o 11 bit dell' ID.
Per risolvere ciò immagino che bisogna dividere i messaggi lunghi in 
pacchetti.

> modo totalmente asioncrono,
"Totalmente" è un termine un po' eccessivo, dato che è necessario che i
singoli bit siano sincronizzati. Usando un controller CAN non li vedi, ma
ci sono almeno 10 "quanta" temporali per ogni bit.

 ci sono almeno 10 "quanta" temporali per ogni bit.
Appunto. Ci pensa il controller e dal punto di vista degli
utenti del bus tutti i messaggi possono essere inviati in modo
completamente asincrono tra loro.
a.

 pacchetti.
Gia'. tutti i protocolli CAN prevedono modalita'
del generere.
In CANopen si usa una modalita' denomitata SDO(Service Data Object)
e ben due differenti modi: il segmented mode e il block mode.
Il secondo e' una aggiunta recente perche' il primo e'
risultato piuttosto arzigogolato e complesso da gestire :-)
A.

aa:


Certo, ma qui si parlava di come riutilizzare una RS485 già esistente e
pozz giustamente si lamentava del fatto che, per emulare il CAN, deve
tagliare due piste (sempre che una non sia addirittura un piano di massa) e
ricollegarle. Metterci un controller CAN sarebbe una procedura parecchio
più complessa.