Qu'est-ce que l'I2C ? SDA, SCL, résistances pull-up et scanner
L'I2C, comment ça marche ? SDA et SCL, adresses 7 bits, calcul des pull-up, code scanner I2C, conflits d'adresse et broches Arduino Uno, ESP32 et Pico.
L'I2C (Inter-Integrated Circuit) est un protocole de communication série qui permet à un microcontrôleur de dialoguer avec des dizaines de capteurs, d'écrans et de modules à l'aide de deux fils de signal seulement (SDA et SCL). On le prononce « I-deux-C » ou « I-carré-C », et certaines fiches techniques le nomment IIC ou TWI (Two Wire Interface). L'écran LCD I2C, l'écran OLED, l'accéléromètre MPU6050, le capteur de pression BMP280 et le module horloge DS1307 de tes projets Arduino utilisent tous ce protocole ; tu peux les brancher en parallèle sur les deux mêmes fils et joindre chacun grâce à sa propre adresse.
Dans ce guide, tu vas apprendre comment l'I2C fonctionne électriquement, ce que signifient les adresses, pourquoi les résistances pull-up sont indispensables et comment calculer leur valeur. Ensuite, étape par étape, tu verras un tableau des broches pour l'Arduino Uno, l'ESP32 et la Raspberry Pi Pico, un code scanner I2C qui trouve tous les appareils du bus, un exemple de lecture de registres sans bibliothèque et les solutions aux problèmes courants comme les conflits d'adresse.

