Ben ritrovati sul 9minuti.it oggi vedremo insieme come far comunicare due schede Arduino o, come mi piace scherzosamente chiamare, arduini.
Faremo comunicare due arduini con la comunicazione seriale che è quella utilizzata anche nelle porte USB (Universal Serial Bus).
Una volta imparata la comunicazione seriale tra due Arduino con i pin RX e TX (che nella scheda coincidono con il PIN 0 e 1) potremmo far comunicare fra di loro qualsiasi dispositivo.
Se ci pensate un attimo lo stesso monitor seriale che utilizzate nell’IDE di Arduino per visualizzare i messaggi nel nostro microcontrollore ha la parola seriale.
Arduino attraverso il metodo
serial.write();
invia i messaggi che abbiamo impostato ma non sa chi ci sarà a riceverli.
Se mettessimo un arduino che manda dati e un arduino configurato in modo da leggere i dati che vengono inviati sulla porta seriale riusciremmo ad inviare i dati da una scheda all’altra.
Per far questo abbiamo innanzitutto bisogno di due schede Arduino e dobbiamo caricare due sketch differenti sui due Arduini: uno sketch per il mittente e uno per il destinatario.
Non effettuare alcun collegamento fra i due arduini per il momento.
Indice
Mittente
//Sketch scritto da Alessandro Oppo per 9minuti.it //collegamenti rx-tx tx-rx gnd-gnd char stringa[20] = "Hello world"; void setup() { Serial.begin(9600); } void loop() { Serial.write(stringa, 20); delay(1000); }
4 – Dichiariamo un array di caratteri chiamato stringa
8 – Inizializziamo la Serial con il metodo begin
12 – Scriviamo sulla seriale la nostra stringa. Il secondo parametro del metodo write è il numero di caratteri che andremo a scrivere e deve essere superiore a quelli della stringa che stiamo inviando (altrimenti ce la taglia in due). Non è un parametro necessario.
14 – Delay che ci permette di eseguire il loop ogni secondo
Destinatario
Ci occuperemo ora del destinatario, che è anche la parte più interessante.
//Sketch scritto da Alessandro Oppo per 9minuti.it //collegamenti rx-tx tx-rx gnd-gnd char stringa[20]; void setup() { Serial.begin(9600); } void loop() { while (Serial.available() == false) { Serial.readBytes(stringa, 20); Serial.write(stringa); } delay(1000); }
13 – Finché la connessione seriale è disponibile
15 – Leggi venti caratteri dalla porta seriale
16 – Stampa della stringa sul nostro monitor seriale
Collegamento elettrico
Una volta che abbiamo caricato gli sketch sui rispettivi Arduini lasciamo l’Arduino destinatario attaccato al nostro computer con il cavo USB e attacchiamo l’Arduino mittente al destinatario con questo semplice schema elettrico.
Come potete vedere RX su uno diventa TX sull’altro. Non parleremo in questa sede di TX ed RX, ma se durante una comunicazione seriale tra più dispositivi doveste avere dei problemi vi consiglio innanzitutto di controllare RX e TX e nel caso di scambiare i due cavi.
Se tutto ha funzionato correttamente dovreste vedere i messaggi stampati sul vostro monitor seriale con i valori dell’Arduino mittente.
Se lo vedete vuol dire che la comunicazione seriale fra due arduini ha funzionato correttamente!
Usiamo la libreria SoftwareSerial
Ora che abbiamo fatto la prima prova siamo pronti a fare un secondo esperimento.
Avere la porta 0 e la porta 1 di Arduino occupate potrebbe essere un problema in certe occasioni.
Se ad esempio volessimo caricare un nuovo sketch, in questo momento non potremmo farlo senza prima liberare i pin TX ed RX dell’Arduino destinatario.
Inoltre se noi avessimo più dispositivi che devono comunicare fra di loro, come ad esempio due Arduini mittenti e un Arduino destinatario, ci troveremmo impossibilitati per mancanza di PIN.
Ci viene in aiuto allora la libreria SoftwareSerial che ci permette di utilizzare dei PIN digitali di Arduino (ovvero la colonna a destra che va da 0 a 13) come se si trattassero dei pin RX e TX.
Ora scriviamo il nuovo codice utilizzando i PIN 7 e 8 invece di 0 e 1, questo solamente per il nostro Arduino destinatario.
//Sketch scritto da Alessandro Oppo per 9minuti.it //collegamenti rx-tx tx-rx gnd-gnd #include <SoftwareSerial.h> char stringa[20]; SoftwareSerial receiver(8, 7); void setup() { Serial.begin(9600); receiver.begin(9600); } void loop() { while (receiver.available() == false) { receiver.readBytes(stringa, 20); Serial.write("\n"); Serial.write(stringa); } delay(1000); }
4 – includiamo la libreria SoftwareSerial.h
8 – creiamo il nostro oggetto di tipo SoftwareSerial e con nome receiver. Come parametri della funzione daremo i pin utilizzati per RX e TX
12 – chiamiamo il metodo begin() con baudrate di 9600 anche per il nostro oggetto receiver
17 – Finché la connessione seriale è disponibile per l’oggetto receiver allora esegue il ciclo e svolge le stesse cose dello sketch precedente.
Da int a carattere con la funzione itoa
E se invece di una stringa o di un array di caratteri dovessimo passare il valore di un sensore dal nostro Arduino mittente a quello destinatario?
Ci viene in aiuto la funzione itoa() che ci permette di trasformare dei dati di tipo intero in un array di caratteri.
Vediamo il codice dello sketch e poi guardiamo i commento del codice, riga per riga come sempre.
//Sketch scritto da Alessandro Oppo per 9minuti.it //collegamenti rx-tx tx-rx gnd-gnd int value = 69; char appoggio[10]; void setup() { Serial.begin(9600); } void loop() { itoa(value, appoggio, 10); Serial.write(appoggio, 10); delay(1000); }
4 – La nostra variabile intera chiamata value che rappresenta il valore del nostro sensore
5 – Il nostro array di char composto chiamato appoggio e in cui salveremo momentaneamente il contenuto della variabile intera prima di inviarlo all’Arduino destinatario
13 – Utilizzo della funzione itoa(). Attenzione ai parametri! Value, il valore del nostro sensore; appoggio, il nostro array di char; 10, il sistema decimale! Se scrivessimo 2 avremmo un numero binario all’interno del nostro array!
Da carattere a intero utilizzando la funzione atoi
Ora il nostro Arduino destinatario dovrebbe ricevere la stringa inviatagli dal mittente.
Per fare in modo che il nostro valore torni ad essere un intero dobbiamo utilizzare la funzione atoi() che, come avrete già capito, è la funzione inversa della itoa() utilizzata in precedenza.
Vediamo lo sketch.
//Sketch scritto da Alessandro Oppo per 9minuti.it //collegamenti rx-tx tx-rx gnd-gnd char stringa[20]; int num = 888; void setup() { Serial.begin(9600); } void loop() { while (Serial.available() == false) { Serial.readBytes(stringa, 20); num = atoi(stringa); Serial.print(num); } delay(1000); }
4 – Dichiarazione di un array di caratteri chiamato stringa
5 – Dichiarazione del nostro intero chiamato num. Notare che ho già assegnato un valore. Se la comunicazione fra i due arduini funziona correttamente dovremmo leggere 69, se invece qualcosa dovesse non andare il numero stampato è 888.
16 – Utilizzo della funzione atoi() e assegnazione del numero appena convertito alla variabile intera num
Per questo tutorial è tutto, credo che sia molto interessante occuparsi di comunicazione seriale fra due arduini perché ci consentirà di utilizzare altri protocolli che funzionano sempre in questa maniera come ad esempio il Bluetooth.
Se aveste dubbi o richieste particolari vi invito come sempre a scrivere nei commenti e a farmi sapere se l’articolo vi è stato utile o meno.
Grazie per l’attenzione,
Alessandro
Grazie Alessandro, tutto molto chiaro. io ho un problema di questo tipo: vorrei usare un Arduino uno per leggere dei dati da delle termocoppie, mandarli ad arduino nano 33 IoT il quale li manda via wifi ad un server. La trasmissione wifi al server funziona “scrivendo in seriale”. Il passaggio dati da Arduino uno e arduino nano usano anch’essi il serialle ho un conflitto tra le trasmissioni seriali. come posso fare?
grazie mille
Ciao Diego, scusa il ritardo. Sai che non ho capito esattamente il problema, o meglio non ho capito di che tipo sia il conflitto.
Se non ho capito male c’è solo una comunicazione seriale fra l’Arduino Uno e il Nano. La comunicazione è unilaterale (è solo uno che manda e l’altro riceve sempre) oppure talvolta si invertono?
Se la comunicazione fra il Nano e il server funziona correttamente direi che possiamo escluderlo dal problema, anche se sinceramente mi sembra strano che sia seriale. Quando ho mandato dei dati su internet ho usato i metodi POST e GET del protocollo HTTP.
Hai dovuto configurare tutto tu o hai usato il Cloud di Arduino?
Alessandro
Spiegazione chiara lo capita anche io , super !!!!!
Ottimo, grazie per il feedback!
Ciao, ho una domanda.. Nel secondo caso, in cui hai voluto trasformare l’intero in array di caratteri, e in seguito una volta ricevuto, fatto la trasformazione inversa… Cosa sarebbe successo se avessimo mandato (e letto) direttamente l’intero? Tipo Serial.write (int) per l’emettitore, e Serial.read(int) e Serial.print(int) per il ricevitore?
Ciao Aurelia, grazie per essere passata di qui. Ogni carattere che noi.scriviamo ( anche di questo messaggio) occupa 8 bit (o 1 byte). Se cerchi ‘tabella ascii’ su google trovi la tabella che mostra i caratteri veri e propri e i loro corrispettivi in bit. Quando noi scriviamo ‘a’ il computer potrebbe capire che indichiamo la lettera ‘a’ oppure il codice numerico corrispondente ad ‘a’ (vedere tabella ASCII). Per evitare queste possibili ‘incomprensioni’ ho dovuto usare le funzioni atoi e itoa. Ti invito a fare delle prove senza le due funzioni e a controllare sulla tabella ASCII, il risultato è piuttosto interessante ed educativo! Spero di aver risposto alla domanda. 😃
caro Alessandro sono un giovanotto di 75 anni che ha scoperto arduino per sostituire la logica elettromeccanica in un modello di nave: alla fine ho riempitp un secchio di rele e timer.Ovviamente sono ,rispetto arduino, come quello che ama la musica ma non sa leggere lo spartito. Vengo alla domanda:quanto hai chiaramente detto prima consente di leggereil programma di un arduino nano su un monitor per ricavarlo ? faccio la domanda perche ho inserito uno sketch su un nano per comandare 4 gruette e miracolosamente funziona .Poi mi hanno rubato il pc e mi sono rimasti 3 arduini con uno sketch su cui non posso intervenire a meno di non sfidare la sorte riscrivendoli ,ringrazio poisaverio lpia successivamente tra gli sgignazzi delle mie figlie ho scoperto la chiavetta usb ringrazio e saluto
Caro Saverio,
Se quello che vuoi fare è ottenere lo sketch attualmente caricato sul tuo Arduino Nano non saprei aiutarti. Sul forum ufficiale dicono che non è possibile (https://forum.arduino.cc/t/way-to-recover-sketches/874945), sempre se non ho frainteso la domanda. Mi sa che sarà necessario riscriverlo da zero…
Grazie del messaggio e a presto!