Was ist I2C? SDA, SCL, Pull-up-Widerstände und I2C-Scanner
Was ist I2C und wie funktioniert es? SDA und SCL, 7-Bit-Adressen, Pull-up-Berechnung, I2C-Scanner-Sketch, Adresskonflikte und Pins für Uno, ESP32, Pico.
I2C (Inter-Integrated Circuit) ist ein serielles Kommunikationsprotokoll, mit dem ein Mikrocontroller über nur zwei Signalleitungen (SDA und SCL) mit Dutzenden Sensoren, Displays und Modulen spricht. Man spricht es „I-Quadrat-C“ aus; in manchen Datenblättern heißt es IIC oder TWI (Two Wire Interface). Das I2C-LCD, das OLED-Display, der Beschleunigungssensor MPU6050, der Drucksensor BMP280 und das Uhrenmodul DS1307 aus deinen Arduino-Projekten nutzen alle dieses Protokoll; du kannst sie parallel an dieselben zwei Leitungen hängen und jedes Gerät über seine eigene Adresse ansprechen.
In dieser Anleitung lernst du, wie I2C elektrisch funktioniert, was die Adressen bedeuten, warum Pull-up-Widerstände Pflicht sind und wie du ihren Wert berechnest. Danach siehst du Schritt für Schritt eine Pin-Tabelle für Arduino Uno, ESP32 und Raspberry Pi Pico, einen I2C-Scanner-Sketch, der alle Geräte am Bus findet, ein Beispiel zum Auslesen von Registern ohne Bibliothek sowie Lösungen für typische Probleme wie Adresskonflikte.