Qu'est-ce que l'I2C et comment fonctionne-t-il ?
L'I2C a été créé en 1982 par Philips (aujourd'hui NXP) pour que les puces d'une même carte communiquent avec peu de fils. Il y a deux rôles sur le bus : le contrôleur (autrefois appelé maître), qui lance chaque échange et génère l'horloge, et les cibles (autrefois esclaves), qui lui répondent. Dans les projets Arduino, le contrôleur est presque toujours l'Arduino, l'ESP32 ou la Pico, tandis que les capteurs et les écrans sont les cibles.
- SDA (Serial Data) : La ligne qui transporte les données dans les deux sens. Le contrôleur envoie les adresses et les commandes, et le capteur renvoie ses mesures sur la même ligne.
- SCL (Serial Clock) : La ligne d'horloge. Un bit de SDA est lu à chaque impulsion d'horloge, et c'est le contrôleur qui génère l'horloge.
- GND (masse commune) : La référence des signaux. Même les modules alimentés séparément doivent partager une masse commune.
Les lignes sont à drain ouvert (open-drain) : aucun appareil ne force une ligne à l'état haut, il peut seulement la tirer vers le bas. Ce qui maintient la ligne à 1, ce sont les résistances pull-up qui relient SDA et SCL à la tension d'alimentation. C'est pourquoi il n'y a pas de court-circuit même si deux appareils tentent de parler en même temps ; si l'un d'eux tire la ligne vers le bas, tout le monde voit un 0. Un message I2C se déroule ainsi :
- START : Pendant que SCL est à l'état haut, le contrôleur fait passer SDA de 1 à 0, et tous les appareils du bus se mettent à écouter.
- Adresse et bit de sens : L'adresse sur 7 bits est envoyée, suivie d'un bit de lecture (1) ou d'écriture (0).
- ACK : L'appareil qui possède cette adresse tire SDA vers le bas pendant la 9e impulsion d'horloge pour dire « je suis là ». Si personne ne le fait, on parle de NACK.
- Octets de données : Chaque octet est envoyé sur 8 bits et le récepteur répond à chacun par un ACK. Sur la plupart des capteurs, le premier octet est le numéro du registre à lire ou à écrire.
- STOP : Pendant que SCL est à l'état haut, SDA remonte de 0 à 1 et le bus est de nouveau libre. Pour les lectures, on utilise un START répété (repeated start) au lieu d'un STOP pour changer de sens sans libérer le bus.
Comparer l'I2C aux deux autres protocoles courants du monde Arduino montre clairement quand le choisir :
| Caractéristique | I2C | SPI | UART (série) |
|---|---|---|---|
| Fils de signal | 2 (SDA, SCL) | 3 partagés (MOSI, MISO, SCK) + un CS par appareil | 2 (TX, RX) |
| Nombre d'appareils | Plus de 100 adresses sur un bus | Autant que de broches CS libres | En général 2 appareils |
| Vitesse typique | 100 kHz, 400 kHz, 1 MHz | 10 MHz et plus | 9600 – 115200 bauds |
| Sélection de l'appareil | Par l'adresse | Par la broche CS | Aucune, point à point |
| Usage typique | Capteurs, horloges, petits écrans, EEPROM | Cartes SD, écrans TFT, RFID | GPS, Bluetooth, liaison avec l'ordinateur |
Vitesses de l'I2C et limites techniques
| Mode | Vitesse maximale | Temps de montée maximal | Où l'utilise-t-on ? |
|---|---|---|---|
| Mode standard (Sm) | 100 kHz | 1000 ns | Par défaut, fils longs |
| Mode rapide (Fm) | 400 kHz | 300 ns | OLED, MPU6050, BMP280 |
| Mode rapide plus (Fm+) | 1 MHz | 120 ns | Pico et certains capteurs récents |
| Mode haute vitesse (Hs) | 3,4 MHz | 80 ns (400 pF), pilotes spéciaux nécessaires | Rare dans les projets amateurs |
La bibliothèque Wire d'Arduino démarre par défaut à 100 kHz ; la plupart des capteurs acceptent aussi 400 kHz, et tu passes à cette vitesse avec Wire.setClock(400000). Une vitesse plus élevée rend le rafraîchissement des écrans plus fluide, mais le bus devient plus sensible à la longueur des fils et à la valeur des pull-up. Selon la norme, la capacité totale du bus (fils et broches des appareils) ne doit pas dépasser 400 pF. Les câbles Dupont et les nappes ordinaires ajoutent 50 à 100 pF par mètre et chaque broche d'appareil jusqu'à 10 pF ; c'est pourquoi l'I2C a été conçu pour fonctionner sur une même carte ou avec des fils de quelques dizaines de centimètres. Au-delà de 1 mètre, il faut réduire la vitesse, utiliser des pull-up plus fortes ou ajouter des prolongateurs de bus comme le P82B715.
Adresses I2C : 7 bits, 8 bits et adresses réservées
Chaque appareil du bus possède une adresse sur 7 bits, ce qui donne en théorie 128 adresses. Comme les plages 0x00–0x07 et 0x78–0x7F sont réservées à des usages particuliers, les adresses utilisables sont les 112 adresses de 0x08 à 0x77. L'adresse est généralement fixée par le fabricant de la puce, mais sur de nombreux modules tu peux modifier ses derniers bits avec des ponts de soudure ou des broches nommées A0, A1, A2 ou AD0.
Voici le point qui prête à confusion : certaines fiches techniques et les inscriptions au dos des modules donnent l'adresse sur 8 bits, bit de sens compris. Par exemple, le dos d'une carte OLED indique « 0x78 », alors que l'adresse dans le code est 0x3C ; si un module LCD indique 0x4E, l'adresse dans le code est 0x27. La règle est simple : divise la valeur sur 8 bits par 2 (décale-la d'un bit vers la droite) et tu obtiens l'adresse sur 7 bits. Les bibliothèques Arduino, ESP32 et MicroPython attendent toutes des adresses sur 7 bits.
| Module | Puce | Adresse par défaut | Modifiable ? |
|---|---|---|---|
| Module LCD I2C (16x2, 20x4) | PCF8574 / PCF8574A | 0x27 / 0x3F | Avec les ponts A0–A2 : 0x20–0x27 ou 0x38–0x3F |
| OLED 0,96 pouce | SSD1306 | 0x3C | 0x3D via une résistance au dos |
| Accéléromètre et gyroscope | MPU6050 | 0x68 | 0x69 si AD0 = 1 |
| Horloge temps réel | DS1307 / DS3231 | 0x68 | Non |
| Pression et température | BMP280 / BME280 | 0x76 ou 0x77 | Selon la broche SDO |
| Intensité lumineuse | BH1750 | 0x23 | 0x5C si ADDR = 1 |
| CAN 16 bits | ADS1115 | 0x48 | 0x48–0x4B via la broche ADDR |
| Pilote servo et PWM 16 canaux | PCA9685 | 0x40 | Des dizaines d'adresses à partir de 0x40 via les ponts A0–A5 |
| Mémoire EEPROM | AT24C32 / AT24C256 | 0x50 | 0x50–0x57 via A0–A2 |
| Multiplexeur I2C | TCA9548A | 0x70 | 0x70–0x77 via A0–A2 |
Résistances pull-up : pourquoi elles sont nécessaires et comment choisir leur valeur
Comme les appareils d'un bus I2C ne peuvent que tirer les lignes vers le bas, ce sont les résistances pull-up qui fournissent l'état haut. Si la résistance est trop grande, la capacité du bus ralentit le passage de 0 à 1, les fronts du signal s'arrondissent et des bits sont mal lus à haute vitesse. Si elle est trop petite, le courant qu'un appareil doit absorber en tirant la ligne vers le bas augmente ; la norme exige seulement qu'un appareil puisse absorber au moins 3 mA à 0,4 V, donc la pull-up doit maintenir le courant en dessous.
Ces formules donnent les deux limites : la résistance minimale vaut R(min) = (VCC − 0,4 V) / 3 mA et la maximale R(max) = t(montée) / (0,8473 × C(bus)). Pour 5 V, on obtient R(min) = 4,6 V / 0,003 A ≈ 1,53 kΩ, et pour 3,3 V ≈ 0,97 kΩ. Sur un bus court de 100 pF, R(max) ≈ 11,8 kΩ à 100 kHz et ≈ 3,5 kΩ à 400 kHz. C'est pourquoi, en pratique, les valeurs les plus utilisées sont 4,7 kΩ pour 100 kHz et 2,2 kΩ pour 400 kHz et les bus chargés. Tu peux utiliser l'outil Code couleur des résistances pour lire les anneaux d'une résistance et l'outil Constante de temps RC pour voir le retard créé par la résistance et la capacité.
| Situation | Pull-up conseillée | Remarque |
|---|---|---|
| Un module, fils courts, 100 kHz | 4,7 kΩ – 10 kΩ | La plupart des modules en ont déjà |
| Plusieurs modules, 400 kHz | 2,2 kΩ – 4,7 kΩ | Les résistances des modules se retrouvent en parallèle |
| Fils de plus de 50 cm | 2,2 kΩ et 100 kHz | Ne torsade pas SDA avec SCL ; torsade chacune avec GND |
| Bus 3,3 V (ESP32, Pico) | 2,2 kΩ – 4,7 kΩ | Relie les résistances au 3,3 V, pas au 5 V |
Sur l'Arduino Uno, l'appel à Wire.begin() active aussi les résistances pull-up internes de 20 à 50 kΩ de l'ATmega328P. Avec un seul module et 10 à 20 cm de fil, elles suffisent souvent, mais elles ne sont pas fiables ; des résistances externes sont toujours préférables. Si tu utilises une carte capteur nue sans pull-up, n'oublie pas d'ajouter une résistance de 4,7 kΩ entre SDA et VCC, et une autre entre SCL et VCC.
Broches I2C : Arduino Uno, Mega, ESP32, ESP8266 et Pico
| Carte | SDA | SCL | Remarque |
|---|---|---|---|
| Arduino Uno / Nano | A4 | A5 | Sur l'Uno R3, les broches SDA et SCL près d'AREF sont le même bus que A4/A5 |
| Arduino Mega 2560 | 20 | 21 | Sur le Mega, A4 et A5 ne sont pas de l'I2C |
| Arduino Leonardo / Micro | D2 | D3 | Ce sont des broches numériques |
| ESP32 (DevKit) | GPIO 21 | GPIO 22 | Autres broches possibles avec Wire.begin(SDA, SCL) ; le second bus est Wire1 |
| ESP8266 NodeMCU | D2 (GPIO 4) | D1 (GPIO 5) | I2C logiciel, broches modifiables |
| Raspberry Pi Pico | GP4 (I2C0) | GP5 (I2C0) | I2C0 et I2C1 disponibles sur de nombreuses paires de broches |
Pas à pas : trouver les adresses avec le scanner I2C
Quand tu reçois un nouveau module, la première chose à faire est de connaître les adresses des appareils du bus. Un scanner I2C envoie un message vide à chaque adresse de 0x08 à 0x77 et affiche celles qui répondent par un ACK. Tu vérifies ainsi à la fois que le module est bien câblé et quelle adresse tu dois mettre dans ton code.
- Relie la GND du module à la GND de l'Arduino et son VCC au 5V (au 3.3V pour les modules qui n'acceptent que 3,3 V).
- Relie SDA à A4 et SCL à A5. Si tu as plusieurs modules, réunis toutes leurs broches SDA et toutes leurs broches SCL sur la breadboard.
- Téléverse le code ci-dessous et ouvre le moniteur série à 115200 bauds.
- Note les adresses affichées. Si rien n'apparaît, vérifie le câblage, la masse commune et les résistances pull-up.
- Débranche et rebranche les modules un par un pour confirmer quelle adresse correspond à quel appareil ; le scanner relance la recherche toutes les 5 secondes.
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ésultat de endTransmission() | Signification | Que faire ? |
|---|---|---|
| 0 | L'appareil a reconnu son adresse (ACK) | Utilise cette adresse dans ton code |
| 1 | Données trop longues pour le tampon | N'apparaît pas dans le scanner ; sur l'Uno, n'écris jamais plus de 32 octets d'un coup |
| 2 | NACK sur l'adresse | Aucun appareil à cette adresse, normal pendant le scan |
| 3 | NACK sur les données | L'appareil a refusé la commande ; vérifie le numéro de registre |
| 4 | Autre erreur de bus | Court-circuit, pull-up manquantes ou parasites |
| 5 | Délai dépassé | Le bus est bloqué ; vérifie le câblage et l'alimentation |
La ligne setWireTimeout du code est importante : quand SDA ou SCL est en court-circuit, ou qu'un appareil reste bloqué en maintenant la ligne à l'état bas, la bibliothèque Wire de l'Uno avec ses réglages par défaut peut attendre indéfiniment et figer ton programme. Avec le délai activé, la bibliothèque abandonne au bout de 3 ms, réinitialise le matériel I2C et le scanner signale le problème avec un code d'erreur. La ligne est placée dans un #if pour n'être compilée que sur les cartes AVR (Uno, Nano, Mega) ; les bibliothèques Wire de l'ESP32 et de l'ESP8266 ont déjà leur propre protection par délai, donc le même code se compile et fonctionne sans modification sur les trois plateformes.
L'I2C sans bibliothèque : lire et écrire des registres
Les bibliothèques simplifient le travail, mais en coulisses elles font toutes la même chose : elles envoient le numéro de registre à l'appareil, puis lisent ou écrivent des octets dans ce registre. Le faire toi-même une fois te permet de lire la fiche technique d'un nouveau capteur et de l'utiliser même sans bibliothèque. L'exemple ci-dessous réveille le capteur MPU6050 de son mode veille, lit son registre d'identité (WHO_AM_I), puis calcule la température et l'accélération sur l'axe Z à partir des valeurs brutes.

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}Fais attention à la ligne endTransmission(false) de la fonction de lecture : elle change de sens avec un START répété au lieu d'un STOP, si bien qu'aucun autre appareil ne peut s'intercaler et que le capteur n'oublie pas quel registre a été demandé. Si WHO_AM_I renvoie 0x68, la communication est parfaite. Sur les modules clones bon marché, la valeur peut être 0x70 ou un autre nombre ; cela indique une puce compatible mais différente, comme le MPU6500, et c'est la raison pour laquelle certaines bibliothèques toutes faites affichent « capteur introuvable ». La formule de température (valeur brute / 340 + 36,53) vient directement de la fiche technique du MPU6050 ; pour l'accélération sur la plage ±2 g, une valeur brute de 16384 correspond à 1 g, donc un capteur posé à plat sur la table affiche environ 1,00 sur l'axe Z.
Plusieurs appareils sur un même bus et conflits d'adresse
Le grand avantage de l'I2C est que tu peux brancher des appareils en parallèle sur les deux mêmes fils tant que leurs adresses sont différentes. Par exemple, un LCD (0x27), un OLED (0x3C), un BMP280 (0x76) et une horloge DS3231 (0x68) partagent sans problème les broches A4 et A5 ; chaque bibliothèque parle à sa propre adresse pendant que les autres appareils écoutent en silence. Les ennuis commencent quand deux appareils ont la même adresse : les deux répondent par un ACK, leurs données se mélangent et, en général, aucun ne fonctionne. Voici les solutions :
- Change la broche d'adresse : Si tu relies la broche AD0 du MPU6050 au 3,3 V, son adresse devient 0x69 et le conflit avec le DS3231 (0x68) disparaît.
- Utilise les ponts de soudure : Les ponts A0–A2 des modules LCD offrent 8 adresses et la broche ADDR de l'ADS1115 en offre 4.
- Ouvre un second bus I2C : Déplace l'appareil en conflit sur d'autres broches avec Wire1 sur l'ESP32 ou I2C1 sur la Pico.
- Ajoute un multiplexeur I2C : Le TCA9548A ouvre huit sous-bus séparés à partir d'une seule adresse (0x70) ; tu pourrais même brancher huit OLED ayant la même adresse.
- Appareils à adresse fixe : Sur certaines puces, comme le DS1307 ou le HTU21D, l'adresse ne peut pas être changée du tout ; seuls un bus séparé ou un multiplexeur règlent alors le problème.
L'I2C sur l'ESP32 : les broches de ton choix et deux bus séparés
Sur l'ESP32, le matériel I2C peut être routé de manière flexible vers les broches. Les broches par défaut sont GPIO 21 (SDA) et GPIO 22 (SCL), mais avec Wire.begin(SDA, SCL) tu peux choisir presque n'importe quelle paire de GPIO. L'ESP32 classique et l'ESP32-S3 ont deux contrôleurs I2C : tu peux donc faire fonctionner deux capteurs de même adresse sur deux bus séparés ; l'ESP32-C3 n'a qu'un seul contrôleur. Les GPIO 34 à 39 sont uniquement des entrées et ne peuvent pas servir à l'I2C. Pour le brochage complet de la carte, consulte l'outil Pinout, et pour une introduction générale l'article Qu'est-ce que l'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}L'I2C avec la Raspberry Pi Pico (MicroPython)
La puce RP2040 de la Pico possède deux contrôleurs, I2C0 et I2C1, et chacun peut être routé vers plusieurs paires de broches. Pour I2C0, tu peux utiliser GP0/GP1, GP4/GP5, GP8/GP9, GP12/GP13, GP16/GP17 et GP20/GP21 ; pour I2C1, GP2/GP3, GP6/GP7, GP10/GP11, GP14/GP15, GP18/GP19 et GP26/GP27. Dans chaque paire, la broche de numéro pair est SDA et celle de numéro impair est SCL. En MicroPython, le scanner tient en une ligne : i2c.scan() renvoie la liste des adresses qui répondent par un ACK. Comme la Pico fonctionne en 3,3 V, alimenter les modules par la broche 3V3(OUT) est la solution la plus sûre ; même si le RP2040 gère aussi le mode rapide plus à 1 MHz, rester à 400 kHz sur une breadboard réserve moins de surprises. Pour tes premiers pas avec la Pico, lis Qu'est-ce que la 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 0x68Idées de projets avec l'I2C
- Mini station météo : Mesure la pression et la température avec un BMP280 et affiche-les sur un écran OLED ; les deux modules partagent les deux mêmes fils.
- Horloge numérique : Lis l'heure d'un module DS3231 et affiche-la sur un écran LCD I2C.
- Indicateur d'inclinaison : Calcule l'angle avec un MPU6050 et dessine le résultat sur l'OLED comme un niveau à bulle.
- Nœud capteur Wi-Fi : Surveille depuis ton téléphone un capteur branché sur les broches D1 et D2 d'un ESP8266 NodeMCU.
- Bras robotique à 16 servos : Pilote 16 servos avec deux broches seulement grâce au driver PCA9685.
- Enregistreur de données : Écris une mesure par minute dans une EEPROM AT24C256 pour que les données survivent à une coupure de courant.
Erreurs fréquentes et solutions
| Symptôme | Cause probable | Solution |
|---|---|---|
| Le scanner ne trouve aucun appareil | SDA et SCL inversés, pas de masse commune ou module non alimenté | Vérifie le câblage ; sur l'Uno, A4 = SDA et A5 = SCL |
| Le scanner se bloque ou signale une erreur à chaque adresse | Bus en court-circuit ou pull-up absentes | Ajoute setWireTimeout ; mesure la tension d'alimentation sur SDA et SCL au repos |
| Le code compile mais l'écran reste vide | Mauvaise adresse dans le code (0x27 au lieu de 0x3F) | Mets l'adresse trouvée par le scanner |
| Le dos indique 0x78 et le code ne marche pas | L'adresse sur 8 bits a été utilisée | Divise par 2 : 0x78 → 0x3C |
| Deux capteurs ne fonctionnent pas ensemble | Conflit d'adresse | Change la broche d'adresse, utilise un second bus ou un TCA9548A |
| Blocages aléatoires, erreurs quand un moteur tourne | Fils longs, parasites ou alimentation faible | Raccourcis les fils, descends à 100 kHz, ajoute des condensateurs de 100 nF aux modules |
| Une broche de l'ESP32 ou de la Pico est abîmée | Pull-up reliées au 5 V branchées sur une broche 3,3 V | Alimente le module en 3,3 V ou utilise un convertisseur de niveau |
L'I2C est le moyen le plus pratique d'ajouter des écrans, des horloges, des capteurs et de la mémoire à ton projet avec seulement deux fils ; une fois que tu maîtrises les adresses, les résistances pull-up et le code scanner, tu résous la plupart des problèmes en quelques minutes. Dans l'application BlueGrays, tu trouveras des projets qui utilisent l'I2C, comme l'écran LCD I2C, le jeu Pong sur écran OLED, une horloge numérique avec DS1307 et un affichage météo avec ESP32, avec schémas de câblage et code pas à pas.
Questions fréquentes
Quelle est la différence entre I2C et SPI ?
L'I2C utilise des adresses pour brancher plus d'une centaine d'appareils sur les deux mêmes fils, mais il est généralement limité à 100–400 kHz. Le SPI demande trois fils partagés et une broche de sélection (CS) par appareil ; en échange, il atteint 10 MHz et plus. On préfère l'I2C pour les capteurs et les petits écrans, et le SPI pour les cartes SD et les écrans TFT couleur.
Combien d'appareils peut-on brancher sur un bus I2C ?
L'adressage sur 7 bits offre 112 adresses utilisables. En pratique, la limite vient moins du nombre d'adresses que de la capacité du bus (400 pF maximum) et des résistances pull-up en parallèle ; sur une breadboard, 5 à 10 appareils fonctionnent sans souci. Au-delà, utilise un multiplexeur TCA9548A ou un second bus I2C.
Quelle valeur choisir pour les résistances pull-up I2C ?
Les valeurs les plus courantes sont 4,7 kΩ pour 100 kHz et des fils courts, et 2,2 kΩ pour 400 kHz ou les bus avec beaucoup d'appareils. Ne descends pas sous 1,5 kΩ sur un bus 5 V ni sous 1 kΩ sur un bus 3,3 V. Pense aussi que les résistances de tes modules se retrouvent en parallèle.
Quelles sont les broches I2C de l'Arduino Uno ?
Sur l'Arduino Uno et le Nano, SDA est la broche A4 et SCL la broche A5. L'Uno R3 possède deux autres broches marquées SDA et SCL à côté d'AREF, mais elles sont reliées à A4 et A5 sur la carte et ne forment pas un bus distinct. Sur le Mega, les broches I2C sont la 20 (SDA) et la 21 (SCL).
Quelle longueur de câble maximale pour l'I2C ?
L'I2C a été conçu pour de courtes distances sur une carte ; à 100 kHz et avec des pull-up adaptées, il fonctionne en général jusqu'à environ 1 mètre. Pour des distances plus grandes, il faut réduire la vitesse, utiliser du câble à paires torsadées ou passer à des pilotes de bus comme le P82B715. Pour plusieurs mètres, le RS-485 ou une liaison sans fil sont de meilleurs choix.
Que faire si le scanner I2C ne trouve pas mon appareil ?
Vérifie d'abord que SDA et SCL sont sur les bonnes broches, que la masse commune est branchée et que le module est alimenté. Contrôle ensuite les pull-up en mesurant la tension d'alimentation sur SDA et SCL au repos. S'il reste introuvable, teste le module seul avec des fils courts à 100 kHz, et sur l'ESP32 vérifie que tu as passé les bonnes broches à Wire.begin.
Projets à réaliser après cet article
Voir tous les projets
Utilisation de l'écran LCD avec I2C
Grâce au module I2C, le projet qui imprime des messages en contrôlant l'écran LCD avec seulement 2 câbles (SDA, SCL). Il enseigne comment économiser des pins avec le protocole I2C.

