Indietro

Scanner I2C con Arduino: Trova Ogni Dispositivo sul Bus

Introduzione

Hai mai collegato un nuovo sensore o display I2C al tuo Arduino chiedendoti: “Che indirizzo usa questo dispositivo?” Non sei solo! Il protocollo I2C è un potente modo per comunicare con più dispositivi usando solo due fili, ma ogni dispositivo ha un indirizzo unico — e a volte quell’indirizzo non è ovvio dal datasheet. È qui che entra in gioco uno scanner I2C. È uno schizzo semplice che sonda ogni possibile indirizzo e riporta quali rispondono.

In questo tutorial, costruiremo uno scanner I2C usando un Arduino Uno e un display OLED SSD1306 (che funge anche da dispositivo noto sul bus). Eseguiremo tutto all’interno del simulatore in-browser Velxio, quindi non hai bisogno di hardware per seguire. Alla fine, capirai come funziona il bus I2C, come collegare i dispositivi e come scrivere codice per scansionarli.

Iniziamo!

Spiegazione del Circuito

Diagramma del circuito dello scanner I2C sul canvas del simulatore Velxio

Il circuito è sorprendentemente semplice. Abbiamo bisogno solo di due componenti:

Dettagli del Collegamento

Collega l’OLED all’Arduino usando quattro fili:

Pin ArduinoPin OLEDColore Filo
A4 (SDA)DATABlu
A5 (SCL)CLKArancione
GNDGNDNero
5VVINRosso

Nota: Sull’Arduino Uno, A4 e A5 sono i pin I2C dedicati. Altre schede potrebbero usare pin diversi (es. SDA/SCL su un ESP32).

Nel simulatore Velxio, puoi aggiungere l’OLED dal selettore di componenti e collegarlo cliccando sui pin. La barra degli strumenti del canvas ti aiuta a zoomare e spostarti per facilitare i collegamenti.

Barra degli strumenti del canvas Velxio sopra la finestra di simulazione

Spiegazione del Codice

Codice sorgente per lo scanner I2C nell'editor Monaco di Velxio

Ora diamo un’occhiata al codice. Apri l’editor del codice in Velxio (vedrai l’editor Monaco con evidenziazione della sintassi). Lo schizzo è scritto in Arduino C++ e usa la libreria Wire integrata.

Inclusione della Libreria

#include <Wire.h>

La libreria Wire gestisce tutta la comunicazione I2C di basso livello. È inclusa con l’IDE Arduino, quindi non è necessaria alcuna installazione aggiuntiva.

Funzione Setup

void setup() {
  Wire.begin();
  Serial.begin(9600);

  Serial.println("===========================");
  Serial.println("  Scanner Bus I2C (TWI)");
  Serial.println("===========================");
  Serial.println("Scansione in corso...");
  Serial.println();

  int dispositiviTrovati = 0;

  for (byte addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    byte errore = Wire.endTransmission();

    if (errore == 0) {
      Serial.print("  Dispositivo trovato a 0x");
      if (addr < 16) Serial.print("0");
      Serial.print(addr, HEX);

      // Identifica indirizzi noti
      switch (addr) {
        case 0x27: Serial.print("  (Backpack LCD PCF8574)"); break;
        case 0x3C: Serial.print("  (OLED SSD1306)"); break;
        case 0x48: Serial.print("  (Sensore di temperatura)"); break;
        case 0x50: Serial.print("  (EEPROM)"); break;
        case 0x68: Serial.print("  (RTC DS1307)"); break;
        case 0x76: Serial.print("  (Sensore BME280)"); break;
        case 0x77: Serial.print("  (BMP180/BMP280)"); break;
      }
      Serial.println();
      dispositiviTrovati++;
    }
  }

  Serial.println();
  Serial.print("Scansione completata. ");
  Serial.print(dispositiviTrovati);
  Serial.println(" dispositivo(i) trovato(i).");

  if (dispositiviTrovati == 0) {
    Serial.println("Nessun dispositivo I2C trovato. Controlla i collegamenti.");
  }
}

