Home

Guide no. 22

Two wires to connect dozens of sensors and displays: how it works, which resistors you need, what to do when two modules have the same address and how to find the ones connected.

By Ada Intelisano · informaticait.it technical team

Download the PDF (A4, 4 pages) Free to print and share, without changes — CC BY-ND 4.0
In short
  • Two lines, SDA (data) and SCL (clock), shared by all the devices. The controller (the board) calls, the targets answer.
  • Each target has a 7-bit address: two devices with the same address cannot share the same bus.
  • The outputs can only pull LOW: you need pull-up resistors to VDD. For the ESP32 Espressif recommends 2 to 5 kΩ.
  • The scanner tries every address and prints the ones that answer: it is the first thing to do when a sensor stays silent.

How it works

One bus, two wires, many devicesVDDRpRpSDASCLESP32controllerDS32310x68ADS11150x48BME2800x76Outputs can only pull LOW:the two Rp provide the HIGHinformaticait.it

The outputs of I²C devices are open-drain: they can connect the line to ground, never to VDD. When the bus is idle the two Rp hold SDA and SCL HIGH; whoever needs to transmit pulls them LOW. This way nobody ever ends up in a short circuit, even if two devices talk at once. The NXP specification calls the device that generates the clock the controller and the one being called the target (once known as master and slave).

The controller calls the DS3231 and it answersSDASCL110100000address 0x68 (7 bits)R/WACKSTARTSTOPinformaticait.it

Every exchange begins with a START (SDA falls while SCL is high). Then come the 7 address bits, one bit saying whether the controller wants to write (0) or read (1), and the ninth clock pulse, during which the called target holds SDA LOW: that is the ACK, “I'm here”. If nobody answers, the line stays high (NACK). It ends with a STOP.

The pins on the boards

SDASCLNotes
Arduino UNOA4A5also on the two pins next to AREF; Wire.begin()
ESP32-DevKitCGPIO 21GPIO 22other pins with Wire.begin(sda, scl)

The pull-up resistors

The right value lies between two limits, both in the NXP specification. The minimum is set by the current an output must be able to sink (3 mA): Rmin = (VDD − 0.4 V) ÷ 3 mA, that is about 1 kΩ at 3.3 V and 1.5 kΩ at 5 V. The maximum is set by the capacitance of the wires and devices: the higher it is, the slower the rising edge. Rmax = tr ÷ (0.8473 × Cb).

Bus capacitance50 pF100 pF200 pF400 pF
Standard, 100 kHz (tr 1000 ns)23.6 kΩ11.8 kΩ5.9 kΩ2.95 kΩ
Fast, 400 kHz (tr 300 ns)7.1 kΩ3.5 kΩ1.8 kΩ885 Ω

Rmax calculated by us with the formula from NXP UM10204. Each pin adds up to 10 pF, and the wires add more.

What about the internal pull-ups? The Wire library turns them on by itself, both on the UNO (20 to 50 kΩ) and on the ESP32 (about 45 kΩ). They are too weak: with 20 kΩ at 100 kHz the bus can handle about 59 pF, and every connected pin brings up to 10. Espressif writes that external resistors are needed. Many modules already have them fitted: if you connect a lot of them, their pull-ups add up in parallel and the value drops. SparkFun gives about seven devices before you need to remove some.

Addresses of the most common modules

