Zurück

I2C-Scanner mit Arduino: Jedes Gerät am Bus finden

Einleitung

Hast du jemals einen neuen I2C-Sensor oder ein Display an deinen Arduino angeschlossen und dich gefragt: “Welche Adresse verwendet dieses Teil?” Damit bist du nicht allein! Das I2C-Protokoll ist eine leistungsstarke Möglichkeit, mit mehreren Geräten über nur zwei Leitungen zu kommunizieren, aber jedes Gerät hat eine eindeutige Adresse – und manchmal ist diese Adresse nicht offensichtlich aus dem Datenblatt ersichtlich. Hier kommt ein I2C-Scanner ins Spiel. Es ist ein einfacher Sketch, der jede mögliche Adresse abfragt und meldet, welche antworten.

In diesem Tutorial bauen wir einen I2C-Scanner mit einem Arduino Uno und einem SSD1306 OLED-Display (das auch als bekanntes Gerät am Bus dient). Wir führen alles im Velxio-Browser-Simulator aus, sodass du keine Hardware benötigst, um mitzumachen. Am Ende wirst du verstehen, wie der I2C-Bus funktioniert, wie man Geräte verdrahtet und wie man Code schreibt, der sie scannt.

Lass uns loslegen!

Schaltungsaufbau

Schaltplan des I2C-Scanners auf der Velxio-Simulator-Leinwand

Die Schaltung ist erfrischend einfach. Wir brauchen nur zwei Komponenten:

Verdrahtungsdetails

Verbinde das OLED mit dem Arduino über vier Kabel:

Arduino-PinOLED-PinKabelfarbe
A4 (SDA)DATABlau
A5 (SCL)CLKOrange
GNDGNDSchwarz
5VVINRot

Hinweis: Auf dem Arduino Uno sind A4 und A5 die dedizierten I2C-Pins. Andere Boards können andere Pins verwenden (z. B. SDA/SCL auf einem ESP32).

Im Velxio-Simulator kannst du das OLED aus der Komponentenauswahl hinzufügen und es durch Klicken auf die Pins verdrahten. Die Leinwand-Symbolleiste hilft dir beim Zoomen und Verschieben, um die Verbindungen zu erleichtern.

Velxio Leinwand-Symbolleiste über dem Simulations-Viewport

Code-Erklärung

Quellcode für den I2C-Scanner im Velxio Monaco-Editor

Schauen wir uns nun den Code an. Öffne den Code-Editor in Velxio (du siehst den Monaco-Editor mit Syntax-Highlighting). Der Sketch ist in Arduino C++ geschrieben und verwendet die integrierte Wire-Bibliothek.

Einbinden der Bibliothek

#include <Wire.h>

Die Wire-Bibliothek übernimmt die gesamte I2C-Kommunikation auf niedriger Ebene. Sie ist in der Arduino-IDE enthalten, sodass keine zusätzliche Installation erforderlich ist.

Setup-Funktion

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

  Serial.println("===========================");
  Serial.println("  I2C Bus Scanner (TWI)");
  Serial.println("===========================");
  Serial.println("Scanning...");
  Serial.println();

  int devicesFound = 0;

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

    if (error == 0) {
      Serial.print("  Device found at 0x");
      if (addr < 16) Serial.print("0");
      Serial.print(addr, HEX);

      // Identify known addresses
      switch (addr) {
        case 0x27: Serial.print("  (PCF8574 LCD backpack)"); break;
        case 0x3C: Serial.print("  (SSD1306 OLED)"); break;
        case 0x48: Serial.print("  (Temperature sensor)"); break;
        case 0x50: Serial.print("  (EEPROM)"); break;
        case 0x68: Serial.print("  (DS1307 RTC)"); break;
        case 0x76: Serial.print("  (BME280 sensor)"); break;
        case 0x77: Serial.print("  (BMP180/BMP280)"); break;
      }
      Serial.println();
      devicesFound++;
    }
  }

  Serial.println();
  Serial.print("Scan complete. ");
  Serial.print(devicesFound);
  Serial.println(" device(s) found.");

  if (devicesFound == 0) {
    Serial.println("No I2C devices found. Check connections.");
  }
}