Écran LCD I2C ESP32 (16x2)
Dans ce projet, nous affichons du texte en connectant un écran LCD 16x2 à l'ESP32 via le protocole I2C. Grâce à l'I2C, nous pouvons contrôler l'écran avec seulement 2 broches de données (SDA et SCL) ; cela évite le gaspillage de 6 broches ou plus inhérent à la connexion parallèle classique. Le code affiche un message fixe sur la première ligne et un compteur qui augmente chaque seconde sur la deuxième ligne. De plus, au démarrage, nous lançons un scanner I2C pour afficher l'adresse de l'écran su

Horloge numérique avec ESP32 et RTC DS1307 (I2C + LCD)
Dans ce projet, nous affichons l'heure et la date sur un écran LCD 16x2 I2C à l'aide du module d'horloge en temps réel (RTC) DS1307. Le DS1307 est une RTC avec batterie de secours qui conserve l'heure même si l'ESP32 s'éteint. Les deux modules partagent la même ligne I2C (SDA/SCL), ce qui nous permet d'apprendre à contrôler plusieurs appareils avec seulement deux fils de signal. Vous decouvrirez ainsi le protocole I2C et le fonctionnement des modules RTC en pratique.

Calculatrice Arduino I2C
Il s'agit d'un projet de calculatrice basé sur Arduino qui effectue des opérations d'addition, de soustraction, de multiplication et de division à l'aide d'un clavier à membrane 4x4 et d'un écran LCD I2C 16x2. Grâce à l'I2C, la connexion de l'écran n'est assurée que par deux câbles, ce qui réduit l'encombrement des câbles et permet d'utiliser plus de broches. L'entrée de nombres décimaux et la prise en charge des nombres négatifs sont également disponibles.

