Come far comunicare due o più schede Arduino o EDI su seriale (bus) RS485 ?
In questo Tutorial mostreremo come far comunicare tra loro più schede Arduino o ETA BETA EDI utilizzando la comunicazione seriale RS485 che può essere sfruttata in un progetto domotico fai da te.
In questo Tutorial mostreremo come far comunicare tra loro più schede Arduino o ETA BETA EDI utilizzando la comunicazione seriale RS485 che può essere sfruttata in un progetto domotico fai da te.
Ciò che faremo è comandare i 2 relè della scheda con ID1 con i 2 button della scheda con ID2 ed allo stesso modo con i 2 button della scheda con ID2 comanderemo i relè della scheda ID1 .
![]() |
Collegamento di tipo seriale RS485 con resistenza di terminazione RT |
- Cos’è la connessione seriale rs485?
Altro non è che un sistema di connessione a due fili denominati A e B, HALF DUPLEX, che sfrutta la trasmissione differenziale del segnale tra i 2 fili, cioè la differenza di tensione tra i due cavi (almeno di 0,2Volt) è il dato trasmesso.
Perchè utilizzare questo tipo di comunicazione (BUS)?![]() |
Segnale Differenziale A-B |
- Può arrivare a distanze di comunicazione maggiori rispetto agli altri bus (1200m)
- Possono essere connesse da 2 a 256 schede a seconda del tipo di driver.
- Scarsamente sensibile ai disturbi.
Lo svantaggio di questo tipo di comunicazione seriale RS485 è quello di non essere un bus ma solo un trasmettitore e ricevitore di segnale, va quindi realizzato un BUS a seconda delle necessità progettuali. Quindi dovremmo scriverci noi il protocollo di comunicazione da utilizzare.
Questo sistema di comunicazione è attualmente quello maggiormente utilizzato sia nei sistemi domotici che di allarme.
- Di cosa abbiamo bisogno?
Per realizzare il nostro progetto abbiamo bisogno:
- ELENCO MATERIALE PER TUTORIAL CON ARDUINO
- n.2 Schede Arduino 2009/UNO
- n.2 Max485 o ADM485
- n.2 NE555
- n.2 Diodi 1N4001
- n.2 Resistenze da 3.9 Kohm
- n.4 Condensatori da 10 nF
- n.2 Resistenze da 100 ohm
- n°4 Resistenze da 1.5K
- n°8 Resistenze da 1K
- n°4 Transistor BC337
- n°4 Diodi 1N4148
- n.1 Breadboard bella capiente
- Vari cavetti per bradboard
- n.2 Cavi USB
- ELENCO MATERIALE PER TUTORIAL CON ETA BETA EDI
- n.2 Schede ETA BETA EDI
- n.2 Cavi Usb
- n.2 cavetti per collegare le due schede
Il chip utilizzato per realizzare la comunicazione RS485 è il chip ADM1485 (max 485), un ricetrasmettitore differenziale conforme con lo Standard RS-485 , questo chip contiene un driver di linea differenziale ed un ricevitore di linea differenziale che possono essere attivati in modo indipendente.
Per gestire la comunicazione multimaster andremo ad aggiungere un NE555 in configurazione monostabile che commuta l’ ADM1485 dalla trasmissione alla ricezione e viceversa.
Dalla seriale viene “sentito” il bit di start (fronte di discesa) e l’uscita del NE555 commuta l’ADM in invio, e viceversa, cioè quando arriva il bit di stop l’ADM viene commutato in ricezione. Grazie a questo componente le schede possono commutare automaticamente il loro stato da MASTER a SLAVE e viceversa, ciò evita la gestione complessa della commutazione via software.
Questa configurazione garantisce il funzionamento anche in caso di guasto di uno dei moduli presenti nel sistema.
- Schemi Elettrici
Ecco gli schemi realizzati con FRITZING per Arduino ed ETA BETA EDI:
Con EDi posizionare Dip switch DS2 , 7 e 8 in ON per abilitare la RS485 al termine della programmazione.
Schema elettrico per Arduino parte BUS:
Schema Fritzing Relè + Switch Button per Arduino:
Con EDi posizionare Dip switch DS2 , 7 e 8 in ON per abilitare la RS485 al termine della programmazione.
Schema elettrico per Arduino parte BUS:
Schema Fritzing Relè + Switch Button per Arduino:
- Sketch uguale sia per Arduino 2009 sia per ETA BETA EDI
Gli Sketch caricati su entrambe le schede sono uguali, l’unica differenza è l’indirizzo della scheda (vedi parte evidenziata in giallo).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | const int buttonPin1 = 5; // the number of the pushbutton pin const int buttonPin2 = 6; // the number of the pushbutton pin int ledPin = 13; // the number of the LED pin int rel1 = 7; int rel2 = 8; boolean i = false; boolean j = false; int buttonState1; // the current reading from the input pin int buttonState2; // the current reading from the input pin int relState1 = LOW; int relState2 = LOW; int lastButtonState1 = LOW; // the previous reading from the input pin int lastButtonState2 = LOW; // the previous reading from the input pin long lastDebounceTime1 = 0; // the last time the output pin was toggled long lastDebounceTime2 = 0; // the last time the output pin was toggled long debounceDelay1 = 50; // the debounce time; increase if the output flickers long debounceDelay2 = 50; // the debounce time; increase if the output flickers void setup() { pinMode(buttonPin1, INPUT); pinMode(buttonPin2, INPUT); pinMode(rel1, OUTPUT); pinMode(rel2, OUTPUT); Serial.begin(9600); } void loop() { int reading1 = digitalRead(buttonPin1); // LEGGERE VALORE BUTTON1 int reading2 = digitalRead(buttonPin2); // LEGGERE VALORE BUTTON2 // PRESSIONE DEL BUTTON 1 if (reading1 != lastButtonState1) { // reset the debouncing timer lastDebounceTime1 = millis(); } if ((millis() - lastDebounceTime1) > debounceDelay1) { if (reading1 != buttonState1) { buttonState1 = reading1; if (buttonState1 == HIGH) { i= !i; // MODIFICA VALORE VARIABILE if (i == true){ String stringa1 = ""; stringa1 += ("b"); // COMANDO PER ATTIVARE VOID SU SCHEDA DESTINATARIO stringa1 += ("2"); //INDIRIZZO SCHEDA DESTINATARIO stringa1 += ("1"); //ATTACCA RELE' 1 SCHEDA 2 Serial.println(stringa1); } if (i == false){ String stringa1 = ""; stringa1 += ("b"); // COMANDO PER ATTIVARE VOID SU SCHEDA DESTINATARIO stringa1 += ("2"); //INDIRIZZO SCHEDA DESTINATARIO stringa1 += ("0"); //STACCA RELE' 1 SCHEDA 2 Serial.println(stringa1); } } } } lastButtonState1 = reading1; // PRESSIONE DEL BUTTON 2 if (reading2 != lastButtonState2) { // reset the debouncing timer lastDebounceTime2 = millis(); } if ((millis() - lastDebounceTime2) > debounceDelay2) { if (reading2 != buttonState2) { buttonState2 = reading2; if (buttonState2 == HIGH) { j= !j; // MODIFICA VALORE VARIABILE if (j == true){ String stringa2 = ""; stringa2 += ("b"); // COMANDO PER ATTIVARE VOID SU SCHEDA DESTINATARIO stringa2 += ("2"); //INDIRIZZO SCHEDA DESTINATARIO stringa2 += ("3"); //ATTACCA RELE' 2 SCHEDA 2 Serial.println(stringa2); } if (j == false){ String stringa2 = ""; stringa2 += ("b"); // COMANDO PER ATTIVARE VOID SU SCHEDA DESTINATARIO stringa2 += ("2"); //INDIRIZZO SCHEDA DESTINATARIO stringa2 += ("2"); //STACCA RELE' 2 SCHEDA 2 Serial.println(stringa2); } } } } lastButtonState2 = reading2; if (Serial.available() > 0 ) { //LETTURA DA SERIALE int ser; ser=Serial.read(); switch (ser) { case 'b': comando(); break; } } } //FINE LOOP void comando(){ delay(50); // questo delay è indispensabile!! if (Serial.available()) { int a = Serial.read()-48; int c = Serial.read()-48; //viene sottratto 48 per rientrare nel range dei caratteri numerici ASCII (0=49,1=50....9=58) digitalWrite (13, HIGH); if (a==2){ if(c == 0){ digitalWrite (7, LOW); } if(c == 1){ digitalWrite (7, HIGH); } if(c == 2){ digitalWrite (8, HIGH); } if(c == 3){ digitalWrite (8, LOW); } } } } //FINE VOID COMANDO |
N.B.Quando viene caricato il firmware su Arduino o sulla scheda ETA BETA EDI bisogna staccare il max485.
- Spiegazione dello Skecth uguale per entrambe le schede
Parte 1 - Dichiarazioni Variabili:
Come da schema sia per Arduino sia per ETA BETA EDI abbiamo i button 1 e 2 collegati rispettivamente ai pin 5 e 6 ed i 2 relè ai pin 7 e 8.
Inizializziamo le due variabili booleane “i” e “j” (assumono 2 valori: vero e falso) come FALSE, e lo stato iniziale dei Button e dei relè come LOW.
Introduciamo anche il tempo di debounce per la funzione anti-rimbalzo indispensabile per il corretto funzionamento dei BUTTON.
Parte 2 - Void Setup
Impostiamo i button come INPUT ed i relè come OUTPUT ed ovviamente inizializziamo la seriale a 9600.
Parte 3 - Void LOOP
Con le dichiarazioni:
int reading1 = digitalRead(buttonPin1)
int reading2 = digitalRead(buttonPin2)
andiamo a leggere i valori in ingresso dati dai pulsanti.
Quando premiamo il button 1 e lo portiamo in HIGH ed è trascorso il tempo impostato viene cambiato il valore della variabile booleana “i” e sulla seriale andremo a scrivere la stringa: b21 oppure b20 a seconda se la booleana è vera o è falsa.
La prima lettera della stringa attiva il VOID comando, il primo numero è l’INDIRIZZO del modulo destinatario ed il terzo numero fa eseguire una determinata operazione, nel nostro caso:
0 - Stacca il primo relè
1- Attacca il primo relè
2- Stacca il secondo relè
3- Attacca il secondo relè
Lo stesso accade quando premiamo il button 2.
Nella seconda parte del LOOP andiamo ad intercettare i valori letti dalla seriale:
Serial.available
La prima lettera letta sulla seriale è la b che attiva il void comando creato nello switch case.
Parte 4 - Void COMANDO
Questo VOID si attiva quando IL DESTINATARIO legge sulla seriale la lettera b.
int a = Serial.read()-48;
int b = Serial.read()-48;
Queste due dichiarazioni permettono di identificare i numeri successivi alla lettera b necessari per capire le operazioni da fare
N.B. viene sottratto 48 per rientrare nel range dei caratteri numerici ASCII (0=49, 1=50 ...)
Se il primo numero letto sulla seriale è uguale all’indirizzo della scheda va avanti.
Buon lavoro!
Christian Acqua
Massimo Pinto
Buon lavoro!
Christian Acqua
Massimo Pinto
perche' il segnale per ricevere o trasmettere e' gestito da un timer e non da arduino ?
RispondiElimina