I2C Scanner

Wozu braucht man einen I2C Scanner?

In einigen Beiträgen hatte ich über Bauteile geschrieben die mittels I2C (genauer: I2C) angesprochen werden, wie beispielsweise in meinem letzten Beitrag über den MCP23017. Hier geht es nun um einen I2C Scanner Sketch, mit dem ihr I2C Adressen herausfinden könnt.

Damit ihr mehrere Bauteile über einen einzigen I2C Bus ansprechen könnt, muss jedes der Bauteile eine eigene I2C Adresse besitzen. Der Adressraum beschränkt sich auf die Adressen 1 bis 127. Genau genommen sogar auf 8 bis 127, da die Adressen 0 bis 7 reserviert sind. Da das nicht besonders viel ist, sind doppelt vergebene Adressen ohne weitere Maßnahmen nicht unwahrscheinlich. Deshalb haben die meisten I2C Bauteile zwei oder drei Eingänge, die ihr auf LOW oder HIGH legen könnt um mehrere Adressen einzustellen. Bei Modulen könnt ihr die Adresse manchmal auch über Jumper wählen.

Idealerweise findet ihr ein Datenblatt in dem die Adressierung beschrieben ist. Manchmal ist das jedoch nicht der Fall und dann braucht man einen I2C Scanner. Vielleicht funktioniert auch eine Schaltung einfach nicht und ihr wollt überprüfen, ob das verwendete I2C Bauteil überhaupt antwortet. Auch dann ist ein I2C Scanner sinnvoll. Darüber hinaus möchtet ihr vielleicht prüfen, für welche Übertragungsgeschwindigkeit euer I2C Bauteil geeignet ist. 

I2C – Übertragungsrate

Der I2C Bus besteht aus zwei Leitungen, die meistens als SDA und SCL bezeichnet werden. SDA überträgt die Daten, SCL gibt den Takt vor und bestimmt so die Datenrate. Es gibt 5 Datenraten:

  • Standard Mode, Takt: 100 KHz
  • Fast Mode: 400 KHz
  • Fast Mode Plus: 1 MHz
  • High Speed Mode: 3.4 MHz
  • Ultra Fast Mode: 5 MHz (nur unidirektional) 

Da bei jedem Takt ein Bit übertragen wird, entspricht die Taktrate der Datenrate in Bit/s. 

Welcher Takt eingestellt werden kann, hängt sowohl vom I2C Bauteil wie auch vom verwendeten Microcontroller ab. Der Arduino Uno kann maximal den Fast Mode.

Weitere Informationen über I2C findet Ihr hier auf Wikipedia. Die Wire Bibliothek wird auf den Arduinoseiten hier beschrieben. 

Der I2C Scanner Sketch

Der Sketch ist denkbar einfach. Wire.setClock() stellt die Übertragungsrate ein. Wire.beginTransmission(adresse) startet die Kommunikation mit dem I2C Bauteil. Wire.endTransmission() liefert „0“ zurück, wenn es geklappt hat. So arbeitet sich der Sketch sklavisch durch den Adressraum für jede Übertragungsrate.

#include<Wire.h>

void setup(){
  Wire.begin();
  Serial.begin(9600);
  Serial.println("I2C Scanner ist bereit.");
  Serial.println();
}

void loop() {
  scanI2C(100000);
  scanI2C(400000);
//  scanI2C(1000000); // nur aktivieren, wenn der Microcontroller diese Frequenz unterstützt
//  scanI2C(3400000); // nur aktivieren, wenn der Microcontroller diese Frequenz unterstützt
//  scanI2C(5000000); // nur aktivieren, wenn der Microcontroller diese Frequenz unterstützt
  
  Serial.println("****************************");
  Serial.println();
  delay(3000);
}

void scanI2C(long frequency){
  String normal = "standard mode (100 kHz):";
  String fast = "fast mode (400 kHz):";
  String fastPlus = "fast mode plus (1 MHz):";
  String highSpeed = "high speed mode (3.4 MHz):";
  String ultraSpeed = "ultra fast mode (5.0 MHz):";
  String defaultStr = " !!!!! Unzulässige Frequenz !!!!!";
  bool error = true;
  bool addressFound = false;

  Serial.print("Scanne im ");
  switch(frequency){
    case 100000:
      Serial.println(normal);
      break;
    case 400000:
      Serial.println(fast);
      break;
    case 1000000:
      Serial.println(fastPlus);
      break;
    case 3400000:
      Serial.println(highSpeed);
      break;
    case 5000000:
      Serial.println(ultraSpeed);
      break;
    default:
      Serial.println(defaultStr);
      break;
  }
  
  Wire.setClock(frequency);
  for(int i=1; i<128; i++){
    Wire.beginTransmission(i);
    error = Wire.endTransmission();
    if(error == 0){
      addressFound = true;
      Serial.print("0x");
      Serial.println(i,HEX);
    }
  }
  if(!addressFound){
    Serial.println("Keine Adresse erkannt");
  }
  Serial.println();
}

 

Beispielschaltung: MCP23017

Hier eine Bespielschaltung mit dem MCP23017. Falls der Sketch bei euch keine Adresse erkennt, könnte es an fehlenden Pull-Up Widerständen (4.7 kOhm) liegen. 

I2C Schaltung am Bispiel des MCP23017.
MCP23017 am Arduino – SDA: gelb, SCL: grün, Adressleitungen: blau.
Ausgabe des I2C Scanners auf dem seriellen Monitor
Ausgabe des I2C Scanners auf dem seriellen Monitor

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.