I²C: Das Kommunikationsprotokoll einfach und klar erklärt
Die Funktion von I²C
Das ist ein vollwertiger Auszug aus dem Buch Elektronik und Heimautomation DIY.
I²C (Inter-Integrated Circuit) ist ein Kommunikationsprotokoll, das Philips in den 1980er-Jahren entwickelt hat, um Komponenten mit nur zwei Leitungen zu verbinden:
– SDA (Serial Data Line): Überträgt Daten.
– SCL (Serial Clock Line): Sendet Taktimpulse.
Im Gegensatz zu UART arbeitet I²C synchron und erreicht Geschwindigkeiten von 100 Kbps bis 3,4 Mbps. Die Leitungen benötigen Pull-up-Widerstände (4,7–10 kΩ), die bei speziellen Mikrocontroller-Pins oft schon integriert sind.
Ein I²C-Bus unterstützt bis zu 112 Geräte bei 7-Bit-Adressen oder bis zu 1008 Geräte bei 10-Bit-Adressen. Jeder Teilnehmer hat eine eindeutige Adresse, um Kollisionen zu vermeiden.
Im Multi-Master-Betrieb können mehrere Master und Slaves im selben Bus arbeiten. Ein Master darf nur dann senden, wenn die SDA-Leitung auf HIGH ist, um die bestehende Kommunikation nicht zu stören.
Das Clock Signal
Das Clock-Signal synchronisiert die Übertragung der Datenbits vom Master mit dem Abtasten der Bits durch den Slave. In jedem Taktzyklus wird ein Datenbit übertragen, was die Geschwindigkeit der Datenübertragung bestimmt.
Um sicherzustellen, dass das Datensignal ausreichend Zeit hat, vom LOW– auf den HIGH-Pegel oder umgekehrt zu wechseln, werden die Daten genau in der Mitte des HIGH-Signals des Clock-Signals abgetastet.
Das I²C Protokoll
Die Kommunikation wird vom Master durch das Senden eines Start-Bits eingeleitet, gefolgt von der Adresse des Teilnehmers, mit dem er kommunizieren möchte, und einem RW-Bit (Read/Write), das angibt, ob der Master Daten an den Slave senden oder von ihm lesen möchte. Alle Slaves im Bus reagieren auf das Start-Bit und vergleichen ihre eigene Adresse mit der vom Master gesendeten. Der Slave mit der richtigen Adresse sendet ein Acknowledge (ACK)-Bit zurück, um zu bestätigen, dass er bereit ist, Daten auszutauschen.
Anschließend überträgt der Master die Adresse des internen Registers des Slaves, auf das er zugreifen möchte, um Daten zu lesen oder zu schreiben. Der Slave bestätigt dies erneut, und der Datenaustausch kann beginnen. Die Kommunikation endet, wenn der Master ein Stop-Bit sendet, wodurch der Bus wieder freigegeben wird.

Start
Geräte (Slave) Adresse
Ack.
Int. Register Adresse
Ack.
Daten
Ack. Stop
Das Start und Stop-bit
Start-Bit: Das Start-Bit wird erzeugt, indem die Datenleitung von HIGH auf LOW gesetzt wird, noch bevor das Clock-Signal von HIGH auf LOW wechselt.
Stop-Bit: Das Stop-Bit wird genau umgekehrt erzeugt: Die Datenleitung geht von LOW auf HIGH, nachdem das Clock-Signal von LOW auf HIGH gewechselt ist.
Adressierung (Ax) und das Read/Write bit
Nach dem Start-Bit sendet der Master die Adresse des Slaves, mit dem er Daten austauschen möchte. Die Adresse kann entweder 7 Bit (Standard) oder 10 Bit groß sein. In unserem Beispiel verwenden wir eine 7-Bit-Adresse. Als achtes Bit (RW) gibt der Master an, ob er Daten an den Slave senden möchte (0 – write) oder ob er Daten vom Slave lesen will (1 – read). Beim Schreiben in den Slave wird das RW-Bit auf 0 gesetzt, beim Lesen auf 1.
Im Beispiel sendet der Master, der mit dem Slave mit der Adresse 0x59 kommunizieren möchte, folgende Daten (10110010) in einem 1-Byte Block (8 Bit). Der Datensatz wird mit dem MSB (Most Significant Bit) zuerst gesendet, also beginnt der Master bei Bit A6 (ganz links).
Acknowledge (ACK) und Not Acknowledge (NACK)
Nach jedem übertragenen Byte sendet der Empfänger ein Bestätigungs-Bit. Wenn das Bit LOW ist (ACK), signalisiert dies dem Master, dass der Slave die Adresse oder die Daten erfolgreich empfangen hat und alles in Ordnung ist.
Tritt jedoch ein Problem auf, wie zum Beispiel, dass der Slave die Daten nicht lesen kann oder gerade mit einer anderen Aufgabe beschäftigt ist und keine Zeit für die Kommunikation hat, sendet der Slave ein HIGH Signal (NACK), um anzuzeigen, dass er die Anfrage nicht verarbeiten kann.
Adressierung vom internen Register (Bx)
Ein Gerät wie der BME280 Sensor hat eine eindeutige Adresse, aber es verfügt über verschiedene Register, in denen Werte wie Temperatur, Luftdruck und Luftfeuchtigkeit gespeichert sind. Diese Register können nicht nur gelesen, sondern auch beschrieben werden. Zum Beispiel kann das 0xF5 „Config“-Register verändert werden, um verschiedene Optionen zu setzen.
Nach dem Senden des Daten-Bytes zur Registeradressierung wird vom Slave ein ACK-Bit gesendet, um dem Master zu bestätigen, dass die Adresse korrekt empfangen wurde.

