Questo sketch esegue la scansione del bus I2C per trovare l’indirizzo dei dispositivi. Se viene trovato un dispositivo, viene segnalato al monitor seriale Arduino.
Moreware si è già occupata, in precedenza, di comunicazione seriale su Arduino, in particolare descrivendo UART, I2C e SPI.
Lo sketch che presenteremo oggi cerca l’indirizzo I2C di una periferica collegata ad Arduino, e rappresenta il primo passo per cercare di capire come funziona praticamente la comunicazione attraverso il protocollo I2C.
Lo sketch mostrerà gli indirizzi (a 7 bit) dei dispositivi trovati durante la scansione, come valori esadecimali. Tali indirizzi verranno in seguito utilizzati per la funzione “Wire.begin” che inizializza la comuncazione sul canale della periferica relativa. Alcuni datasheet utilizzano l’indirizzo a 8 bit, e alcuni sketch di esempio utilizzano indirizzi decimali: l’importante è capire il funzionamento della procedura.
Il programma
Apriamo un nuovo sketch su Arduino IDE, e copiamo il codice sorgente riportato di seguito. Carichiamolo su Arduino e apriamo il monitor seriale. Verrà segnalato ogni dispositivo trovato sul bus I2C.
È possibile spostare i cavi e collegare i dispositivi I2C mentre i2c_scanner è in esecuzione.
L’output del monitor seriale sarà simile a quello nell’immagine di presentazione.
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 |
// -------------------------------------- // i2c_scanner // // This sketch tests the standard 7-bit addresses // Devices with higher bit address might not be seen properly. // #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknown error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for next scan } |
Il codice è abbastanza semplice da seguire: viene inclusa la libreria Wire per l’utilizzo di I2C, poi si inizializza l’oggetto nel setup, assieme al monitor seriale.
Il loop si basa su di un ciclo for che “chiama” in modo sequenziale tutti i numeri (indirizzi) compresi tra 1 e 127 (7 bit): viene richiesta una beginTrasmission() sul relativo indirizzo, e se risponde un apparato, la funzione endTrasmission riporta un codice di errore uguale a zero. Se abbiamo trovato un device I2C valido, stampiamo il valore del suo indirizzo e aggiorniamo il contatore. Infine stampiamo un messaggio rieplogativo, ed attendiamo 5 secondi prima di lanciare una nuova scansione.
Riconoscere l’indirizzo I2C di una scheda collegata ad Arduino non è mai stato così semplice!
Post Scriptum
Ci è stato fatto notare che lo script esegue la scansione degli indirizzi a partire dall’1 ed escludendo il 127. L’indirizzo 0 è infatti un indirizzo speciale chiamato “general call address.” L’idea di base è che ogni device “slave” sul bus possa rispondere a tale indirizzo. In realtà non tutti i devices implementano correttamente tale protocollo, si è pertanto sceltyo di lasciarlo fuori dalla scansione.
Gli indirizzi 0x7C 0x7D 0x7E 0x7F sono invece riservati per scopi futuri.
Ovviamente è disponibile la lsita con gli utilizzatori più importanti degli indirizzi I2C.
Join our groups onTelegram…