Arduino + RS485 + Protocollo comunicazione

Ciao a tutti,

Come anticipato in altri post mi sto accingendo a progettare una rete domotica dove installerò diversi arduini che dovranno collegarsi tra loro attraverso la RS485 in modalità MASTER e SLAVE.

Ho visto in giro che ci sono diversi protocolli tra cui il MODBUS e CANBUS (altri?).

Vorrei evitare di riscrivere tutto da ZERO e utilizzare quello ce già c'è anche per uniformarmi agli standard. Gradirei un consiglio su quale usare e se c'è documentazione/esempi/tutorial da utilizzare.

Ringrazio anticipatamente tutti per la pazienza.

Alberto

inter1908:
Ho visto in giro che ci sono diversi protocolli tra cui il MODBUS e CANBUS (altri?).

Canbus richiede del hardware aggiuntivo, non è compatibile con la RS485 a livello hardware, inoltre è molto complesso come protocollo, però è molto robusto ed affidabile, esistono appositi controller CAN che gestiscono loro quasi tutto.
MODBUS è un protocollo open royaltyfree, è indipendente dal bus fisico, è molto usato a livello industriale, è ben documentato, esistono le librerie per Arduino pronte all'uso.
Se opti per MODBUS è la scelta giusta.

astrobeed:
Canbus richiede del hardware aggiuntivo, non è compatibile con la RS485 a livello hardware, inoltre è molto complesso come protocollo, però è molto robusto ed affidabile, esistono appositi controller CAN che gestiscono loro quasi tutto.
MODBUS è un protocollo open royaltyfree, è indipendente dal bus fisico, è molto usato a livello industriale, è ben documentato, esistono le librerie per Arduino pronte all'uso.
Se opti per MODBUS è la scelta giusta.

Scritta così sembra che la scelta debba ricadere obbligatoriamente verso il MODBUS :).
Se hai documentazione/link da girare ad una persona che approccia per la prima volta al tema te ne sarei grato.

Grazie,
A.

inter1908:
Se hai documentazione/link da girare ad una persona che approccia per la prima volta al tema te ne sarei grato.

Con google trovi moltissimo sul modbus, un buon punto di partenza è questo pdf.

MODBUS è nato nel mondo PLC ed il suo uso per la domotica è per alcuni versi una forzatura, dovuta più che tutto perché i primi sistemi domotici erano di fatto PLC (o meglio, molti sviluppatori arrivano prevalentemente da quel mondo e hanno riutilizzato le conoscenze acquisite) e perché di fatto era l'unica strada percorribile se non si vuole finire nel baratro dei protocolli proprietari.

Ne consegue che su MODBUS serve documentarsi un po' prima di buttarsi a scrivere codice. Niente di complicato però, visto che comunque esistono librerie già fatte da cui attingere.

Personalmente sento proprio l'esigenza della nascita di qualcosa di più moderno, orientato ai moderni microcontrollori e tipi di comunicazione (non esiste solo la seriale...) e non tanto ai PLC, che ad esempio integri meglio la gestione delle collisioni in modalità multimaster, le priorità, la criptazione del bus ecc ecc ma seppur con MODBUS sembri di far un salto 20 anni indietro nel tempo, di fatto fa ancora egregiamente il suo dovere.

Molto dipende anche da cosa vuoi fare. Modbus ha il vantaggio di essere molto supportato anche da oggetti di terze parti, quindi se non hai qualcosa di estrememanete complesso o critico dal punto di vista della sicurezza, MODBUS va benissimo

Rimane il fatto che MODBUS è un protocollo, quindi devi cumunque fare la parte "fisica" della comunicazione.
In tal caso, la cosa più semplice è un semplice convertitore da seriale TTL dell'Arduino a RS485, cosa che si fa con un solo integrato aggiuntivo (es. MAX485)

La connessione fisica va poi protetta da extratensioni e altre brutte cose che capitano ai cavi che girano dentro i muri di una casa

In sostanza, più che consigliare Modbus, io sconsiglio di infilarsi in protocolli di comunicazione proprietari. E (purtroppo) Modbus è una tra le pochissime alternative a tua disposizione.

Nel caso in cui il tuo sistema domotico non sia di tipo multimaster, ma solo un master e tanti slave, puoi prendere in cosiderazione il DMX512 (quello che si usa in campo teatrale per gestire i fari per intenderci)