Jeu de pong - SSD1306
Le jeu Pong classique construit à l'aide d'Arduino et d'un écran OLED SSD1306, équipé d'une intelligence artificielle (CPU) autonome qui suit instantanément les mouvements de la balle et réagit en fon

ESP32 HTTPClient + API météo (avec écran OLED SSD1306)
Dans ce projet, nous effectuons un appel à l'API REST de la météo (wttr.in) via Internet à l'aide de l'ESP32 et de la bibliothèque `HTTPClient.h`. Contrairement à la version précédente avec écran LCD I2C, nous utilisons ici un écran OLED SSD1306 (128×64) — ce qui permet d’afficher une police de grande taille, des icônes vectorielles et une présentation visuelle riche sur un seul écran. Sept icônes vectorielles différentes représentant les conditions météorologiques (ensoleillé, partiellement nua

Horloge et calendrier matriciel (MAX7219, DS1307)
Il s'agit d'un projet qui affiche l'horloge et le calendrier en temps réel sur un écran LED matriciel à points MAX7219 8x32 avec un module RTC DS1307. Dans l'affichage de l'horloge, deux points cligno

Enregistreur de Température ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
Construis un enregistreur de température horodaté avec ESP32 ! Lis la température/humidité du DHT22 toutes les 10 secondes, obtiens l'heure réelle du DS1307 RTC et enregistre sur carte microSD au format CSV. L'OLED affiche en direct la température (grande police), le pourcentage d'humidité, l'horodatage et le compteur. Le fichier `/temp_log.csv` sur la carte SD s'ouvre dans Excel, Google Sheets ou Python pandas pour analyse — parfait pour surveillance de serre, suivi de température à domicile, c
Autres articles
Découvre le protocole I2C, qui te permet de brancher des dizaines de capteurs et d'écrans sur deux fils seulement : adresses, résistances pull-up, code scanner I2C et solutions aux erreurs les plus courantes, avec des exemples.