Was ist I2C und wie funktioniert es?
I2C wurde 1982 von Philips (heute NXP) entwickelt, damit Chips auf derselben Platine mit wenigen Leitungen kommunizieren können. Am Bus gibt es zwei Rollen: den Controller (früher Master), der jede Übertragung startet und den Takt erzeugt, und die Targets (früher Slaves), die ihm antworten. In Arduino-Projekten ist der Controller fast immer der Arduino, ESP32 oder Pico, Sensoren und Displays sind die Targets.
- SDA (Serial Data): Die Datenleitung, auf der in beide Richtungen übertragen wird. Der Controller sendet Adressen und Befehle, der Sensor schickt seine Messwerte über dieselbe Leitung zurück.
- SCL (Serial Clock): Die Taktleitung. Bei jedem Taktimpuls wird ein Bit auf SDA gelesen; den Takt erzeugt der Controller.
- GND (gemeinsame Masse): Der Bezugspunkt der Signale. Auch Module mit getrennter Stromversorgung müssen eine gemeinsame Masse haben.
Die Leitungen arbeiten als Open-Drain: Kein Gerät treibt eine Leitung auf High, es kann sie nur auf Low ziehen. Den High-Pegel liefern die Pull-up-Widerstände, die SDA und SCL mit der Versorgungsspannung verbinden. Deshalb entsteht kein Kurzschluss, selbst wenn zwei Geräte gleichzeitig senden wollen; zieht ein Gerät die Leitung auf Low, sehen alle eine 0. Eine I2C-Nachricht läuft so ab:
- START: Während SCL High ist, zieht der Controller SDA von 1 auf 0, und alle Geräte am Bus hören zu.
- Adresse und Richtungsbit: Die 7-Bit-Adresse wird gesendet, gefolgt von einem Lese- (1) oder Schreibbit (0).
- ACK: Das Gerät mit dieser Adresse zieht SDA beim 9. Taktimpuls auf Low und meldet damit „Ich bin da“. Tut das niemand, nennt man das NACK.
- Datenbytes: Jedes Byte wird als 8 Bit gesendet, und der Empfänger bestätigt jedes mit einem ACK. Bei den meisten Sensoren ist das erste Byte die Nummer des Registers, das gelesen oder beschrieben werden soll.
- STOP: Während SCL High ist, steigt SDA von 0 auf 1, und der Bus ist wieder frei. Beim Lesen wird statt STOP ein wiederholtes START (Repeated Start) verwendet, damit die Richtung wechseln kann, ohne den Bus freizugeben.
Ein Vergleich mit den beiden anderen verbreiteten Protokollen der Arduino-Welt zeigt, wann I2C die richtige Wahl ist:
| Eigenschaft | I2C | SPI | UART (Seriell) |
|---|---|---|---|
| Signalleitungen | 2 (SDA, SCL) | 3 gemeinsame (MOSI, MISO, SCK) + je Gerät ein CS | 2 (TX, RX) |
| Anzahl der Geräte | Über 100 Adressen an einem Bus | So viele wie freie CS-Pins | Meist 2 Geräte |
| Typische Geschwindigkeit | 100 kHz, 400 kHz, 1 MHz | 10 MHz und mehr | 9600 – 115200 Baud |
| Geräteauswahl | Über die Adresse | Über den CS-Pin | Keine, Punkt-zu-Punkt |
| Typischer Einsatz | Sensoren, Uhren, kleine Displays, EEPROM | SD-Karten, TFT-Displays, RFID | GPS, Bluetooth, Verbindung zum PC |
I2C-Geschwindigkeiten und technische Grenzen
| Modus | Höchste Geschwindigkeit | Maximale Anstiegszeit | Wo wird er genutzt? |
|---|---|---|---|
| Standard-Mode (Sm) | 100 kHz | 1000 ns | Standard, lange Leitungen |
| Fast-Mode (Fm) | 400 kHz | 300 ns | OLED, MPU6050, BMP280 |
| Fast-Mode Plus (Fm+) | 1 MHz | 120 ns | Pico und einige neuere Sensoren |
| High-Speed-Mode (Hs) | 3,4 MHz | 80 ns (400 pF), spezielle Treiber nötig | In Hobbyprojekten selten |
Die Wire-Bibliothek von Arduino startet standardmäßig mit 100 kHz; die meisten Sensoren unterstützen auch 400 kHz, und mit Wire.setClock(400000) schaltest du auf diese Geschwindigkeit um. Ein höherer Takt lässt Displays flüssiger aktualisieren, macht den Bus aber empfindlicher gegenüber Leitungslänge und Pull-up-Wert. Laut Standard darf die gesamte Buskapazität (Leitungen plus Gerätepins) 400 pF nicht überschreiten. Normale Jumper- und Flachbandkabel bringen 50–100 pF pro Meter mit, jeder Gerätepin bis zu 10 pF; deshalb wurde I2C für den Einsatz auf einer Platine oder mit Leitungen von einigen zehn Zentimetern entwickelt. Über 1 Meter musst du die Geschwindigkeit senken, stärkere Pull-ups verwenden oder Bus-Extender wie den P82B715 einsetzen.
I2C-Adressen: 7 Bit, 8 Bit und reservierte Adressen
Jedes Gerät am Bus hat eine 7-Bit-Adresse, was theoretisch 128 Adressen ergibt. Da die Bereiche 0x00–0x07 und 0x78–0x7F für Sonderzwecke reserviert sind, bleiben die 112 Adressen von 0x08 bis 0x77 nutzbar. Die Adresse legt meist der Chiphersteller fest; bei vielen Modulen kannst du aber die letzten Bits über Lötbrücken oder Pins wie A0, A1, A2 oder AD0 ändern.
Jetzt kommt der verwirrende Teil: Manche Datenblätter und die Aufdrucke auf der Rückseite von Modulen geben die Adresse als 8 Bit inklusive Richtungsbit an. Auf der Rückseite eines OLED-Boards steht zum Beispiel „0x78“, im Code lautet die Adresse aber 0x3C; steht auf einem LCD-Modul 0x4E, ist die Code-Adresse 0x27. Die Regel ist einfach: Teile den 8-Bit-Wert durch 2 (ein Bit nach rechts schieben), dann hast du die 7-Bit-Adresse. Die Bibliotheken für Arduino, ESP32 und MicroPython erwarten alle 7-Bit-Adressen.
| Modul | Chip | Standardadresse | Änderbar? |
|---|---|---|---|
| I2C-LCD-Modul (16x2, 20x4) | PCF8574 / PCF8574A | 0x27 / 0x3F | Mit A0–A2-Brücken: 0x20–0x27 bzw. 0x38–0x3F |
| 0,96-Zoll-OLED | SSD1306 | 0x3C | 0x3D über einen Widerstand auf der Rückseite |
| Beschleunigungssensor und Gyroskop | MPU6050 | 0x68 | 0x69, wenn AD0 = 1 |
| Echtzeituhr | DS1307 / DS3231 | 0x68 | Nein |
| Druck und Temperatur | BMP280 / BME280 | 0x76 oder 0x77 | Je nach SDO-Pin |
| Lichtstärke | BH1750 | 0x23 | 0x5C, wenn ADDR = 1 |
| 16-Bit-ADC | ADS1115 | 0x48 | 0x48–0x4B über den ADDR-Pin |
| 16-Kanal-Servo- und PWM-Treiber | PCA9685 | 0x40 | Dutzende Adressen ab 0x40 über A0–A5-Brücken |
| EEPROM-Speicher | AT24C32 / AT24C256 | 0x50 | 0x50–0x57 über A0–A2 |
| I2C-Multiplexer | TCA9548A | 0x70 | 0x70–0x77 über A0–A2 |
Pull-up-Widerstände: Warum sie nötig sind und wie du den Wert wählst
Da die Geräte am I2C-Bus die Leitungen nur auf Low ziehen können, liefern die Pull-up-Widerstände den High-Pegel. Ist der Widerstand zu groß, verlangsamt die Buskapazität den Wechsel von 0 auf 1, die Signalflanken werden rund und bei hohen Geschwindigkeiten werden Bits falsch gelesen. Ist er zu klein, steigt der Strom, den ein Gerät beim Herunterziehen der Leitung aufnehmen muss; der Standard verlangt nur, dass ein Gerät bei 0,4 V mindestens 3 mA aufnehmen kann, also muss der Pull-up den Strom darunter halten.
Diese Formeln liefern die beiden Grenzen: Der kleinste Widerstand ist R(min) = (VCC − 0,4 V) / 3 mA, der größte R(max) = t(Anstieg) / (0,8473 × C(Bus)). Für 5 V ergibt sich R(min) = 4,6 V / 0,003 A ≈ 1,53 kΩ, für 3,3 V ≈ 0,97 kΩ. An einem kurzen Bus mit 100 pF Kapazität liegt R(max) bei 100 kHz bei ≈ 11,8 kΩ und bei 400 kHz bei ≈ 3,5 kΩ. Deshalb sind in der Praxis 4,7 kΩ für 100 kHz und 2,2 kΩ für 400 kHz und volle Busse die üblichsten Werte. Mit dem Werkzeug Widerstand-Farbcode liest du die Farbringe eines Widerstands ab, und mit RC-Zeitkonstante siehst du die Verzögerung, die Widerstand und Kapazität erzeugen.
| Situation | Empfohlener Pull-up | Hinweis |
|---|---|---|
| Ein Modul, kurze Leitungen, 100 kHz | 4,7 kΩ – 10 kΩ | Die meisten Module haben sie schon |
| Mehrere Module, 400 kHz | 2,2 kΩ – 4,7 kΩ | Die Widerstände der Module liegen parallel |
| Leitungen länger als 50 cm | 2,2 kΩ und 100 kHz | SDA nicht mit SCL verdrillen, sondern jede mit GND |
| 3,3-V-Bus (ESP32, Pico) | 2,2 kΩ – 4,7 kΩ | Widerstände an 3,3 V anschließen, nicht an 5 V |
Beim Arduino Uno schaltet Wire.begin() zusätzlich die internen 20–50-kΩ-Pull-ups des ATmega328P ein. Mit einem einzigen Modul und 10–20 cm Leitung reichen sie oft aus, zuverlässig sind sie aber nicht; externe Widerstände sind immer besser. Nutzt du eine nackte Sensorplatine ohne Pull-ups, vergiss nicht, je einen 4,7-kΩ-Widerstand von SDA und SCL nach VCC zu setzen.
I2C-Pins: Arduino Uno, Mega, ESP32, ESP8266 und Pico
| Board | SDA | SCL | Hinweis |
|---|---|---|---|
| Arduino Uno / Nano | A4 | A5 | Beim Uno R3 sind die SDA- und SCL-Pins neben AREF derselbe Bus wie A4/A5 |
| Arduino Mega 2560 | 20 | 21 | Beim Mega sind A4 und A5 kein I2C |
| Arduino Leonardo / Micro | D2 | D3 | Das sind digitale Pins |
| ESP32 (DevKit) | GPIO 21 | GPIO 22 | Mit Wire.begin(SDA, SCL) sind andere Pins wählbar; der zweite Bus heißt Wire1 |
| ESP8266 NodeMCU | D2 (GPIO 4) | D1 (GPIO 5) | Software-I2C, Pins änderbar |
| Raspberry Pi Pico | GP4 (I2C0) | GP5 (I2C0) | I2C0 und I2C1 auf vielen Pin-Paaren verfügbar |
Schritt für Schritt: Adressen mit dem I2C-Scanner finden
Wenn du ein neues Modul bekommst, solltest du zuerst die Adressen der Geräte am Bus herausfinden. Ein I2C-Scanner schickt an jede Adresse von 0x08 bis 0x77 eine leere Nachricht und listet die Adressen auf, die mit ACK antworten. So erfährst du gleichzeitig, ob das Modul richtig verdrahtet ist und welche Adresse du in deinen Code schreiben musst.
- Verbinde GND des Moduls mit GND des Arduino und VCC mit 5V (bei Modulen, die nur 3,3 V vertragen, mit 3.3V).
- Verbinde SDA mit A4 und SCL mit A5. Bei mehreren Modulen verbindest du alle SDA- und alle SCL-Pins auf dem Steckbrett miteinander.
- Lade den Sketch unten hoch und öffne den seriellen Monitor mit 115200 Baud.
- Notiere dir die angezeigten Adressen. Erscheint nichts, prüfe Verdrahtung, gemeinsame Masse und Pull-up-Widerstände.
- Ziehe die Module nacheinander ab und stecke sie wieder an, um zu prüfen, welche Adresse zu welchem Gerät gehört; der Scanner sucht alle 5 Sekunden neu.
1#include <Wire.h>
2
3void printHex(byte addr) {
4 Serial.print(F("0x"));
5 if (addr < 16) Serial.print('0'); // tek haneliye sıfır ekle / pad single digit
6 Serial.print(addr, HEX);
7}
8
9void setup() {
10 Serial.begin(115200);
11 Wire.begin(); // Uno: A4 = SDA, A5 = SCL
12#if defined(ARDUINO_ARCH_AVR)
13 Wire.setWireTimeout(3000, true); // AVR (Uno, Nano, Mega): hat kilitlenirse 3 ms sonra kurtar / recover a stuck bus after 3 ms
14#endif
15 Serial.println(F("I2C tarayici / I2C scanner"));
16}
17
18void loop() {
19 byte found = 0;
20 for (byte addr = 0x08; addr <= 0x77; addr++) { // geçerli 7 bit adresler / valid 7-bit addresses
21 Wire.beginTransmission(addr);
22 byte err = Wire.endTransmission(); // 0 = cihaz ACK verdi / device acknowledged
23 if (err == 0) {
24 Serial.print(F("Bulundu / found: "));
25 printHex(addr);
26 Serial.println();
27 found++;
28 } else if (err == 4 || err == 5) {
29 Serial.print(F("Hat hatasi / bus error at "));
30 printHex(addr);
31 Serial.println();
32 }
33 }
34 if (found == 0) {
35 Serial.println(F("Cihaz yok: kablolari ve pull-up'lari kontrol et / no devices: check wiring and pull-ups"));
36 } else {
37 Serial.print(found);
38 Serial.println(F(" cihaz bulundu / device(s) found"));
39 }
40 Serial.println();
41 delay(5000); // 5 sn sonra yeniden tara / rescan after 5 s
42}| Rückgabe von endTransmission() | Bedeutung | Was tun? |
|---|---|---|
| 0 | Gerät hat seine Adresse bestätigt (ACK) | Diese Adresse im Code verwenden |
| 1 | Daten zu lang für den Puffer | Kommt beim Scanner nicht vor; beim Uno nie mehr als 32 Byte auf einmal schreiben |
| 2 | NACK auf die Adresse | Kein Gerät unter dieser Adresse, beim Scannen normal |
| 3 | NACK auf die Daten | Gerät hat den Befehl abgelehnt; Registernummer prüfen |
| 4 | Anderer Busfehler | Kurzschluss, fehlende Pull-ups oder Störungen |
| 5 | Timeout | Bus hängt; Verdrahtung und Stromversorgung prüfen |
Die Zeile setWireTimeout im Sketch ist wichtig: Wenn SDA oder SCL kurzgeschlossen ist oder ein Gerät die Leitung auf Low festhält, kann die Wire-Bibliothek des Uno mit Standardeinstellungen ewig warten und dein Programm einfrieren. Mit aktiviertem Timeout gibt die Bibliothek nach 3 ms auf, setzt die I2C-Hardware zurück, und der Scanner meldet das Problem mit einem Fehlercode. Die Zeile steht in einem #if, damit sie nur auf AVR-Boards (Uno, Nano, Mega) kompiliert wird; die Wire-Bibliotheken von ESP32 und ESP8266 bringen bereits einen eigenen Timeout-Schutz mit, daher kompiliert und läuft derselbe Sketch unverändert auf allen drei Plattformen.
I2C ohne Bibliothek: Register lesen und schreiben
Bibliotheken erleichtern die Arbeit, aber im Hintergrund machen sie alle dasselbe: Sie schicken dem Gerät die Registernummer und lesen dann Bytes aus diesem Register oder schreiben welche hinein. Wenn du das einmal selbst machst, kannst du das Datenblatt eines neuen Sensors lesen und ihn auch ohne Bibliothek nutzen. Das folgende Beispiel weckt den MPU6050 aus dem Schlafmodus, liest sein Identitätsregister (WHO_AM_I) und berechnet dann Temperatur und Beschleunigung auf der Z-Achse aus den Rohwerten.