Start
Geräte (Slave) Adresse
Ack.
Int. Register Adresse
Ack.
Die Datenübertragung (Dx)
Nachdem der Master das ACK-Bit für die interne Registeradresse vom Slave erhalten hat, kann die eigentliche Datenübertragung beginnen. Ein Block von Daten ist immer 1 Byte groß (8 Bit) und wird mit dem Most Significant Bit (MSB) zuerst übertragen. Zum besseren Verständnis hier ein Beispiel:
Wenn wir den HEX-Wert 0xD0 senden möchten, entspricht dies dem 8-Bit-Binärwert 11010000. Da MSB (links) zuerst gesendet wird, beginnen wir mit dem ersten Bit (1), gefolgt von der nächsten 1 und so weiter, bis alle 8 Bits übertragen wurden.
Beim Least Significant Bit (LSB) hingegen beginnen wir auf der rechten Seite und senden die Bits in umgekehrter Reihenfolge: Zuerst die 0, dann die nächste 0 und so weiter.
Nach jedem übertragenen Byte bestätigt der Slave den Empfang mit einem ACK-Bit. Die Daten können nun Byte für Byte gesendet werden, bis der Master ein Stop-Bit sendet und damit die Kommunikation beendet.

Datensatz 1
Ack.
Datensatz 2
Ack. Stop

Daten lesen vom Slave
Das Datenlesen von einem Slave funktioniert fast genauso wie das Beschreiben eines Slaves. Der Master sendet zuerst die Geräteadresse, gefolgt von einer 1 im RW-Bit (lesen). Nachdem der Master das ACK-Bit vom Slave erhalten hat, überträgt er die Registeradresse, aus der er Daten lesen möchte.

Start
Geräte (Slave) Adresse
Ack.
Int. Register Adresse
Ack.
Die Daten werden vom Slave zum Master gesendet, jedoch wird das Clock-Signal weiterhin vom Master bereitgestellt. Nach jedem empfangenen Byte sendet der Master ein ACK-Bit an den Slave, um den Empfang zu bestätigen. Der Slave sendet daraufhin das nächste Byte, bis der Master die Übertragung mit einem NACK-Bit (Not Acknowledge) und einem Stop-Bit beendet.

Datensatz 1
Ack.
Datensatz 2
Nack. Stop
Standard I²C Pins unterschiedlicher Mikrocontroller
Hier findet ihr eine Übersicht über verschiedene Mikrocontroller und die Standard-Pins für die Kommunikation über I²C.
Bei Mikrocontrollern der ESP-Serie sind die I²C-Pins flexibel und können mithilfe der Funktion Wire.begin(SDA, SCL) frei definiert werden, was eine hohe Anpassungsfähigkeit ermöglicht.
Bei Mikrocontrollern wie dem Arduino UNO oder Arduino Nano, die den ATmega328P verwenden, sind die I²C-Pins hingegen fest mit den Pins A4 (SDA) und A5 (SCL) verbunden. Diese Zuordnung ist hardwareseitig vorgegeben und kann nicht geändert werden.
Falls du jedoch andere Pins für die I²C-Kommunikation nutzen möchtest, kannst du auf eine Software-I²C-Bibliothek zurückgreifen. Diese emuliert die I²C-Protokollfunktionalität und erlaubt die Verwendung beliebiger digitaler Pins, ist jedoch in der Regel etwas langsamer als die hardwarebasierte Lösung.
Standard Pins für I²C
Mikrocontroller | SDA (Datenleitung) | SCL (Clockleitung) |
---|---|---|
ESP8266 | GPIO 4 (D2) | GPIO 5 (D1) |
Wemos D1 Mini | GPIO 4 (D2) | GPIO 5 (D1) |
ESP32 | GPIO 21 | GPIO 22 |
Wemos D1 Mini ESP32 | GPIO 21 | GPIO 22 |
Arduino Nano ESP32 | GPIO 11 | GPIO 12 |
Arduino Nano | A4 | A5 |
Arduino UNO | A4 | A5 |
Arduino Mega | 20 | 21 |