Comunicazione tra 2 Arduino

Forse non tutti sanno che e` possibile far comunicare tra loro 2 schede Arduino,
questo ci può tornare utile nei casi in cui abbiamo bisogno di aumentare il numero di porte, oppure dobbiamo semplicemente scambiare informazioni tra due schede magari lontane tra loro.



Ma come fanno a comunicare?
comunicano grazie al protocollo i2c e alla libreria Wire.


Vediamo ora un semplice esempio, infatti collegheremo un led all`Arduino che utilizzeremo come master, mentre un pulsante a quello utilizzato come slave.

Ecco un video che vi mostra il funzionamento:




Il funzionamento è semplice,
il master richiede un byte allo slave, quando lo slave riceve la richiesta legge lo stato del pulsante e se è premuto invia "a" altrimenti invia "s".
Quindi il master legge il byte ricevuto e se è "a" accende il led, altrimenti se è "s" lo lascia spento.

Questo è lo schema utilizzato nell'esempio, come potete vedere il led è collegato ad un Arduino, mentre il pulsante all'altro.
I 2 fili collegati tra i pin A4 e A5 dei due Arduino servono a stabilire la comunicazione i2c, sono necessarie anche 2 resistenze di pull-up.
Ora dovete caricare i due sketch, uno sul master e uno sullo slave.
Ecco quello per il master:

  1. //master
  2. #include <Wire.h>
  3. void setup()
  4. {
  5.   Wire.begin();        // avvia il bus i2c
  6.   pinMode (2,OUTPUT);
  7. }
  8. void loop()
  9. {
  10.   Wire.requestFrom(2, 1); // richiedi 1 byte al dispositivo presente all'indirizzo 2.
  11.   String b = "";
  12.   char c = Wire.read(); // leggi il byte ricevuto
  13.   b = b + c;
  14.   delay (100);
  15.   if (b == "a")
  16.   {
  17.     digitalWrite(2, HIGH);
  18.   }
  19.   else
  20.   {
  21.     digitalWrite(2, LOW);
  22.   }
  23.   delay(10);
  24. }

Ed ecco quello per lo Slave:

  1. //slave
  2. #include <Wire.h>
  3. void setup()
  4. {
  5.   pinMode(2, INPUT);
  6.   pinMode(13,OUTPUT);
  7.   Wire.begin(2);                // entra nel bus I2C con indirizzo 2
  8.   Wire.onRequest(requestEvent); // esegue la funzione quando ha una richiesta
  9. }
  10. void loop()
  11. {
  12.   delay(100);
  13. }
  14. void requestEvent()
  15. {
  16.   if (digitalRead(2) == HIGH){
  17.     Wire.write("a");       // se il pulsante è premuto invia "a"  
  18.     digitalWrite(13,HIGH);  
  19.   }
  20.   else
  21.   {
  22.     Wire.write("s");      // altrimenti invia "s"
  23.     digitalWrite(13,LOW);
  24.   }
  25. }