nabla:
MODBUS è nato nel mondo PLC ed il suo uso per la domotica è per alcuni versi una forzatura, dovuta più che tutto perché i primi sistemi domotici erano di fatto PLC (o meglio, molti sviluppatori arrivano prevalentemente da quel mondo e hanno riutilizzato le conoscenze acquisite) e perché di fatto era l'unica strada percorribile se non si vuole finire nel baratro dei protocolli proprietari.

Ne consegue che su MODBUS serve documentarsi un po' prima di buttarsi a scrivere codice. Niente di complicato però, visto che comunque esistono librerie già fatte da cui attingere.

Personalmente sento proprio l'esigenza della nascita di qualcosa di più moderno, orientato ai moderni microcontrollori e tipi di comunicazione (non esiste solo la seriale...) e non tanto ai PLC, che ad esempio integri meglio la gestione delle collisioni in modalità multimaster, le priorità, la criptazione del bus ecc ecc ma seppur con MODBUS sembri di far un salto 20 anni indietro nel tempo, di fatto fa ancora egregiamente il suo dovere.

Molto dipende anche da cosa vuoi fare. Modbus ha il vantaggio di essere molto supportato anche da oggetti di terze parti, quindi se non hai qualcosa di estrememanete complesso o critico dal punto di vista della sicurezza, MODBUS va benissimo

Rimane il fatto che MODBUS è un protocollo, quindi devi cumunque fare la parte "fisica" della comunicazione.
In tal caso, la cosa più semplice è un semplice convertitore da seriale TTL dell'Arduino a RS485, cosa che si fa con un solo integrato aggiuntivo (es. MAX485)

La connessione fisica va poi protetta da extratensioni e altre brutte cose che capitano ai cavi che girano dentro i muri di una casa

http://masters.donntu.org/2010/fkita/loginov/library/other2pic3.png

In sostanza, più che consigliare Modbus, io sconsiglio di infilarsi in protocolli di comunicazione proprietari. E (purtroppo) Modbus è una tra le pochissime alternative a tua disposizione.

Nel caso in cui il tuo sistema domotico non sia di tipo multimaster, ma solo un master e tanti slave, puoi prendere in cosiderazione il DMX512 (quello che si usa in campo teatrale per gestire i fari per intenderci)

Grazie.
Mi chiedo sia reale poi la possibilità di collegare i propri progetti a servizi di terze parti e se non si finisce sempre per svilupparsi tutto in loco. Anche perchè dovresti conoscere come il protocollo della terza parte e strutturato. Non basta aver applicato il modbus. Corretto?

A questo punto potrebbe avere senso un protocllo custom?

Ad esempio avevo visto (non usato personalmente) dei monitor touch basati su MODBUS: erano configurabili sul come mappare i diversi oggetti e icone.
L'uscita era TTL, quindi per interfacciarli, almeno in teoria serviva solo passare a RS485 nello stesso modo in cui fai già per il microcontrollore, e perdere un po' di tempo a confiurare l'interfaccia (caricare icone, definire stati ecc)

Con un protocollo proprietario non sarebbe stato possibile.