1#include <Wire.h>
2
3const byte MPU_ADDR = 0x68; // AD0 GND'de; AD0 = 3.3V ise 0x69 / AD0 low; 0x69 if AD0 high
4
5void writeReg(byte reg, byte value) {
6 Wire.beginTransmission(MPU_ADDR);
7 Wire.write(reg); // önce yazmaç adresi / register address first
8 Wire.write(value); // sonra veri / then the data
9 Wire.endTransmission(); // STOP gönder / send STOP
10}
11
12int16_t readWord(byte reg) {
13 Wire.beginTransmission(MPU_ADDR);
14 Wire.write(reg);
15 Wire.endTransmission(false); // STOP yok, tekrarlı START / no STOP, repeated START
16 Wire.requestFrom(MPU_ADDR, (byte)2); // 2 bayt iste / request 2 bytes
17 uint8_t hi = Wire.read();
18 uint8_t lo = Wire.read();
19 return (int16_t)(((uint16_t)hi << 8) | lo);
20}
21
22void setup() {
23 Serial.begin(115200);
24 Wire.begin();
25 Wire.setClock(400000); // hızlı mod 400 kHz / fast mode 400 kHz
26 writeReg(0x6B, 0x00); // PWR_MGMT_1: uykudan uyandır / wake up from sleep
27 Wire.beginTransmission(MPU_ADDR);
28 Wire.write(0x75); // WHO_AM_I yazmacı / WHO_AM_I register
29 Wire.endTransmission(false);
30 Wire.requestFrom(MPU_ADDR, (byte)1);
31 Serial.print(F("WHO_AM_I = 0x"));
32 Serial.println(Wire.read(), HEX); // 68 beklenir / expect 68
33}
34
35void loop() {
36 int16_t raw = readWord(0x41); // TEMP_OUT_H ve TEMP_OUT_L / TEMP_OUT_H and TEMP_OUT_L
37 float tempC = raw / 340.0 + 36.53; // veri sayfasındaki formül / datasheet formula
38 int16_t az = readWord(0x3F); // Z ekseni ivmesi / Z-axis acceleration
39 Serial.print(F("Sicaklik / temp: "));
40 Serial.print(tempC, 1);
41 Serial.print(F(" C AccZ: "));
42 Serial.println(az / 16384.0, 2); // +-2g aralığında 16384 = 1 g / 16384 = 1 g at +-2g
43 delay(500);
44}Achte auf die Zeile endTransmission(false) in der Lesefunktion: Sie wechselt mit einem Repeated Start statt eines STOP die Richtung, sodass kein anderes Gerät dazwischenfunken kann und der Sensor nicht vergisst, welches Register angefragt wurde. Liefert WHO_AM_I den Wert 0x68, funktioniert die Kommunikation einwandfrei. Bei günstigen Klonmodulen kann der Wert 0x70 oder eine andere Zahl sein; dann steckt ein kompatibler, aber anderer Chip wie der MPU6500 darauf, und genau deshalb melden manche fertigen Bibliotheken „Sensor nicht gefunden“. Die Temperaturformel (Rohwert / 340 + 36,53) stammt direkt aus dem MPU6050-Datenblatt; bei der Beschleunigung im Bereich ±2 g entspricht ein Rohwert von 16384 genau 1 g, ein flach auf dem Tisch liegender Sensor zeigt auf der Z-Achse also etwa 1,00.
Mehrere Geräte an einem Bus und Adresskonflikte
Der größte Vorteil von I2C ist, dass du Geräte parallel an dieselben zwei Leitungen anschließen kannst, solange ihre Adressen verschieden sind. Ein LCD (0x27), ein OLED (0x3C), ein BMP280 (0x76) und eine DS3231-Uhr (0x68) teilen sich zum Beispiel problemlos A4 und A5; jede Bibliothek spricht mit ihrer eigenen Adresse, während die anderen Geräte still mithören. Ärger gibt es, wenn zwei Geräte dieselbe Adresse haben: Beide senden ein ACK, ihre Daten überlagern sich, und meist funktioniert keines von beiden. So löst du das Problem:
- Adresspin ändern: Verbindest du AD0 des MPU6050 mit 3,3 V, wird seine Adresse 0x69, und der Konflikt mit der DS3231 (0x68) ist weg.
- Lötbrücken nutzen: Die A0–A2-Brücken auf LCD-Modulen bieten 8 Adressen, der ADDR-Pin des ADS1115 bietet 4.
- Zweiten I2C-Bus öffnen: Lege das kollidierende Gerät beim ESP32 mit Wire1 oder beim Pico mit I2C1 auf eigene Pins.
- I2C-Multiplexer einsetzen: Der TCA9548A öffnet unter einer einzigen Adresse (0x70) acht getrennte Unterbusse; so kannst du sogar acht OLEDs mit gleicher Adresse anschließen.
- Geräte mit fester Adresse: Bei manchen Chips wie dem DS1307 oder HTU21D lässt sich die Adresse gar nicht ändern; hier helfen nur ein eigener Bus oder ein Multiplexer.
I2C am ESP32: freie Pinwahl und zwei getrennte Busse
Beim ESP32 lässt sich die I2C-Hardware flexibel auf die Pins legen. Standard sind GPIO 21 (SDA) und GPIO 22 (SCL), mit Wire.begin(SDA, SCL) kannst du aber fast zwei beliebige GPIOs wählen. Der klassische ESP32 und der ESP32-S3 haben zwei I2C-Controller, sodass du zwei Sensoren mit gleicher Adresse an zwei getrennten Bussen betreiben kannst; der ESP32-C3 hat nur einen Controller. GPIO 34–39 sind reine Eingänge und eignen sich nicht für I2C. Die vollständige Pinbelegung findest du im Werkzeug Pinout, eine allgemeine Einführung im Artikel Was ist der ESP32?.
1#include <Wire.h>
2
3// Klasik ESP32'de iki I2C denetleyicisi vardır: Wire ve Wire1 / the classic ESP32 has two I2C controllers: Wire and Wire1
4
5void scan(TwoWire &bus, const char *name) {
6 Serial.printf("%s:\n", name);
7 for (uint8_t addr = 0x08; addr <= 0x77; addr++) {
8 bus.beginTransmission(addr);
9 if (bus.endTransmission() == 0) {
10 Serial.printf(" bulundu / found 0x%02X\n", addr);
11 }
12 }
13}
14
15void setup() {
16 Serial.begin(115200);
17 Wire.begin(21, 22); // SDA, SCL: varsayılan pinler / default pins
18 Wire1.begin(32, 33, 400000); // SDA, SCL, hız: başka iki GPIO / SDA, SCL, speed: any two other GPIOs
19 scan(Wire, "Wire (SDA 21, SCL 22)");
20 scan(Wire1, "Wire1 (SDA 32, SCL 33)");
21}
22
23void loop() {
24}I2C mit dem Raspberry Pi Pico (MicroPython)
Der RP2040-Chip des Pico hat zwei Controller namens I2C0 und I2C1, und jeder lässt sich auf mehrere Pin-Paare legen. Für I2C0 kannst du GP0/GP1, GP4/GP5, GP8/GP9, GP12/GP13, GP16/GP17 und GP20/GP21 nutzen, für I2C1 GP2/GP3, GP6/GP7, GP10/GP11, GP14/GP15, GP18/GP19 und GP26/GP27. In jedem Paar ist der gerade Pin SDA und der ungerade SCL. In MicroPython ist der Scanner eine einzige Zeile: i2c.scan() gibt eine Liste der Adressen zurück, die mit ACK antworten. Da der Pico mit 3,3 V arbeitet, ist die Versorgung der Module über den Pin 3V3(OUT) am sichersten; der RP2040 beherrscht zwar auch den Fast-Mode Plus mit 1 MHz, auf dem Steckbrett gibt es mit 400 kHz aber weniger Überraschungen. Für deine ersten Schritte mit dem Pico lies Was ist der Raspberry Pi Pico?.
1from machine import Pin, I2C
2
3i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000) # I2C0: GP4 = SDA, GP5 = SCL
4devices = i2c.scan() # ACK veren adresler / addresses that ACK
5
6if devices:
7 for addr in devices:
8 print("Bulundu / found:", hex(addr))
9else:
10 print("Cihaz yok / no devices")
11
12# MPU6050 varsa WHO_AM_I yazmacını oku / if an MPU6050 is present, read WHO_AM_I
13if 0x68 in devices:
14 i2c.writeto_mem(0x68, 0x6B, b"\x00") # uykudan uyandır / wake up
15 who = i2c.readfrom_mem(0x68, 0x75, 1)[0]
16 print("WHO_AM_I:", hex(who)) # 0x68 beklenir / expect 0x68Projektideen mit I2C
- Mini-Wetterstation: Miss Luftdruck und Temperatur mit einem BMP280 und zeige sie auf einem OLED-Display an; beide Module teilen sich dieselben zwei Leitungen.
- Digitaluhr: Lies die Uhrzeit aus einem DS3231-Modul und gib sie auf einem I2C-LCD aus.
- Neigungsanzeige: Berechne den Winkel mit einem MPU6050 und zeichne das Ergebnis auf dem OLED wie eine Wasserwaage.
- WLAN-Sensorknoten: Überwache einen Sensor an den Pins D1 und D2 eines ESP8266 NodeMCU vom Handy aus.
- Roboterarm mit 16 Servos: Steuere mit einem PCA9685-Treiber 16 Servos über nur zwei Pins.
- Datenlogger: Schreibe jede Minute einen Messwert in ein AT24C256-EEPROM, damit die Daten auch einen Stromausfall überstehen.
Häufige Fehler und Lösungen
| Symptom | Mögliche Ursache | Lösung |
|---|---|---|
| Der Scanner findet kein Gerät | SDA und SCL vertauscht, keine gemeinsame Masse oder Modul ohne Strom | Verdrahtung prüfen; beim Uno ist A4 = SDA und A5 = SCL |
| Der Scanner hängt oder meldet bei jeder Adresse Fehler | Bus kurzgeschlossen oder Pull-ups fehlen | setWireTimeout ergänzen; Versorgungsspannung an ruhendem SDA und SCL messen |
| Der Sketch kompiliert, aber das Display bleibt leer | Falsche Adresse im Code (0x27 statt 0x3F) | Die vom Scanner gefundene Adresse eintragen |
| Auf der Rückseite steht 0x78, der Code funktioniert nicht | 8-Bit-Adresse verwendet | Durch 2 teilen: 0x78 → 0x3C |
| Zwei Sensoren funktionieren nicht zusammen | Adresskonflikt | Adresspin ändern, zweiten Bus oder TCA9548A nutzen |
| Zufällige Hänger, Störungen wenn ein Motor läuft | Lange Leitungen, Störungen oder schwache Versorgung | Leitungen kürzen, auf 100 kHz gehen, 100-nF-Kondensatoren an die Module |
| Ein Pin von ESP32 oder Pico ist beschädigt | Pull-ups an 5 V mit einem 3,3-V-Pin verbunden | Modul mit 3,3 V versorgen oder Pegelwandler verwenden |
I2C ist der praktischste Weg, deinem Projekt mit nur zwei Leitungen Displays, Uhren, Sensoren und Speicher hinzuzufügen; sobald du Adressen, Pull-up-Widerstände und den Scanner-Sketch verstanden hast, löst du die meisten Probleme in wenigen Minuten. In der BlueGrays-App findest du Projekte mit I2C wie das I2C-LCD, das Pong-Spiel auf einem OLED-Display, eine Digitaluhr mit DS1307 und eine ESP32-Wetteranzeige, jeweils mit Schritt-für-Schritt-Schaltplänen und Code.
Häufige Fragen
Was ist der Unterschied zwischen I2C und SPI?
I2C bringt dank Adressierung über hundert Geräte an dieselben zwei Leitungen, ist aber typischerweise auf 100–400 kHz begrenzt. SPI braucht drei gemeinsame Leitungen und für jedes Gerät einen eigenen Chip-Select-Pin (CS), erreicht dafür aber 10 MHz und mehr. Für Sensoren und kleine Displays nimmt man I2C, für SD-Karten und farbige TFT-Displays SPI.
Wie viele Geräte kann man an einen I2C-Bus anschließen?
Mit 7-Bit-Adressierung gibt es 112 nutzbare Adressen. In der Praxis begrenzen weniger die Adressen als die Buskapazität (maximal 400 pF) und die parallel liegenden Pull-up-Widerstände; auf dem Steckbrett laufen 5–10 Geräte problemlos. Für mehr nutzt du einen TCA9548A-Multiplexer oder einen zweiten I2C-Bus.
Welchen Wert sollten I2C-Pull-up-Widerstände haben?
Am häufigsten sind 4,7 kΩ für 100 kHz und kurze Leitungen sowie 2,2 kΩ für 400 kHz oder Busse mit vielen Geräten. An einem 5-V-Bus solltest du nicht unter 1,5 kΩ gehen, an einem 3,3-V-Bus nicht unter 1 kΩ. Denk auch daran, dass die Widerstände auf deinen Modulen parallel liegen.
Welche Pins sind beim Arduino Uno I2C?
Beim Arduino Uno und Nano ist SDA der Pin A4 und SCL der Pin A5. Der Uno R3 hat neben AREF zwei weitere Pins mit der Aufschrift SDA und SCL, die auf der Platine aber mit A4 und A5 verbunden sind und keinen eigenen Bus bilden. Beim Mega sind die I2C-Pins 20 (SDA) und 21 (SCL).
Wie lang darf ein I2C-Kabel maximal sein?
I2C wurde für kurze Strecken auf einer Platine entwickelt; bei 100 kHz und passenden Pull-ups funktioniert es meist bis etwa 1 Meter. Für längere Strecken musst du die Geschwindigkeit senken, verdrillte Kabel verwenden oder auf Bustreiber wie den P82B715 umsteigen. Für mehrere Meter sind RS-485 oder eine Funkverbindung die bessere Wahl.
Was tun, wenn der I2C-Scanner mein Gerät nicht findet?
Prüfe zuerst, ob SDA und SCL an den richtigen Pins stecken, die gemeinsame Masse verbunden ist und das Modul Strom hat. Kontrolliere dann die Pull-ups, indem du an ruhendem SDA und SCL die Versorgungsspannung misst. Wird es immer noch nicht gefunden, teste das Modul allein mit kurzen Leitungen bei 100 kHz, und achte beim ESP32 darauf, Wire.begin die richtigen Pins zu übergeben.
Projekte, die du danach bauen kannst
Alle Projekte ansehen
Verwendung des LCD-Bildschirms mit I2C
Dank des I2C-Moduls druckt das Projekt Nachrichten, indem es den LCD-Bildschirm mit nur 2 Kabeln (SDA, SCL) steuert. Es lehrt, wie man Pins mit dem I2C-Protokoll speichern kann.

