Skip to content

How to make a reliable I2C bus

Koepel edited this page Apr 15, 2023 · 36 revisions

How to make a reliable I2C bus (hardware)


These things are important to remember

  • Different voltage levels of devices connected to the I2C bus can not be ignored.
  • The I2C bus needs pullup resistors. The sink current (to make the signal low) should not exceed 3 mA.
  • Keep a SDA wire away from a SCL wire. The I2C bus can not handle crosstalk between SDA and SCL.
  • OLED displays are known for disturbing the I2C bus for others.
  • When adding a motor or relays or many leds to your project, then the ground currents can disturb the I2C bus.

Make it easy for yourself

  1. Use a 3.3V Arduino board.
    Most sensors are 3.3V. Connecting a 3.3V sensor to a 3.3V Arduino board works best. Many things on this page are about problems when using a 5V Arduino board with a 3.3V sensor. You can avoid all those problems with a 3.3V Arduino board.

  2. Use short wires and keep SDA away from SCL.
    On the forum we say sometimes that 50 cm is the maximum length for the I2C bus. However, when SDA and SCL are next to each other in a flat ribbon cable, then 50 cm might already be too much. When SDA is not near the SCL wire, and there are no level shifters, and all the voltage levels match, and the pullup is just right, then the length can be a few meters or more.
    In the document "UM10204" is a paragraph "7.5 Wiring pattern of the bus lines". It shows the best order of the signals. In the 2021 version of that document it is on page 54. It shows that that SDA and SCL should not be next to each other. That means that the Qwiic, Qwiic Micro, Stemma and Gravity I2C bus, the I2C connector on the Arduino MKR boards, the Arduino ESLOV connector and also the UEXT connector are all wrong.

There are many misconceptions about the I2C bus

  1. "The I2C bus is open-drain so voltage levels have no influence".
    The I2C bus is indeed open-drain. However, every processor and sensor has internal ESD protection diodes. A voltage at SDA and SCL that is too high will flow via those ESD diodes to VCC and might lift the voltage of the sensor and damage it.
    A Arduino Uno or Mega or Leonardo needs 3.5V to accept it as a high level for the I2C signals (it is in the datasheets). A 3.3V device can not give that voltage.

  2. "The I2C bus has two wires".
    The I2C bus has three wires: SDA, SCL, GND.
    Without the GND, there is no I2C bus.

  3. "The I2C bus is a bus, so it can go through a cable".
    The I2C bus was designed to be used on the same pcb board. The I2C bus is not meant to go through a cable. If wires or a short cable is used, then keep SDA away from SCL. The I2C bus can not handle crosstalk between SDA and SCL.

  4. "The I2C bus is a bus, so it is ideal to communicate between two Arduino boards or between an Arduino board and a Raspberry Pi".
    The I2C bus can be used to retrieve small packages of data from a sensor. When the I2C bus is used between two Arduino board (or with a Raspberry Pi) then the Arduino has to be set in Target mode. That requires knowledge about writing clean code and how to use minimal code in interrupt routines. It is possible but there are a lot of bad examples. It is easier to use a Serial/UART communication between two Arduino boards. When a Raspberry Pi is used, then the Arduino can be connected to the USB bus and Serial communication over the USB bus can be used.
    When a Arduino is used as a I2C Target, then using libraries that turn off interrupts should be avoided. Those libraries are: DHT libraries, OneWire/DallasTemperature, Neopixel and FastLED libraries, and more.
    A Raspberry Pi is a 3.3V device, if that is connected to a 5V Arduino then the I2C bus has a voltage mismatch. The pins of the Raspberry Pi are also not 5V tolerant.

  5. "My I2C bus works, so my pullup resistors are okay".
    The maximum sink current for the standard I2C bus (100 kHz to 400 kHz) should not exceed 3mA. However, when the sink current is very small then the I2C bus has a higher impedance and electrical noise can more easy disturb the signal. It is best to calculate the sink current. I prefer a value between 1mA and 3mA.

  6. "A level shifter will solve all problems with different voltage levels".
    A level shifter is not ideal. Most of them use mosfets and make use of the internal diode of the mosfet. That makes the signals weaker. When two level shifters are used in the signal path, then it might no longer work.

  7. "A Arduino Uno can sink 40 mA, so the I2C bus is much stronger".
    A Arduino Uno can sink more than the minimal 3mA. Therefor a stronger I2C bus can be created with a low value of the pullup resistor. However, some manufacturers make sensors that can barely sink 3mA. To be compatible with those sensor, it is better to keep the I2C bus according to the I2C standard.

  8. "I read that the I2C bus allows multiple Controllers".
    The I2C standard allows that multiple Controllers can be used. The hardware inside the microcontrollers and processors can detect a bus collision. The Arduino Wire library does use that information from the hardware. However, the consequences go much further and I have not seen a serious multi-Controller bus implementation yet.
    Every advanced Arduino-user stays away from a multi-Controller bus.
    For now, a multi-Controller I2C bus with Arduino boards is a fairy tale.

  9. "The I2C bus is a standard, so the I2C bus of the Arduino Uno and the I2C bus of a MKR board or other processor are all the same standard".
    Not even close. The Arduino Uno and other basic Arduino boards have an extra. They have a filter for incoming signals and a slew rate limiter for outgoing signals and a large sink current. Newer Arduino boards have a processor that just uses digital pins. Sometimes resistors of 100 Ω are put in the signal lines to limit the slew rate.

Calculating the total pullup value

When a number of pullup resistors are used, then they are parallel.
For example when there are three resistors: 4k7, 10k and 22k as pullup resistors.
The notation for them parallel is: 4k7 // 10k // 22k
The calculation for the resulting resistor value is: 1 / ( (1/4700) + (1/10000) + (1/22000) ) = 2971 Ω

The total pullup value is not important, the sink current is important and should not exceed 3 mA. Many simple I2C level shifters use mosfets that connect the high voltage side with the low voltage side. When such a level shifter is used, then a device making a signal low has to sink both sides.

Schematic with level shifter and pullup resistors.

In the example above a number of pullup resistors are shown for the SDA only. The SCL signal has of course the same resistors.
The total sink current is: (5/10000) + (5/22000) + (5/10000) + (3.3/4700) + (3.3/50000) + (3.3/10000) = 2.3 mA.
Every device, either on the high side or the low side, has to sink the whole 2.3 mA to make a signal low.

There are chips for level shifting that amplify the signals in both directions without connecting both sides. Those chips create separate I2C buses, and each I2C bus should have its own pullup resistors and has its own sink current.

Fun fact: The signals of the I2C bus can be improved when a constant pullup current is used instead of pullup resistors. A current mirror with transistors or mosfsets is a simple circuit to make a constant current.

Measuring the total sink current

When an empty sketch is used, with only Wire.begin() in setup(), then the short circuit current from SDA to GND and the short circuit current from SCL to GND can me measured with a multimeter. That is the sink current and should not exceed 3 mA.

#include <Wire.h>

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

void loop()
{
}

A reminder

The first thing that I wrote on top of this page is that it can not be ignored when devices with different voltage levels are connected to the same I2C bus.