Arduino - Inter Integrated Circuit

Il circuito inter-integrato (I2C) è un sistema per lo scambio seriale di dati tra i microcontrollori e circuiti integrati specializzati di nuova generazione. Viene utilizzato quando la distanza tra di loro è breve (ricevitore e trasmettitore si trovano solitamente sulla stessa scheda stampata). La connessione viene stabilita tramite due conduttori. Uno è utilizzato per il trasferimento dei dati e l'altro per la sincronizzazione (segnale di clock).

Come si vede nella figura seguente, un dispositivo è sempre un master. Esegue l'indirizzamento di un chip slave prima dell'inizio della comunicazione. In questo modo, un microcontrollore può comunicare con 112 dispositivi diversi. La velocità di trasmissione è generalmente di 100 Kb / sec (modalità standard) o 10 Kb / sec (modalità di velocità di trasmissione lenta). Recentemente sono apparsi sistemi con velocità di trasmissione di 3,4 Mb / sec. La distanza tra i dispositivi che comunicano su un bus I2C è limitata a diversi metri.

Pin I2C della scheda

Il bus I2C è costituito da due segnali: SCL e SDA. SCL è il segnale di clock e SDA è il segnale di dati. L'attuale bus master genera sempre il segnale di clock. Alcuni dispositivi slave possono forzare il clock basso a volte per ritardare l'invio di più dati da parte del master (o per richiedere più tempo per preparare i dati prima che il master tenti di sincronizzarli). Questo è noto come "allungamento dell'orologio".

Di seguito sono riportati i pin per diverse schede Arduino:

  • Uno, Pro Mini A4 (SDA), A5 (SCL)
  • Mega, Due 20 (SDA), 21 (SCL)
  • Leonardo, Yun 2 (SDA), 3 (SCL)

Arduino I2C

Abbiamo due modalità - codice master e codice slave - per collegare due schede Arduino utilizzando I2C. Sono -

  • Trasmettitore Master / Ricevitore Slave
  • Ricevitore Master / Trasmettitore Slave

Trasmettitore Master / Ricevitore Slave

Vediamo ora cosa sono il trasmettitore master e il ricevitore slave.

Trasmettitore principale

Le seguenti funzioni vengono utilizzate per inizializzare la libreria Wire e unire il bus I2C come master o slave. Normalmente viene chiamato solo una volta.

  • Wire.begin(address) - L'indirizzo è l'indirizzo slave a 7 bit nel nostro caso in quanto il master non è specificato e si unirà al bus come master.

  • Wire.beginTransmission(address) - Inizia una trasmissione al dispositivo I2C slave con l'indirizzo fornito.

  • Wire.write(value) - Accoda i byte per la trasmissione da un dispositivo master a uno slave (chiamate intermedie a beginTransmission () e endTransmission ()).

  • Wire.endTransmission() - Termina una trasmissione a un dispositivo slave iniziata da beginTransmission () e trasmette i byte accodati da wire.write ().

Example

#include <Wire.h> //include wire library

void setup() //this will run only once { 
   Wire.begin(); // join i2c bus as master
} 

short age = 0; 

void loop() {   
   Wire.beginTransmission(2); 
   // transmit to device #2
   Wire.write("age is = ");
   Wire.write(age); // sends one byte
   Wire.endTransmission(); // stop transmitting
   delay(1000); 
}

Ricevitore slave

Vengono utilizzate le seguenti funzioni:

  • Wire.begin(address) - L'indirizzo è l'indirizzo dello slave a 7 bit.

  • Wire.onReceive(received data handler) - Funzione da richiamare quando un dispositivo slave riceve dati dal master.

  • Wire.available() - Restituisce il numero di byte disponibili per il recupero con Wire.read (). Dovrebbe essere chiamato all'interno del gestore Wire.onReceive ().

Example

#include <Wire.h> //include wire library

void setup() {  //this will run only once
   Wire.begin(2); // join i2c bus with address #2
   Wire.onReceive(receiveEvent); // call receiveEvent when the master send any thing 
   Serial.begin(9600); // start serial for output to print what we receive 
}

void loop() {   
   delay(250); 
}

//-----this function will execute whenever data is received from master-----//

void receiveEvent(int howMany) { 
   while (Wire.available()>1) // loop through all but the last {
      char c = Wire.read(); // receive byte as a character
      Serial.print(c); // print the character
   }
}

Ricevitore Master / Trasmettitore Slave

Vediamo ora cosa sono il ricevitore master e il trasmettitore slave.

Ricevitore principale

Il Master è programmato per richiedere e quindi leggere i byte di dati che vengono inviati dallo Slave Arduino con indirizzo univoco.

Viene utilizzata la seguente funzione:

Wire.requestFrom(address,number of bytes)- Utilizzato dal master per richiedere byte da un dispositivo slave. I byte possono quindi essere recuperati con le funzioni wire.available () e wire.read ().

Example

#include <Wire.h> //include wire library void setup() { 
   Wire.begin(); // join i2c bus (address optional for master) 
   Serial.begin(9600); // start serial for output
} 

void loop() { 
   Wire.requestFrom(2, 1); // request 1 bytes from slave device #2
   while (Wire.available()) // slave may send less than requested {
      char c = Wire.read(); // receive a byte as character
      Serial.print(c); // print the character
   } 
   delay(500); 
}

Trasmettitore slave

Viene utilizzata la seguente funzione.

Wire.onRequest(handler) - Una funzione viene chiamata quando un master richiede dati da questo dispositivo slave.

Example

#include <Wire.h> 

void setup() { 
   Wire.begin(2); // join i2c bus with address #2
   Wire.onRequest(requestEvent); // register event
} 

Byte x = 0;

void loop() { 
   delay(100); 
} 

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()

void requestEvent() { 
   Wire.write(x); // respond with message of 1 bytes as expected by master
   x++; 
}