Come funzionano gli indirizzi I²C
Ogni dispositivo su un bus I²C risponde a un indirizzo a 7 bit, da 0x08 a 0x77. Molti chip permettono di scegliere tra due, quattro o otto indirizzi collegando alcuni pin a massa o all’alimentazione; altri hanno un solo indirizzo fisso. Due dispositivi sullo stesso indirizzo rispondono insieme, e le letture di entrambi sono inutilizzabili.
Alcuni datasheet danno valori a 8 bit, cioè l’indirizzo spostato a sinistra con in più il bit di lettura/scrittura: il VL53L0X è indicato come 0x52/0x53, il BMP180 come 0xEE/0xEF. Spostando a destra di un bit ottieni l’indirizzo a 7 bit usato da librerie e scanner: 0x29 e 0x77.
Indirizzi riservati
| Indirizzo | |
|---|---|
| 0x00 | Chiamata generale (scrittura) o byte di START (lettura) |
| 0x01 | Indirizzo CBUS |
| 0x02 | Riservato a un formato di bus diverso |
| 0x03 | Riservato a usi futuri |
| 0x04–0x07 | Codice del controller in modalità Hs |
| 0x78–0x7B | Indirizzamento a 10 bit |
| 0x7C–0x7F | Device ID |
Dalla specifica del bus I²C di NXP (UM10204). Per i tuoi dispositivi usa solo gli indirizzi da 0x08 a 0x77.
Quando due dispositivi sono in conflitto
Prima cerca un pin di indirizzo: spostare un dispositivo è la soluzione più pulita. Se entrambi hanno l’indirizzo fisso, come un orologio DS3231 e un DS1307, o ti servono due sensori uguali senza pin di indirizzo, usa un multiplexer TCA9548A, che dà otto rami separati dietro un unico indirizzo, oppure metti il secondo dispositivo su un altro bus I²C. ESP32, ESP32-S3 e RP2040 hanno due controller I²C; l’ESP32-C3 ne ha uno.
Scoprire cosa c’è sul bus
In ESPHome il componente i2c scansiona il bus all’avvio e scrive nel log gli indirizzi che trova. In Arduino lo sketch I2C scanner fa lo stesso sul monitor seriale. Se un dispositivo non compare, controlla alimentazione, SDA e SCL, le pull-up e il suo pin di indirizzo.
Resistenze di pull-up
Le linee I²C sono open-drain: i chip le portano solo verso il basso e le resistenze le riportano in alto. Con una pull-up troppo forte i chip non riescono ad abbassare abbastanza la linea; con una troppo debole la linea sale troppo lentamente per la velocità scelta. La specifica dà entrambi i limiti.
Rmin = (VDD − 0,4 V) ÷ 3 mA (VDD > 2 V; 20 mA a 1 MHz) Rmax = tr ÷ (0,8473 × Cbus) tr = 1000 ns a 100 kHz, 300 ns a 400 kHz, 120 ns a 1 MHz
Tutti i dispositivi dell’elenco
| Indirizzo | |||
|---|---|---|---|
| QMC5883L | magnetometro a 3 assi | 0x0D | indirizzo fisso |
| VEML6075 | sensore di luce UVA/UVB | 0x10 | indirizzo fisso |
| VEML7700 | sensore di luce ambiente ad alta precisione | 0x10 | indirizzo fisso |
| LIS2DH12 | accelerometro a 3 assi | 0x18, 0x19 | SA0: GND → 0x18 · VDD → 0x19 |
| MCP9808 | sensore di temperatura digitale | 0x18–0x1F | A2 A1 A0 → 0x18–0x1F |
| MMA8451Q | accelerometro a 3 assi | 0x1C, 0x1D | SA0: GND → 0x1C · VDD → 0x1D |
| ADXL345 | accelerometro a 3 assi | 0x1D, 0x53 | ALT ADDRESS: GND → 0x53 · VDD → 0x1D |
| MCP23008 | espansore di I/O a 8 bit | 0x20–0x27 | A2 A1 A0 → 0x20–0x27 |
| MCP23017 | espansore di I/O a 16 bit | 0x20–0x27 | A2 A1 A0 → 0x20–0x27 |
| PCF8574 | espansore di I/O a 8 bit (moduli I²C per LCD) | 0x20–0x27 | A2 A1 A0 → 0x20–0x27 |
| PCF8575 | espansore di I/O a 16 bit | 0x20–0x27 | A2 A1 A0 → 0x20–0x27 |
| TCA9555 | espansore di I/O a 16 bit con interrupt | 0x20–0x27 | A2 A1 A0 → 0x20–0x27 |
| BH1750FVI (BH1750) | sensore di luce ambiente | 0x23, 0x5C | ADDR: GND → 0x23 · VCC → 0x5C |
| PN532 | controller NFC/RFID (modalità I²C) | 0x24 | indirizzo fisso |
| BNO055 | sensore di orientamento assoluto a 9 assi con fusione dei sensori integrata | 0x28, 0x29 | COM3: GND → 0x28 · VDD → 0x29 |
| TCS34725 | sensore di colore RGB | 0x29 | indirizzo fisso |
| TSL2561 | sensore di luce ambiente (visibile e infrarosso) | 0x29, 0x39, 0x49 | ADDR SEL: GND → 0x29 · Float → 0x39 · VDD → 0x49 |
| VL53L0X | sensore di distanza a tempo di volo (ToF) | 0x29 | |
| VL53L1X | sensore di distanza a tempo di volo (ToF) | 0x29 | |
| MLX90640 | termocamera 32×24 | 0x33 | |
| AXP192 | integrato di gestione dell’alimentazione (PMIC) | 0x34 | indirizzo fisso |
| AXP2101 | integrato di gestione dell’alimentazione (PMIC) | 0x34 | indirizzo fisso |
| MAX17048 / MAX17049 | indicatore di carica per 1 o 2 celle Li-ion | 0x36 | indirizzo fisso |
| AHT20 | sensore di temperatura e umidità | 0x38 | indirizzo fisso |
| PCF8574A | espansore di I/O a 8 bit, indirizzi alternativi | 0x38–0x3F | A2 A1 A0 → 0x38–0x3F |
| VEML6070 | sensore di luce UV | 0x38 | indirizzo fisso |
| APDS-9960 | sensore di gesti, prossimità, luce ambiente e colore | 0x39 | indirizzo fisso |
| SH1106 | controller per display OLED 132×64 | 0x3C, 0x3D | SA0: GND → 0x3C · VDD → 0x3D |
| SSD1306 | controller per display OLED 128×64 / 128×32 | 0x3C, 0x3D | SA0 (D/C#): GND → 0x3C · VDD → 0x3D |
| SSD1309 | controller per display OLED 128×64 | 0x3C, 0x3D | SA0 (D/C#): GND → 0x3C · VDD → 0x3D |
| SX1509 | espansore di I/O a 16 canali con driver LED e gestione tastierino | 0x3E, 0x3F, 0x70, 0x71 | ADDR1 ADDR0: 00 → 0x3E · 01 → 0x3F · 10 → 0x70 · 11 → 0x71 |
| HDC1080 | sensore di temperatura e umidità | 0x40 | indirizzo fisso |
| HTU21D | sensore di temperatura e umidità | 0x40 | indirizzo fisso |
| INA219 | monitor di corrente, tensione e potenza | 0x40–0x4F | A1, A0: GND · VS · SDA · SCL → 0x40–0x4F |
| INA226 | monitor di corrente, tensione e potenza | 0x40–0x4F | A1, A0: GND · VS · SDA · SCL → 0x40–0x4F |
| INA260 | monitor di corrente, tensione e potenza con shunt integrato | 0x40–0x4F | A1, A0: GND · VS · SDA · SCL → 0x40–0x4F |
| INA3221 | monitor di corrente e tensione a 3 canali | 0x40, 0x41, 0x42, 0x43 | A0: GND → 0x40 · VS → 0x41 · SDA → 0x42 · SCL → 0x43 |
| PCA9685 | driver PWM / servo a 16 canali, 12 bit | 0x40–0x77 | A5…A0 → 0x40–0x77 (0x70 = All Call) |
| Si7021 | sensore di temperatura e umidità | 0x40 | indirizzo fisso |
| OPT3001 | sensore di luce ambiente | 0x44, 0x45, 0x46, 0x47 | ADDR: GND → 0x44 · VDD → 0x45 · SDA → 0x46 · SCL → 0x47 |
| SHT30 / SHT31 / SHT35 | sensore di temperatura e umidità | 0x44, 0x45 | ADDR: GND → 0x44 · VDD → 0x45 |
| SHT40 / SHT41 / SHT43 / SHT45 (SHT4x) | sensore di temperatura e umidità | 0x44, 0x45, 0x46 | |
| ADS1015 | ADC a 12 bit e 4 canali | 0x48, 0x49, 0x4A, 0x4B | ADDR: GND → 0x48 · VDD → 0x49 · SDA → 0x4A · SCL → 0x4B |
| ADS1115 | ADC a 16 bit e 4 canali | 0x48, 0x49, 0x4A, 0x4B | ADDR: GND → 0x48 · VDD → 0x49 · SDA → 0x4A · SCL → 0x4B |
| ADS7830 | ADC a 8 bit e 8 canali | 0x48, 0x49, 0x4A, 0x4B | A1 A0 → 0x48–0x4B |
| LM75B | sensore di temperatura digitale / termostato | 0x48–0x4F | A2 A1 A0 → 0x48–0x4F |
| PCF8591 | ADC a 8 bit e 4 canali + 1 DAC | 0x48–0x4F | A2 A1 A0 → 0x48–0x4F |
| TMP102 | sensore di temperatura digitale | 0x48, 0x49, 0x4A, 0x4B | ADD0: GND → 0x48 · V+ → 0x49 · SDA → 0x4A · SCL → 0x4B |
| TMP117 | sensore di temperatura digitale ad alta precisione | 0x48, 0x49, 0x4A, 0x4B | ADD0: GND → 0x48 · V+ → 0x49 · SDA → 0x4A · SCL → 0x4B |
| 24LC256 / 24AA256 / 24FC256 | EEPROM I²C da 256 Kbit | 0x50–0x57 | A2 A1 A0 → 0x50–0x57 |
| AT24C32 | EEPROM I²C da 32 Kbit | 0x50–0x57 | A2 A1 A0 → 0x50–0x57 |
| PCF85063A | orologio in tempo reale (RTC) | 0x51 | indirizzo fisso |
| PCF8563 | orologio in tempo reale (RTC) | 0x51 | indirizzo fisso |
| ENS160 | sensore di qualità dell’aria a ossidi metallici (TVOC/eCO₂/AQI) | 0x52, 0x53 | ADDR: GND → 0x52 · VDD → 0x53 |
| BQ27441-G1 | indicatore di carica per una cella Li-ion | 0x55 | indirizzo fisso |
| MAX30100 | pulsossimetro e sensore di battito | 0x57 | indirizzo fisso |
| MAX30102 | pulsossimetro e sensore di battito | 0x57 | indirizzo fisso |
| SGP30 | sensore di gas VOC ed eCO₂ | 0x58 | indirizzo fisso |
| SGP40 | sensore di gas, indice VOC | 0x59 | indirizzo fisso |
| SGP41 | sensore di gas, indici VOC e NOx | 0x59 | indirizzo fisso |
| CCS811 | sensore di gas eCO₂ / TVOC | 0x5A, 0x5B | ADDR: GND → 0x5A · VDD → 0x5B |
| MLX90614 | termometro a infrarossi senza contatto | 0x5A | |
| MPR121 | controller touch capacitivo a 12 canali | 0x5A, 0x5B, 0x5C, 0x5D | ADDR: GND → 0x5A · VDD → 0x5B · SDA → 0x5C · SCL → 0x5D |
| LPS22HB | sensore di pressione barometrica | 0x5C, 0x5D | SA0: GND → 0x5C · VDD → 0x5D |
| GT911 | controller touch screen capacitivo a 5 punti | 0x5D, 0x14 | |
| MCP4725 | DAC a 12 bit con EEPROM | 0x60–0x67 | A0: GND → 0x60 · VDD → 0x61 (MCP4725A0) |
| MCP4728 | DAC a 12 bit e 4 canali con EEPROM | 0x60–0x67 | |
| SCD30 | modulo CO₂ NDIR, temperatura e umidità | 0x61 | indirizzo fisso |
| SCD40 / SCD41 | sensore di CO₂ fotoacustico, temperatura e umidità | 0x62 | indirizzo fisso |
| BMI270 | IMU a 6 assi | 0x68, 0x69 | SDO: GND → 0x68 · VDDIO → 0x69 |
| DS1307 | orologio in tempo reale (RTC) | 0x68 | indirizzo fisso |
| DS3231 | orologio in tempo reale compensato in temperatura | 0x68 | indirizzo fisso |
| MPU-6050 | accelerometro + giroscopio a 6 assi | 0x68, 0x69 | AD0: GND → 0x68 · VDD → 0x69 |
| MPU-6886 | IMU a 6 assi | 0x68, 0x69 | SA0: GND → 0x68 · VDD → 0x69 |
| MPU-9250 | IMU a 9 assi (accelerometro, giroscopio, magnetometro AK8963) | 0x68, 0x69 | AD0: GND → 0x68 · VDD → 0x69 |
| PCF8523 | orologio in tempo reale (RTC) | 0x68 | indirizzo fisso |
| SEN50 / SEN54 / SEN55 | modulo polveri sottili, VOC/NOx, temperatura e umidità | 0x69 | indirizzo fisso |
| HT16K33 | driver per matrici LED 16×8 con scansione tasti | 0x70–0x77 | A2 A1 A0 → 0x70–0x77 |
| SHTC3 | sensore di temperatura e umidità | 0x70 | indirizzo fisso |
| TCA9548A | multiplexer I²C a 8 canali | 0x70–0x77 | A2 A1 A0 → 0x70–0x77 |
| IP5306 | SoC per power bank (caricatore + boost), versione I²C | 0x75 | indirizzo fisso |
| BME280 | sensore di temperatura, umidità e pressione | 0x76, 0x77 | SDO: GND → 0x76 · VDDIO → 0x77 |
| BME680 | sensore di gas (VOC), temperatura, umidità e pressione | 0x76, 0x77 | SDO: GND → 0x76 · VDDIO → 0x77 |
| BME688 | sensore di gas con IA, temperatura, umidità e pressione | 0x76, 0x77 | SDO: GND → 0x76 · VDDIO → 0x77 |
| BMP280 | sensore di pressione e temperatura | 0x76, 0x77 | SDO: GND → 0x76 · VDDIO → 0x77 |
| BMP388 | sensore di pressione e temperatura | 0x76, 0x77 | SDO: GND → 0x76 · VDDIO → 0x77 |
| MS5611-01BA | sensore di pressione barometrica (altimetro) | 0x76, 0x77 | CSB: VDD → 0x76 · GND → 0x77 |
| BMP180 | sensore di pressione e temperatura | 0x77 | indirizzo fisso |
Domande frequenti
Perché il datasheet dice 0x52 ma lo scanner trova 0x29?
Il datasheet dà l’indirizzo di scrittura a 8 bit, cioè quello a 7 bit spostato a sinistra di un bit. 0x52 ÷ 2 = 0x29. Librerie e scanner usano la forma a 7 bit.
Due sensori uguali possono stare sullo stesso bus?
Sì, se il sensore ha un pin di indirizzo: impostalo diversamente su ciascuno. Se non ce l’ha, usa un multiplexer TCA9548A o un secondo bus I²C.
Il mio LCD I²C è a 0x3F e non a 0x27: perché?
Il modulo monta un PCF8574AT invece di un PCF8574T. La versione A usa 0x38–0x3F invece di 0x20–0x27: con tutti i pin di indirizzo alti diventa 0x3F invece di 0x27.
Servono le pull-up se i moduli le hanno già?
Di solito no: basta una coppia di pull-up per bus. Con molti moduli le loro pull-up si sommano in parallelo e possono diventare troppo forti: il calcolatore qui sopra lo verifica.