Analizziamolo:

  1. Wire.begin() – Inizializza l’Arduino come master I2C.
  2. Serial.begin(9600) – Avvia la comunicazione seriale a 9600 baud per vedere i risultati nel Monitor Seriale.
  3. Il ciclo itera attraverso gli indirizzi da 1 a 126 (0x01 a 0x7E). L’indirizzo 0 è riservato per chiamate generali e 127 è riservato per scopi speciali.
  4. Wire.beginTransmission(addr) – Avvia una trasmissione verso l’indirizzo specificato.
  5. Wire.endTransmission() – Termina la trasmissione e restituisce un codice di errore. Se l’errore è 0, significa che il dispositivo ha riconosciuto (ACK) — abbiamo trovato un dispositivo!
  6. Stampa dell’indirizzo – Lo stampiamo in formato esadecimale con uno zero iniziale per leggibilità.
  7. Istruzione switch – Identifica dispositivi comuni tramite i loro indirizzi noti. È opzionale ma utile.
  8. Conteggio dei dispositivi – Incrementiamo dispositiviTrovati per ogni ACK.
  9. Rapporto finale – Stampa il numero totale di dispositivi trovati.

Funzione Loop

void loop() {
  // Riscansiona ogni 10 secondi
  delay(10000);
  Serial.println("\nRiscansione in corso...");
  setup();
}

La funzione loop() attende semplicemente 10 secondi e poi chiama setup() di nuovo per riscansionare. Questo è utile se aggiungi o rimuovi dispositivi mentre il sistema è in esecuzione.

Concetti Chiave per Studenti

Cos’è I2C?

I2C (Inter-Integrated Circuit), chiamato anche TWI (Two-Wire Interface), è un protocollo di comunicazione seriale sincrono. Usa due linee bidirezionali open-drain: SDA (dati) e SCL (clock). Ogni dispositivo sul bus ha un indirizzo unico a 7 bit (anche se esistono indirizzi a 10 bit). Il master (Arduino) avvia la comunicazione e genera il segnale di clock.

Come Funziona lo Scanner

Lo scanner invia una condizione di start seguita dal byte dell’indirizzo (indirizzo a 7 bit + bit di lettura/scrittura). Se esiste un dispositivo con quell’indirizzo, risponde con un ACK (riconoscimento) portando SDA a livello basso durante il nono impulso di clock. Se nessun dispositivo risponde, viene ricevuto un NACK (non riconoscimento) e endTransmission() restituisce un codice di errore diverso da zero.

Perché Usare uno Scanner?

Insidie Comuni e Consigli per il Debug

  1. Collegamenti errati – Ricontrolla che SDA e SCL siano collegati correttamente. Scambiarli non funzionerà.
  2. Resistenze di pull-up mancanti – Le linee I2C necessitano di resistenze di pull-up (tipicamente 4.7kΩ) verso VCC. Molte schede breakout le includono, ma se costruisci da zero, non dimenticarle.
  3. Conflitti di indirizzo – Se due dispositivi condividono lo stesso indirizzo, nessuno dei due funzionerà in modo affidabile. Usa lo scanner per rilevare conflitti.
  4. Disallineamento del baud rate – Lo scanner usa la modalità standard a 100 kHz. Alcuni dispositivi potrebbero necessitare velocità più basse. Puoi cambiarla con Wire.setClock(400000) per la modalità veloce.
  5. Il Monitor Seriale non mostra output – Assicurati che il baud rate nel Monitor Seriale corrisponda a 9600.

In Velxio, puoi aprire il Monitor Seriale dalla barra degli strumenti dell’editor. Se non vedi output, controlla che il codice sia stato compilato con successo (cerca errori nella console).

Barra degli strumenti dell'editor Velxio con controlli di compilazione ed esecuzione

Estensioni Suggerite

Una volta che lo scanner di base funziona, prova questi miglioramenti:

Per aggiungere librerie in Velxio, usa il Gestore Librerie.

Finestra del Gestore Librerie Velxio che elenca le librerie Arduino installate

Conclusione

Hai appena costruito uno scanner I2C universale che funziona con qualsiasi scheda compatibile con Arduino. Questo strumento è prezioso per il debug e l’esplorazione di nuovi moduli I2C. La parte migliore? Puoi eseguirlo subito nel tuo browser su Velxio senza alcun hardware.

Pronto a provarlo tu stesso? Apri l’esempio live e inizia a scansionare:

👉 Avvia lo Scanner I2C su Velxio

Buon hacking!


Condividi su:
David Montero

Scritto da

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Articoli correlati


Articolo precedente
Orologio RTC I2C con DS1307 su Velxio
Articolo successivo
Controllo LED Seriale con Arduino: Invia Comandi per Lampeggiare