Lass uns das im Detail betrachten:

  1. Wire.begin() – Initialisiert den Arduino als I2C-Master.
  2. Serial.begin(9600) – Startet die serielle Kommunikation mit 9600 Baud, damit wir die Ergebnisse im seriellen Monitor sehen können.
  3. Die Schleife durchläuft die Adressen 1 bis 126 (0x01 bis 0x7E). Adresse 0 ist für den General Call reserviert, und 127 ist für spezielle Zwecke reserviert.
  4. Wire.beginTransmission(addr) – Startet eine Übertragung an die angegebene Adresse.
  5. Wire.endTransmission() – Beendet die Übertragung und gibt einen Fehlercode zurück. Wenn der Fehler 0 ist, bedeutet dies, dass das Gerät quittiert hat (ACK) – wir haben ein Gerät gefunden!
  6. Adresse ausgeben – Wir geben sie im Hexadezimalformat mit einer führenden Null für die Lesbarkeit aus.
  7. Switch-Anweisung – Identifiziert bekannte Geräte anhand ihrer bekannten Adressen. Dies ist optional, aber hilfreich.
  8. Geräte zählen – Wir erhöhen devicesFound für jedes ACK.
  9. Abschlussbericht – Gibt die Gesamtzahl der gefundenen Geräte aus.

Loop-Funktion

void loop() {
  // Rescan every 10 seconds
  delay(10000);
  Serial.println("\nRescanning...");
  setup();
}

Die loop()-Funktion wartet einfach 10 Sekunden und ruft dann setup() erneut auf, um erneut zu scannen. Dies ist nützlich, wenn du Geräte hinzufügst oder entfernst, während das System läuft.

Wichtige Konzepte für Schüler

Was ist I2C?

I2C (Inter-Integrated Circuit), auch TWI (Two-Wire Interface) genannt, ist ein synchrones serielles Kommunikationsprotokoll. Es verwendet zwei bidirektionale Open-Drain-Leitungen: SDA (Daten) und SCL (Takt). Jedes Gerät am Bus hat eine eindeutige 7-Bit-Adresse (obwohl es auch 10-Bit-Adressen gibt). Der Master (Arduino) initiiert die Kommunikation und erzeugt das Taktsignal.

Wie der Scanner funktioniert

Der Scanner sendet eine Startbedingung gefolgt vom Adressbyte (7-Bit-Adresse + Lese-/Schreibbit). Wenn ein Gerät mit dieser Adresse existiert, antwortet es mit einem ACK (Acknowledge), indem es SDA während des neunten Taktimpulses auf Low zieht. Wenn kein Gerät antwortet, wird ein NACK (Not Acknowledge) empfangen, und endTransmission() gibt einen Fehlercode ungleich Null zurück.

Warum einen Scanner verwenden?

Häufige Fallstricke und Debugging-Tipps

  1. Falsche Verdrahtung – Überprüfe, ob SDA und SCL korrekt angeschlossen sind. Ein Vertauschen funktioniert nicht.
  2. Fehlende Pull-Up-Widerstände – I2C-Leitungen benötigen Pull-Up-Widerstände (typischerweise 4,7 kΩ) zu VCC. Viele Breakout-Boards enthalten sie, aber wenn du von Grund auf baust, vergiss sie nicht.
  3. Adresskonflikte – Wenn zwei Geräte dieselbe Adresse teilen, funktioniert keines zuverlässig. Verwende den Scanner, um Konflikte zu erkennen.
  4. Baudratenkonflikt – Der Scanner verwendet standardmäßig 100 kHz (Standardmodus). Einige Geräte benötigen möglicherweise langsamere Geschwindigkeiten. Du kannst sie mit Wire.setClock(400000) für den schnellen Modus ändern.
  5. Serieller Monitor zeigt keine Ausgabe – Stelle sicher, dass die Baudrate im seriellen Monitor mit 9600 übereinstimmt.

In Velxio kannst du den seriellen Monitor über die Editor-Symbolleiste öffnen. Wenn du keine Ausgabe siehst, überprüfe, ob der Code erfolgreich kompiliert wurde (suche nach Fehlern in der Konsole).

Velxio Editor-Symbolleiste mit Kompilieren- und Ausführen-Steuerung

Vorgeschlagene Erweiterungen

Sobald der grundlegende Scanner funktioniert, probiere diese Verbesserungen aus:

Um Bibliotheken in Velxio hinzuzufügen, verwende den Bibliotheksmanager.

Velxio Bibliotheksmanager-Dialog mit installierten Arduino-Bibliotheken

Fazit

Du hast gerade einen universellen I2C-Scanner gebaut, der mit jedem Arduino-kompatiblen Board funktioniert. Dieses Werkzeug ist unverzichtbar zum Debuggen und Erkunden neuer I2C-Module. Das Beste daran? Du kannst es jetzt direkt in deinem Browser auf Velxio ausführen, ohne jegliche Hardware.

Bereit, es selbst auszuprobieren? Öffne das Live-Beispiel und beginne mit dem Scannen:

👉 Starte den I2C-Scanner auf Velxio

Viel Spaß beim Hacken!


Teilen auf:
David Montero

Geschrieben von

David Montero

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

GitHub velxio.dev

Ähnliche Artikel


Vorheriger Artikel
I2C-RTC-Uhr mit DS1307 auf Velxio
Nächster Artikel
Serielle LED-Steuerung mit Arduino — Befehle zum Blinken senden