MODBUS NON è la risposta a tutte le esigenze. E' la risposta a una domanda del tipo "come faccio ad avere una comunicazione decente tra due oggetti senza perderci secoli a programmare?" Non sempre è quella la domanda che uno si fa... Sarebbe bello se ci fosse un protocollo simile ma più evoluto, supportato da tanti produttori, ma non c'è (o se c'è non lo conosco).

I protocolli proprietari non sono in sé il male assoluto (li ho usati anche io in alcuni casi!) ma hanno 2 prerequisiti.

1 non avere né ora né in futuro oggetti di terze parti connesse (o nel caso, saper scrivere il codice che possa fare da interfaccia)
2 essere certo che sia affidabile, questo è il punto dolente.

Chiunque sa prendere il serial out, trasferire su RS485 e riprendere il dato al contrario dall'altro micro.
Da una parte mandare in uscita "ACCENDI001" e "SPEGNI001" e dall'altra parte fare un semplice controllo che la stringa in arrivo sia una oppure l'altra e decide se attivare o meno un relé

Il problema (per assurdo) è proprio che una cosa cosa così funziona al primo colpo! Uno si illude che sia cosa semplice.

Però poi si va nel mondo reale e le cose funzionano bene il 98% del tempo, poi di tanto in tanto vedi il relé che si attiva senza ragioni, o ritardi anomali da quando premi il pulsante da una parte e si eccita il relé dall'altra

Un protocollo di comunicazione deve saper gestire gli errori di comunicazione. Ad esempio con un checksum.
Se dall'altra parte non hai un checksum identico, non eseguire il comando.

Però così perdi il comando...

Allora aggiungi il comando acknowledge indietro per dire ("ok ricevuto" piuttosto che "ritrasmetti")

Ma anche il comando all'indietro deve arrivare privo di errori. Cosa fa il master se non riceve acknowledge?

E se lo riceve come "ritrasmetti", deve davvero ritrasmettere? Eh sì perché se la comuncazione è un continuo rimpallarsi di "non ho capito, ritrasmetti" stai occupando tutta la banda in comunicazioni spazzatura e di fatto stai bloccando tutti gli altri dispositivi!

A proposito di altri dispositivi... come fare a far parlare uno alla volta? Come capisci che il bus è libero?

E come gestisci due che per errore hanno occupato il bus in contemporanea perché hanno visto il bus libero nello stesso momento e si sono messi a tramettere?
A chi dei due fai ritrasmettere il dato per primo? e dopo quanto tempo al secondo? Ma se il primo si dilunga perché la linea è disturbata, come ritardi ulteriormente l'attesa al secondo?

Poi ci sono fattori prettamente legati ai dati da trasmettere:

Come rappresento al meglio l'intera struttura di dati che è necessario trasferire da un controller ad un altro?
Indirizzi? quanti?
Comando fissi? Quali?
E se un domani ho bisogno di un parametro in più?

Come posso garantire la scalabilità (aggiungere funzioni senza riprogrammare tutti i dispositivi ma solo quelli strettamente interessati dalla nuova funzione)?

Come garantisco la sicurezza del dato? Mica vorrai passare il codice dell'antifurto in chiaro sui cavi???
Come recupero un dato parzialmente sporcato da disturbi? Devo per forza ritrasmettere?

Insomma... sperimentare in questo campo è molto bello e si imparano tante cose, ma come vedi non è proprio facile fare un protocollo che funzioni davvero.

E per inciso, nemmeno MODBUS ha tutte queste cose... spesso si devono fare dei compromessi, e l'accettabilità di tali compromessi è funzione del progetto e del contesto.

Quando si è passati a MODBUS su PLC, alcune delle cose che ho scritto non erano né una priorità né una esigenza. E come ti dicevo, è solo una possibilità di fare comunicazioni semplici in modo semplice, aperta facilmente ad estensioni di terze parti. NON è detto che sia quello che cerchi.

Intanto ho trovato un progettino documentato molto bene QUI
Non è un MODBUS ma un custom ... Almenosi capisce cosa voleva fare :slight_smile:

Nella sua semplicità ha molti punti a favore, specie nel codice che ho visto a fine pagina.
Direi che come punto di inizio è valido e discretamente robusto.

Se non hai applicazioni troppo critiche come risorse (es. numero elevato di sensori, alta occupazione in termini di tempo dedicato alla comunicazione in rapporto al tempo a riposo) o come sicurezza (non hai da gestire movimentazioni automatiche che potrebbero ferire le persone) allora potrebbe già essere il tuo protocollo "definitivo".

Non ho visto (ma magari c'è e mi è sfuggito) un "auto retrasmit" in sostanza, se una chiamata è persa, la sua ritrasmissione in automatico.
Se non c'è dovrai gestirla tu (es. se entro x millisecondi non hai risposte, accodi nuovamente il messaggio, per un max di n volte e poi vai in errore)

PS
personalemte uso le seriali al contrario: RS485 la affido alla seriale hardware, il debug alla seriale software (con convertitore TTL/USB a parte). Questo perché la seriale software non ha buffer, se il processore è molto impegnato, si perde pezzi di comunicazione per strada
Un miglioramento della libreria sarebbe a mio avviso il passare tutto all'uso della seriale hardware

nabla:
Nella sua semplicità ha molti punti a favore, specie nel codice che ho visto a fine pagina.
Direi che come punto di inizio è valido e discretamente robusto.

Se non hai applicazioni troppo critiche come risorse (es. numero elevato di sensori, alta occupazione in termini di tempo dedicato alla comunicazione in rapporto al tempo a riposo) o come sicurezza (non hai da gestire movimentazioni automatiche che potrebbero ferire le persone) allora potrebbe già essere il tuo protocollo "definitivo".

Non ho visto (ma magari c'è e mi è sfuggito) un "auto retrasmit" in sostanza, se una chiamata è persa, la sua ritrasmissione in automatico.
Se non c'è dovrai gestirla tu (es. se entro x millisecondi non hai risposte, accodi nuovamente il messaggio, per un max di n volte e poi vai in errore)

PS
personalemte uso le seriali al contrario: RS485 la affido alla seriale hardware, il debug alla seriale software (con convertitore TTL/USB a parte). Questo perché la seriale software non ha buffer, se il processore è molto impegnato, si perde pezzi di comunicazione per strada
Un miglioramento della libreria sarebbe a mio avviso il passare tutto all'uso della seriale hardware

L'ambito su cui lo utilizzerò è sicuramente domotico : controllo luci/sensori temperatura/serrande/antifurto/etc. Quindi mi verrebbe da dire che le vite umane sono salve...

Domani cerco di guardare meglio il codice e fornirti anche delle risposte.

Francamente non ho capito come e perché inverti le logiche delle seriali.

nabla:
personalemte uso le seriali al contrario: RS485 la affido alla seriale hardware, il debug alla seriale software (con convertitore TTL/USB a parte). Questo perché la seriale software non ha buffer, se il processore è molto impegnato, si perde pezzi di comunicazione per strada
Un miglioramento della libreria sarebbe a mio avviso il passare tutto all'uso della seriale hardware

Sicuramente, la seriale software per la connessione ad un bus è sempre in bilico tra "funziona/non funziona, se si utilizza lIDE arduino l'ideale sarebbe utilizzare sempre MC con almeno 2 seriali hardware, se questo non è possibile utilizzando avrstudio si accede al micro per la programmazione mediante ISP e se si ha bisogno di un monitor in uscita ....una seriale software su un pin libero

icio:
Sicuramente, la seriale software per la connessione ad un bus è sempre in bilico tra "funziona/non funziona, se si utilizza lIDE arduino l'ideale sarebbe utilizzare sempre MC con almeno 2 seriali hardware, se questo non è possibile utilizzando avrstudio si accede al micro per la programmazione mediante ISP e se si ha bisogno di un monitor in uscita ....una seriale software su un pin libero

Non ho le competenze per comprendere ciò che scrivete. Se mi rimandare a qualche articolo / esempio studio e vi comprendo.

In buona sostanza, una seriale hardware è gestita a basso livello dal microcontrollore in modo autonomo dal resto del flusso di calcolo del codice che scrivi tu in Arduino.
In altre parole, il timing (la seriale per funzionare a dovere deve rispettare precisi tempi in cui i livelli logici sono alti o bassi), il buffer di ingresso (spazio in cui accantonare i dati in arrivo dal flusso seriale in attesa di essere processati dal software) e altre cose (interrupt, aggiunta di bit di controllo ecc) è tutto quanto gestito solo configurando opportuni registri in fase di inizializzazione. Nel codice che si scrive in Arduino, c'è solo la parte di analisi del dato ricevuto.
Se il codice scritto occupa il processore, tendenzialmente non si perdono comunicazioni, perché appena si libera dal processo ingombrante, va a recuperare dati dal buffer e li analizza.
Perdi dati solo se il processore è occupato per lunghi periodi, ma in quel caso... è il software scritto male, non la seriale che non va.

Una seriale software ha tutto quanto gestito dal codice. Questo significa che se il processore è occupato mentre arriva una comunicazione, non se ne accorge. Si accorgerà di una comunicazione in atto e tratterà il dato appena sarà libero, ma è possibile che si sia già perso qualche bit per strada. La libreria software serial è scritta molto bene e limita al minimo la perdita di dati, ma è intrinseco nel tipo di architettura quella di potenzialmente perdere dati quando il processore ha molto da fare.

Come avrai capito, la criticità è prevalentemente nei dati in ingresso al processore e non quelli in uscita. Gli eventi in uscita sono gestibili in maniera sincrona (il processore mentre manda dati in seriale, non fa altro). Gli eventi in ingresso non lo sono (non sai mai quando il dato arriverà e non puoi far stare tutto il tempo in attesa di dati altrimenti blocchi tutti gli altri processi)

Visto che il debug è tendenzialmente un dato in uscita e non in ingresso, è un abuso di risorse usare la seriale hardware.

La seriale hardware in (quasi) tutti gli Arduino è connessa via USB al computer, tramite un convertitore rs232 ttl/USB incluso nella sched, la si usa quindi per comodità a debuggare.

Ma in applicazioni dove la seriale è critica, come la domotica, allora è preferibile usare la seriale hardware per comunicare con i vari dispositivi e relegare il debug ad una seriale software

Il dato seriale software esce però su un pin del microcontrollore a scelta, ma comunque non connesso al convertitore interno, questo dato non è leggibile direttamente dal PC, quindi serve un convertitore rs232 ttl/USB

La configurazione più affidabile in termini di domotica è quindi

seriale hardware con due usi: inizialmente per programmare il microcontroller via usb, poi una volta connessa alla rete RS485 la si usa per la comunicazione primaria

seriale software: per il debug tramite convertitore esterno.

Purtroppo solo poche schede Arduino hanno almeno due seriali hardware distinte, in questi casi allora si usa la seriale hardware connessa al convertitore per il debug e la seriale hardware non connessa come comunicazione RS485

Come fatto giustamente notare, i microcontrollori nascono con delle porte di programmazione che hanno ampie funzionalità di debug native.

L'idea dietro Arduino è quella di non usare questa porta (perché necessita un programmatore esterno) ma usare un bootloader per caricare il codice. Questo implica che è possibile programmare e debuggare via seriale, ma non vuol dire che la porta di programmazione sia fuori uso... quindi con gli strumenti giusti si possono fare dei debug decisamente più avanzati passando da tale porta.

Non ho esperienza diretta a riguardo, ma ne ho tanta con microcontrollori di altre marche: in quel caso si possono vedere durante il debug interi blocchi di memoria e lo stato dei registri in tempo reale. In altre parole milioni di informazioni in più di quello che si può sapre da un debug seriale.
Sono abbastanza certo che il tutto sia replicabile anche sui microcontrollori usati da Arduino, solo servono gli strumenti (software e hardware) giusti, ma ovviamente la fase di partenza per uno che inizia è più complicata.

nabla:
Sono abbastanza certo che il tutto sia replicabile anche sui microcontrollori usati da Arduino, solo servono gli strumenti (software e hardware) giusti, ma ovviamente la fase di partenza per uno che inizia è più complicata.

Si anche gli AVR usati su Arduino dispongono del supporto per il debug hardware, però serve un apposito hardware esterno, il minimo possibile è l'ottimo AVR Dragon di Atmel che fa sia da programmatore che debugger.
Il debug hardware si può fare tramite l'ambiente di sviluppo di Atmel, Atmel studio, ed è free, se si utilizzano i tool di Atmel, altri ambienti di sviluppo non Atmel, tutti a pagamento, possono utilizzare tool hardware proprietari per il debug.
L'IDE di Arduino attualmente non supporta il debug hardware, sulla ZERO hanno inserito un apposito chip aggiuntivo, l'EDBG di Atmel (una mcu appositamente programmata) che fornisce il supporto hardware per il debug, però non è supportato dal IDE, tocca comunque usare Atmel Studio.

nabla:
Una seriale software ha tutto quanto gestito dal codice. Questo significa che se il processore è occupato mentre arriva una comunicazione, non se ne accorge. Si accorgerà di una comunicazione in atto e tratterà il dato appena sarà libero, ma è possibile che si sia già perso qualche bit per strada. La libreria software serial è scritta molto bene e limita al minimo la perdita di dati, ma è intrinseco nel tipo di architettura quella di potenzialmente perdere dati quando il processore ha molto da fare.

Non ho esaminato il software della seriale fornito con arduino ma penso che usi un interrupt a livello di singolo bit, quindi quando perde dati perde a livello di carattere e non di bit
comunque tutto giusto quello che dici :slight_smile:

Giusto per condivisione, ho trovato questa libreria che sembra essere molto interessante.

Non ho ancora con me i MAX485 per iniziare le attività di test ...