ESP32 I2C-LCD-Display (16×2)
In diesem Projekt zeigen wir Text an, indem wir ein 16x2-Zeichen-LCD-Display über das I2C-Protokoll an den ESP32 anschließen. Dank I2C können wir das Display mit nur zwei Datenpins (SDA und SCL) steuern; die Verschwendung von 6+ Pins bei einer klassischen parallelen Verbindung entfällt. Der Code schreibt in die erste Zeile eine feste Meldung und in die zweite Zeile einen Zähler, der sich jede Sekunde erhöht. Außerdem lassen wir zu Beginn den I2C-Scanner laufen und geben die Adresse des Displays

Digitale Uhr mit ESP32 und RTC DS1307 (I2C + LCD)
In diesem Projekt zeigen wir Uhrzeit und Datum auf einem 16x2-I2C-LCD-Display mithilfe des DS1307-Echtzeituhrmoduls (RTC) an. Das DS1307 ist ein batteriegestütztes RTC, das die Uhrzeit auch dann beibehält, wenn das ESP32 ausgeschaltet ist. Beide Module teilen sich denselben I2C-Bus (SDA/SCL), sodass wir mit nur zwei Signalkabeln die Steuerung mehrerer Geräte erlernen. So lernen Sie das I2C-Protokoll und die Funktionsweise von RTC-Modulen in der Praxis kennen.

