Post

Das I²C Protokoll und Auslesen von I²C Adressen angeschlossener Geräte

Für die Ansteuerung komplexer Kontrollen werden üblicherweise Kommunikationsprotokolle verwendet. Ein sehr populäres Protokoll ist das I²C-Bus-Protokoll (steht für inter-integrated circuit). Eine Erklärung über die internen Details gibt es hier https://fmh-studios.de/theorie/informationstechnik/i2c-bus.

Dieses Busprotokoll selbst zu implementieren, wäre ziemlich aufwändig. Daher verwendet man am besten eine fertige Arduino-Bibliothek.

Nachfolgend versuche das mal selbst und teste das I²C Protokoll mit der Wire-Bibliothek. Damit versuche ich mal, von I²C Geräten wie dem LCD16x02 Display (oder LCD 20x04) die Adresse auszulesen.

Anschluss des Displays

Am LiquidCrystal-Display sind nur 4 Pins, diese sind wie folgt zu verbinden:

  • GND -> an Arduino GND
  • VCC -> an Arduino +5V
  • SDA -> an Arduino SDA (Pin D18)
  • SCL -> an Arduino SCL (Pin D19)

siehe auch Pinout-Diagramm:

Arduino Uno Rev3 Pinout

Hier die Schaltung. Die Adapterplatine, die die LCD-Eingänge auf I²C umsetzt ist bei vielen LCD-Modulen bereits angelötet.

Arduino LCD I²C Schaltung

Die SDA/SCL Pins sind je nach Board fest vorgegeben, siehe auch Tabelle in Arduine Wire Library docs. Beispielsweise sind beim Arduino Mega 2560 die Pins SDA = D20 und SCL = D21 zu verwenden.

Die unten verwendete Standardbibliothek Wire erlaubt keine nutzerseitige Umdefinition der Pins. Es gibt aber andere Bibliotheken für das I²C Protokoll, bei denen man die Pins umbelegen kann. Es ist aber guter Stil (und erlaubt auch das leichtere Nachbauen von Schaltungen), wenn man sich an die Standardports hält und z.B. die SDA/SCL Pins beim Breadboard auf eine Seite der +- Schiene klemmt. Dann kann man bequem mehrere I²C-Bus-Geräte anklemmen.

Test mit I²C Adressenscan

Es wird die Bibliothek Wire verwendet, siehe Arduine Wire Library docs.

Beim Scan wird einfach probiert, auf allen 127 Adressen zu kommunizieren. Wenn das erfolgreich ist, wird ein Gerät auf der Adresse als gefunden angezeigt. Hier ist das Beispielprogramm dafür:

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
/* Testprogramm für die Verwendung des I²C-Protokolls am Arduino.

Man verbindet das I²C-Gerät, bspw. das LCD16x02 Display via folgender Pins:
- GND mit GND
- VCC mit +5V
- SDA mit SDA (D18)
- SCL mit SCL (D19)
*/
#include <Wire.h>

void setup() {
  // I²C Bibliothek initialisieren
  Wire.begin();

  Serial.begin(115200);
  Serial.println("---I2C Scanner---");
}

void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for (address = 1; address < 127; ++address) {
    // Kommunikationsversuch an der Adresse
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    // Kommunikationsversuch an der Folgeadresse
    Wire.beginTransmission(address + 1);

    if (error == 0 && Wire.endTransmission() != 0) { // Special flag for SAMD Series
      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");

  delay(5000);  // wait 5 seconds for next scan
}

Man kann sich die Ausgabe des Programms mit dem Serial Monitor anzeigen lassen, siehe auch meine Erläuterungen dazu im Blog zum Serial Monitor.

This post is licensed under CC BY 4.0 by the author.