DeviceAddressHow to change it
ADS1115 (A/D converter)0x48–0x4BADDR pin to GND, VDD, SDA or SCL
BME280 (pressure, temperature, humidity)0x76 / 0x77SDO pin to GND or to VDDIO
SSD1306 (OLED display)0x3C / 0x3DSA0 pin (D/C#)
DS3231 (clock)0x68fixed
AHT20 (temperature, humidity)0x38the datasheet gives no alternatives
SHT4x (temperature, humidity)0x44 / 0x45 / 0x46depends on the version you buy (A, B or C)

If two identical modules have a fixed address, you use a multiplexer such as the TCA9548A: eight separate channels, and the controller opens the one it needs. The TCA9548A itself has an address from 0x70 to 0x77.

Long cables and connectors

I²C was designed to stay on one board. The specification does not set a length: the limit is the capacitance, 400 pF in Standard and Fast mode. NXP talks about “a few meters”. If you need longer distances: lower the speed, use lower pull-ups, or an extender such as the P82B715 (about 50 m) or a differential buffer such as the PCA9615, which SparkFun uses with Ethernet cables. For long wires NXP recommends not running SDA and SCL side by side: SDA, VDD, GND, SCL is better.
Qwiic and STEMMA QT are the same 4-pin JST SH connector with the same colors: black GND, red V+, blue SDA, yellow SCL. Qwiic is 3.3 V only, STEMMA QT accepts 3 to 5 V.

Wiring: ESP32 with two modules

ESP32 with two modules on one bus−+DS3231DS3231VinGNDSCLSDABAT32KSQWRSTPrecision I2C RTConADS111516-bit ADCVINGNDSCLSDAADDRALRTA+A3A2A1A0A−ESP32-WROOM-323V3GNDEN23VP22VNTX34RX352132GND3319251826527171416124GND0132D215D3D1CMDD05VCLKDS3231 (Adafruit 3013)ADS1115 (Adafruit 1085)3V3 → + railGND → − railSCL → GPIO 22SDA → GPIO 21ADDR to GNDinformaticait.it

The DS3231 and the ADS1115 are plugged into the same breadboard and connected with four wires: power, ground, SCL and SDA. The ADS1115's ADDR pin goes to ground to get address 0x48. The scanner will find 0x48 and 0x68.

The scanner

// I2C scanner: tries every address from 0x08 to 0x77 and prints the ones that respond.
// Same sketch for Arduino UNO (SDA = A4, SCL = A5) and ESP32 (SDA = GPIO 21, SCL = GPIO 22).
#include <Arduino.h>
#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin();
}

void loop() {
  int found = 0;
  Serial.println("Scanning the I2C bus...");
  for (uint8_t address = 0x08; address <= 0x77; address++) {
    Wire.beginTransmission(address);
    uint8_t result = Wire.endTransmission();   // 0 = someone answered with ACK
    if (result == 0) {
      Serial.print("  device at address 0x");
      if (address < 16) Serial.print('0');
      Serial.println(address, HEX);
      found++;
    } else if (result == 4) {
      Serial.print("  unknown error at 0x");
      Serial.println(address, HEX);
    }
  }
  if (found == 0) Serial.println("No devices: check wires, power supply and pull-ups");
  Serial.println();
  delay(5000);
}

The scan starts at 0x08 and stops at 0x77: addresses 0x00 to 0x07 and 0x78 to 0x7F are reserved by the specification. endTransmission() returns 0 if the device answered, 2 if the address got no answer (NACK), 4 for other errors, 5 for a timeout.

Common mistakes

What happensWhyFix
The scanner finds nothingSDA and SCL swapped, ground or power missingcheck the four wires, then the pull-ups
It finds the module at a different address than expectedjumper or address pin in another positionuse the address found in the sketch
Two identical modules, only one answerssame addresschange the address if you can, otherwise TCA9548A
Works on the bench, hangs with long wirestoo much capacitance: the rising edge is slowlower pull-ups, lower speed, extender
The sketch hangs on a readingbus stuck because of a deviceWire.setWireTimeout() on the UNO, then find the cause
5 V module on an ESP32the module's pull-ups go to 5 Vpower it at 3.3 V if it allows that, or use a level shifter
Sources: NXP, UM10204 “I2C-bus specification and user manual” (Rev. 7.0, 2021); P82B715 and PCA9615 datasheets · Texas Instruments, SLVA689A “I2C Bus Pullup Resistor Calculation”, SLVA704 “Understanding the I2C Bus”, TCA9548A and ADS1115 datasheets · Microchip, ATmega328P datasheet (DS40002061B); Espressif, ESP32 Series Datasheet v5.3 and ESP-IDF and Arduino-ESP32 documentation (I2C) · Arduino, Wire library documentation and twi.c source; Arduino Playground, I2C scanner · Datasheets: Bosch BME280, Solomon Systech SSD1306, Maxim DS3231, Aosong AHT20, Sensirion SHT4x · Adafruit, “Introducing Adafruit STEMMA QT”; SparkFun, Qwiic page, “I2C” tutorial and QwiicBus guide

Useful products

Other guides

All our guides →
Loading...
Back to top