Arduino I2C-Rechner
Es handelt sich um ein Arduino-basiertes Taschenrechnerprojekt, das Addition, Subtraktion, Multiplikation und Division mit einer 4x4-Folientastatur und einem 16x2 I2C-LCD-Display durchführt. Dank I2C ist der Anschluss des Displays mit nur 2 Kabeln möglich, was den Kabelsalat reduziert und mehr Pins für die Verwendung offen hält. Die Eingabe von Dezimalzahlen und die Unterstützung negativer Zahlen sind ebenfalls möglich.

Pong-Spiel - SSD1306
Das klassische Pong-Spiel, gebaut mit Arduino und SSD1306 OLED-Display, ausgestattet mit einer autonomen künstlichen Intelligenz (CPU) Gegner, die sofort verfolgt die Bewegungen des Balls und reagiert

ESP32 HTTPClient + Wetter-API (mit SSD1306-OLED-Display)
In diesem Projekt führen wir mit dem ESP32 über das Internet mithilfe von `HTTPClient.h` einen REST-API-Aufruf an die Wetter-API (wttr.in) durch. Im Gegensatz zur vorherigen I2C-LCD-Version verwenden wir hier ein SSD1306-OLED-Display (128×64) – dies ermöglicht große Schriftarten, Vektor-Symbole und eine reichhaltige visuelle Darstellung auf einem einzigen Bildschirm. Für die Wetteranzeige werden 7 verschiedene Vektor-Symbole (sonnig, teilweise bewölkt, bewölkt, regnerisch, schneereich, stürmisch

Punktmatrixuhr und Kalender (MAX7219, DS1307)
Es handelt sich um ein Projekt, das Echtzeit-Uhr- und Kalenderinformationen auf einem MAX7219 8x32 Punktmatrix-LED-Display mit DS1307 RTC-Modul anzeigt. In der Uhranzeige blinken jede Sekunde zwei Pun

ESP32 Temperatur-Datenlogger (DHT22 + DS1307 RTC + microSD + OLED)
Baue einen zeitgestempelten Temperaturlogger mit ESP32! Lese Temperatur/Feuchtigkeit vom DHT22 alle 10 Sekunden, hole die aktuelle Zeit vom DS1307 RTC und protokolliere auf microSD-Karte als CSV. Das OLED zeigt live Temperatur (große Schrift), Luftfeuchtigkeit, Zeitstempel und Logzähler. Die `/temp_log.csv`-Datei auf der SD-Karte öffnet sich in Excel, Google Sheets oder Python pandas zur Analyse — perfekt für Gewächshausüberwachung, Raumtemperaturverfolgung, Laboraufzeichnung, Lebensmittellageru
Weitere Artikel
Lerne das I2C-Protokoll kennen, mit dem du Dutzende Sensoren und Displays an nur zwei Leitungen betreibst: Adressen, Pull-up-Widerstände, ein I2C-Scanner-Sketch und Lösungen für die häufigsten Fehler, mit Beispielen.