Spero sia tutto chiaro e che vi possa essere d`aiuto per i vostri progetti, se avete dubbi lasciate un commento qui sotto, ciao!!

Seguimi sulle mie pagine per rimanere sempre aggiornato sui nuovi post!

34 commenti:

  1. Interessante, sicuramente da approfondire. Grazie.

    RispondiElimina
  2. Ciao, non mi è ben chiaro attraverso quale porta comunicano: dallo schema sembra tramite a4 e a5, ma nello sketch non c'è riferimento a quelle porte e sembrerebbe sulla porta 2 o 13.
    Grazie per la risposta!

    RispondiElimina
    Risposte
    1. Ciao, comunicano attraverso i pin a4 e a5, nello sketch non sono dichiarati perché sono i pin di default attraverso il quale avviene la comunicazione i2c. Nel momento in cui la comunicazione i2c viene avviata (Wire.begin) i pin a4 e a5 vengono impiegati per essa.
      Ciao!

      Elimina
    2. Grazie mille! Un'ultima cosa: posso collegare anche più di due arduino in questo modo? Nello specifico, mi servirebbe mandare da un "master" dei comandi a due "slave" che li devono giusto leggere.

      Elimina
    3. Penso proprio di sì, l'unico dubbio riguarda la distanza è la resistenza ai disturbi che non penso sia granché

      Elimina
    4. Si, si possono collegare fino a 100 schede. Per aumentare la distanza esistono degli integrati appositi (ho sentito che però arrivano fino ad un metro). La soluzione che, secondo me, è la migliore è di acquistare dei chip MAX485 ed utilizzare quelli che permettono di portare una linea seriale (UART, non l'I2C) ad una distanza molto maggiore.

      Elimina
  3. buon giorno sig. Alberti sono un uomo di 50 anni mi sono appassionato di modellismo ferroviario da un anno ed ora mi trovo davanti al problema di cosa utilizzare per gestire tutti i meccanismi e luci di un plastico un pò complesso . mi sto documentando per utilizzare Arduino ( che mi affascina moltissimo ) ma ho molte incognite che vorrei sottoporgli . se le può interessare e la posso disturbare le esporrò le mie domande. cordiali saluti Cosma Brioni

    RispondiElimina
    Risposte
    1. Buongiorno a lei sig. Brioni,

      penso che Arduino possa essere la scelta giusta, faccia pure le domande nella sezione "chiedi e rispondi", e cercherò di risponderle il prima possibile.

      Saluti,

      Elimina
  4. grazie sig. Alberti per i suoi articoli,tempo fa avevo iniziato a sviluppare un piccolo progettino con Labview usando un arduino 2009 come scheda di acquisizione,ma mi sono accorto che il tempo di campionamento (di 32 ms) mi dà problemi con alcune misure, tipo quella del vento,cioè se il vento supera una certa velocità la misura è falsata;
    allora (dopo una pausa di sconforto) ho pensato di usare oltre alla scheda collegata a labview una scheda che acquisisca il segnale mediante uno sketch fatto con l'ide di arduino e mediante I2C o altro tipo di comunicazione tra arduini portarlo alla scheda interfacciata con labview,domande:
    è possibile fare questa operazione ?(io penso di si ma per ignoranza non so quale protocollo usare a causa di labview)

    mi dà una mano per favore,cordiali saluti Armenia Massimo

    RispondiElimina
    Risposte
    1. Salve sig. Massimo, penso proprio sia una cosa fattibile, labview comunica con l'arduino tramite la seriale usb? 32 ms mi sembra un tempo abbastanza alto, come è fatto lo sketch?

      Elimina
  5. Grazie sig.Alberti per la risposta,arduino e labview comunicano in fase sperimentale tramite usb,ma vorrei portarlo in wifi con xbee sperando di non apportare altri deadtime e rendere vano ogni sforzo; avevo intenzione di inserire lo sketch fatto con labview, ma non so come fare.

    RispondiElimina
    Risposte
    1. Può caricalo su un server esterno e poi condividere il link qui sotto. Ad esempio Arduino Create permette di caricare uno sketch e di condividerne il link

      Elimina
  6. Ciao sig.massimo mi avvicino adesso ad arduino ho fatto qualche sketch cin led e interruttori.Se possibile mi spieghi come col pulsante posso far rimanere il led sempre acceso.grazie
    Auguri di Buon Natale
    Michele

    RispondiElimina
  7. Ciao sig.massimo mi avvicino adesso ad arduino ho fatto qualche sketch cin led e interruttori.Se possibile mi spieghi come col pulsante posso far rimanere il led sempre acceso.grazie
    Auguri di Buon Natale
    Michele

    RispondiElimina
  8. Buonasera, Le spiego il mio problema, devo collegare un NANO V3.0 ad un DUE, il nano legge 6 sensori MLX90614 perché il DUE non supporta la condizione repeated_start sul bus i2c necessaria per i sensori in oggetto, il nano salva i valori letti in 6 diversi byte, come posso passare questi 6 byte al DUE, perché non riesco ad estendere al mio problema l'esempio riportato

    RispondiElimina
    Risposte
    1. Ciao, potresti risolvere mandando una stringa di 6 char, poi in ricezione la dividi con il comando "substring" e riconverti ad intero con "toint"

      Elimina
    2. Grazie mille per l'ottimo suggerimento

      Elimina
    3. Questo commento è stato eliminato dall'autore.

      Elimina
  9. Questo commento è stato eliminato dall'autore.

    RispondiElimina
  10. Ciao sono alle prime armi con arduino, innanzitutto complimenti per l'ottima guida, semplice e chiara anche per un neofita come me... Volevo applicare lo stesso progetto ma anzichè tra 2 arduino uno.. con Arduino mega ed arduino uno...ho fatto svariate prove ma non ci riesco. potresti darmi un aiutino?

    RispondiElimina
    Risposte
    1. Ciao, che pin usi sulla Mega? prova a verificare con questa foto:
      http://www.14core.com/wp-content/uploads/2015/09/I2C-LCD-Module-Board-Arduino-Mega-2560.jpg
      Ciao!

      Elimina
    2. grazie mille!! provavo erroneamente con tutti i pin dove era indicato "tx" e "rx"

      Elimina
  11. Salve. Mi è chiaro il meccanismo con cui far comunicare 2 Arduino, ma avrei una domanda specifica: nell'esempio riportato bisogna impostare manualmente l'indirizzo di ogni Arduino (a parte il master che non ha alcun indirizzo). C'è un modo per far sì che, una volta definito il Master, gli altri Arduino in cascata si "battezzino" in automatico assegnandosi un indirizzo univoco all'interno della catena? A me è venuto in mente un protocollo che dovrebbe funzionare, ma volevo sapere se esiste già un modo nativo per farlo. Grazie

    RispondiElimina
  12. Ciao, non conosco un modo nativo, ma se vuoi condividere il tuo sistema potrebbe tornare molto utile!

    RispondiElimina
  13. Ciao, sai se è possibile fare la stessa cosa comunicando fra un Arduino Uno e un Galileo Gen 2? hanno processori a frequenze ben diverse... Se non si può così, hai in mente un modo per far ciò? esiste un modo che implichi il NON utilizzare il pin RX di uno dei due Arduini (giacchè mi serve un pin libero per la comunicazione seriale di un apparecchio del progetto)? Grazie in anticipo, scusa per la tonnellata di domande! :)

    RispondiElimina
  14. Ciao l'I2C é un protocollo standard, quindi non ci dovrebbero essere problemi anche tra dispositivi diversi.
    Purtroppo non ho esperienza con la Galileo. Ciao!

    RispondiElimina
  15. SALVE ALBERTI
    mi domandavo questa stringa col 13
    if (digitalRead(2) == HIGH){
    Wire.write("a"); // se il pulsante è premuto invia "a"
    digitalWrite(13,HIGH);
    }
    else
    {
    Wire.write("s"); // altrimenti invia "s"
    digitalWrite(13,LOW);
    ma nel disegno sopra non è collegato da nessuna parte.
    grazie

    RispondiElimina
    Risposte
    1. Buongiorno, sulla scheda Arduino Uno è presente un led, pilotabile agendo sul PIN 13

      Elimina
    2. Buon pomeriggio in che senso pilotati grazie

      Elimina
  16. Buonasera sig. Alberti è altrettanto possibile fare leggere al primo Arduino anziche un valore digitale ,nel nostro caso lo stato del pulsante quindi 0 o 1, un valore analogico e inviare anziché "s"o "a" il valore stesso al secondo Arduino per visualizzarlo su un display?

    RispondiElimina
  17. Salve, ma le due usb dei rispettivi arduino sono entrambi collegati al pc? E, se usassi arduino uno e arduino mega, anche in questo caso dovrei collegare entrambe le usb al pc? Grazie per la risposta

    RispondiElimina
    Risposte
    1. Ciao, non c'è bisogno che nessuno dei due sia collegato al pc, ovviamente andranno alimentati in altro modo

      Elimina
  18. Se ho bisogno di memorizzare i dati rilevati da un sensore che collego ad arduino UNO(che funge da slave) su un database SQL, nemmeno in questo caso vanno collegati al pc?

    RispondiElimina
  19. buongiorno, mi collego a questo vecchio post per fare una domanda stupida, sono uno alle prime armi,come faccio a far dialogare una R3 con un'altra R3 o micro o nano a 150 metri di distanza in maniera filare? dovrei azionare una specie di macchinina con 2 motori ma non ho abbastanza fili, mi sono perso con I2C RS422 ed altro, grazie

    RispondiElimina

Lascia un commento qui sotto, ti risponderò il prima possibile!

Altri Post