Go Down

Topic: Autodiscovery degli slave modbus rtu (Read 1 time) previous topic - next topic

daniele_dll

Avrei la necessità di implementare un meccanismo di "autodiscovery" per semplificarmi la vita: in una rete multipunto rs485 basata su modbus vorrei essere in grado di riconoscere, automaticamente, i device collegati (tramite pooling, quindi effettuo una ricerca ogni TOT di tempo)

Premesso che sto usando un clone del MAX485 e premesso che nella rete multipunto sono presenti ESCLUSIVAMENTE dispositivi miei e non di terze parti, pensavo di implementare un meccanismo per l'autoriconoscimento molto banale!
In pratica pensavo: se mando un pacchetto con slave id a zero, quindi un pacchetto di broadcast, con codice di funzione 17 (Report Slave ID), un semplice e banale controllo che verifichi se il pin TX è HIGH mi metterebbe al sicuro da eventuali sorprese?
Stavo pensado, eventualmente, non di rispondere subito ma di rispondere dopo un tempo casuale, il problema però è come calcolare il tempo casuale visto che l'unico elemento che potrei usare è millis ... solo che se si accendono tutti gli arduino insieme (a causa di uno sbalzo di tensione oppure viene tolta e riattivata la corrente) sarà in tutti più o meno uguale

Cosa mi consigliate?
Software/Embedded/Web Developer, Linux Sys Admin

niki77

Ciao,
Tempo fà anche io stavo affrontando un problema del genere, ma io avrei voluto anche fare l'assegnazione automatica degli id ai singoli slave  :smiley-mr-green: (troppo ghiotto!)

L'unica soluzione che mi era venuta in mente era quella che il master invia sequenzialmente una richiesta di 'echo'(Report slave ID 0x11 del protocollo) specificando progressivamente tutti gli indirizzi  da 1 a 247 [0 è broadcast e 248-255 sono riservati), ed in questa maniera si accorgerebbe dalle risposte quanti e quali slave sono collegati ed operativi.
Ovviamente non è il massimo dell'efficienza, ma non credo si riesca a fare diversamente.
Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

daniele_dll

Avevo pensato di adottare questa soluzione inizialmente, però il fatto è che voglio cambiare leggermente la logica degli ID per passare il dato dalla lunghezza di 1 byte alla lunghezza di 4 byte (lo so, 4 miliardi è una cifra che non raggiungerò mai) perché in questo modo non mi devo preoccupare di far permettere all'utente finale e/o all'installatore che imposta il sistema di impostare lo slave id (dovrei farlo fare tramite dei jumper o un dip switch altrimenti)

E quest'aspetto mi interessa molto più dell'autodiscovery motivo per il quale non posso ciclarmi 4 miliardi di possibili slave id, la ricerca impiegherebbe, attenendo anche solo 500ms a richiesta inviata, una cifra astronomica (68 anni per ricerca è eccessivo :D)

In realtà al massimo nella mia rete ci staranno 32 slave, non di più, però il problema di fondo rimane

L'idea di controllare il pin RX per verificare se ci sono ricezioni in corso e quindi posticipare l'invio è malvagia? Lo so che non sono operazioni atomiche e ci sono sempre dei tempi di latenza ma è l'unica cosa che mi viene in mente. Al massimo potrei prevedere una logica di ACK dove il primo comando successivo alla risposta deve essere un comando SPECIFICO per quello slave id (anche un echo, o in generale un comando diagnostico) perché se non lo ricevo entro 10 secondi allora significa che è andato perso e devo reinviare il pacchetto per l'autodiscovery.

O magari, visto che tanto controllo sia il DE sia l'RE dell'ic, potrei tenere il DE in HIGH e l'RE(negato) in low e controllare ogni singolo byte che scrivo ... questo insieme al check del pin RX dovrebbe darmi un certo livello di sicurezza, no?
Anche se a dire la verità poi il problema si sposta sul master che si ritrova un un buffer tutto scassato, ma li mi sa che l'unica cosa che mi conviene fare è modificare il protocollo modbus per prevedere una sequenza di apertura ed una sequenza di chiusura posta dopo il CRC così da scartare tutti quei byte che non sono preceduti da una sequenza di apertura.
Così, in questo modo, se ci fosse il buffer dei dati del master corrotto non risponderei nemmeno a quello che mi ha fatto la richiesta corretta, ma dopo i 10 secondi di timeout quest'ultima verrebbe rispedita risolvendo il problema.
E negli slave, appena becco la prima collisione, fermo l'invio e lo riprogrammo dopo 1 secondo

Tra l'altro ho il problema di non poter fare un test a pieno regime perché attualmente sono in fase di progettazione e per avere la certezza di questa situazione dovrei collegare almeno un 15/20 arduino nella rete multipunto
Software/Embedded/Web Developer, Linux Sys Admin

niki77

Ciao, comunque vada, visto il casino, sarà un successo!!

Quello che non capisco è il perchè portare l'id da 1 byte a 4(ricordati che devi comunque modificare il protocollo perchè di suo non è previsto!) visto che userai massimo 32 terminali.
Per il discorso dell'assegnazione automatica dell'id ti capisco, del resto ci ho provato anche io  :smiley-mr-green: , non con tantissima energia però un paio di ragionamenti sopra li avevo fatti.
Non credo che riuscirai a risolvere il problema delle collisioni solo implementandoti qualche magheggio hardware verificando lo stato delle linee, delr esto come dici tu, esiste sempre la possibilità che due o più slave facciano sulla stessa linea la stessa operazione nello stesso identico istante ( o perlomeno in un intervallo tale il cui nessuno  si accorge che un altro è in trasmissione).
Una soluzione interessante potrebbe essere quella di vedere se si riesce a portare la logica di funzionamento del protocollo one wire su linea 485.
Per quel protocollo è prevista una logica molto interessante per stabilire univocamente quale sia il primo slave che deve rispondere alla chiamata.
Non risolveresti in pieno il problema in quanto ti rimarrebbe il fatto che perlomeno all'avvio del singolo slave, esso si 'autonomini' con un certo id e sperare che nella rete non vi sia un altro 'autonominato' alla stessa maniera, ma con un codice a 11 byte è sicuramente mooooolto più difficile che con uno singolo!
Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

daniele_dll


Ciao, comunque vada, visto il casino, sarà un successo!!

Quello che non capisco è il perchè portare l'id da 1 byte a 4(ricordati che devi comunque modificare il protocollo perchè di suo non è previsto!) visto che userai massimo 32 terminali.


Il sistema su cui sto lavorando dovrà essere, alla fine, prodotto in serie e quindi una delle cose per me necessarie è evitare questa seccatura all'installatore che, altrimenti, dovrà tenersi una mappa degli slave e dei loro ID per evitare accavallamenti

Quote

Per il discorso dell'assegnazione automatica dell'id ti capisco, del resto ci ho provato anche io  :smiley-mr-green: , non con tantissima energia però un paio di ragionamenti sopra li avevo fatti.
Non credo che riuscirai a risolvere il problema delle collisioni solo implementandoti qualche magheggio hardware verificando lo stato delle linee, delr esto come dici tu, esiste sempre la possibilità che due o più slave facciano sulla stessa linea la stessa operazione nello stesso identico istante ( o perlomeno in un intervallo tale il cui nessuno  si accorge che un altro è in trasmissione).


si, infatti è questa la mia preoccupazione :D

Quote

Una soluzione interessante potrebbe essere quella di vedere se si riesce a portare la logica di funzionamento del protocollo one wire su linea 485.
Per quel protocollo è prevista una logica molto interessante per stabilire univocamente quale sia il primo slave che deve rispondere alla chiamata.
Non risolveresti in pieno il problema in quanto ti rimarrebbe il fatto che perlomeno all'avvio del singolo slave, esso si 'autonomini' con un certo id e sperare che nella rete non vi sia un altro 'autonominato' alla stessa maniera, ma con un codice a 11 byte è sicuramente mooooolto più difficile che con uno singolo!


non mi interessa fargli prendere l'id da solo, lo voglio assegnare io a priori (è proprio il motivo per cui voglio ingrandire la dimensione dello slave id passandolo a 4 byte, una volta che faccio la modifica trovo poco sensato portarlo a 3 byte)
Però mi pare di capire che la collisione sul bus nel protocollo 1-wire è gestita interamente a livello software (o almeno così dice wikipedia)

Software/Embedded/Web Developer, Linux Sys Admin

Go Up