Table of contents
Introduction What is I2C How the I2C bus Works Address and Device Identification Start and Stop Conditions Acknowledge Bits Why I2C is so popular Common I2C Bus Speeds Pull Up Resistors in I2C Circuits Using I2C on Arduino and ESP32 Popular I2C components in maker projects Troubleshooting I2C ProblemsTable of contents
Introduction
The I2C is one of the most widely used communication protocols in modern embedded electronics. It appears in everything from small sensors breakout boards to consumer devices, industrial systems and more. Because it uses only two wires and supports multiple devices on the same bus, I2C has become the default choice for microcontrollers such as Arduino, ESP32, STM32, Raspberry Pi and many others.

Whether you are building a smart home device, and enviromental monitoring station or a roborics project, understanding how the I2C works will help you design cleaner and more reliable circuits.
What is I2C
I2C stands for Inter Integrated Circuit. Is is a syncronous serial communication protocol that allows digital devices to exchange data using two shared lines:
- SDA: Serial Data
- SCL: Serial Clock

All devices on the I2C bus are connected paralel to it, meaning that they share these two wires. Each device has its own address, which allows a single microcontroller to communicate with many sensors and modules at once. This makes the I2C ideal for low powered, projects where data transmition speeds are not as important, such as: sensor hubs, compact boards, wearables and more.
How the I2C bus Works
The I2C bus supports multiple masters and multiple slaves, altrough in most projects there is only one master. The master generates clock signal and initiates communication. Slaves respond only when they are addressed.

Address and Device Identification
Most I2C devices use a 7-bit address. Some advanced components use 10-bit addressing, but these are less common. The address identifies the device on the shared bus. When the master wants to read or write data, it sends the address along with a bit that indicates whether the operation is a read or write.
Important: If two connected devices share the same address they cannot operate reliably on the same bus unless one address can be changed using jumpers or configuration pins.
Start and Stop Conditions
Every communication frame begins with a start condition. This event signals every device on the bus that a new transaction is beginning. After the address and data bytes are exchanged, the master sends a stop condition to release the bus.

Acknowledge Bits
After each transmitted byte, the receiving device send an acknowledgment bit, This lets the master know if the data was received correctly. If no acknowledgment bit is returned, the master can retry or stop the communication.

Why I2C is so popular
There are several reasons as to why makers rely on using I2C:
- Communication is realized using only two wires regardless of device count
- Low power consumption
- Universally supported across microcontroller platforms
- Ideal for sensors, configuration registers and display control
Common I2C Bus Speeds
I2C supports several communication modes:
- Standard mode, bus speed up to 100 kHz
- Fast mode, bus speed up to 400 kHz
- Fast mode plus, bus speed up to 1 MHz
- High speed mode, bus speed up to 3.4 MHz
In hobby electronics, 100kHz and 400kHz are most common. Many Arduino boards default to 100 kHz, while ESP32 and more modern microcontrollers can run at 400 kHz or higher, depending on the connected hardware.
Pull Up Resistors in I2C Circuits
SDA and SCL lines must have pull up resistors. Without them, the bus cannot operate correctly. When a device sends a logic low state, it actively pulls the line down. When the line needs to go high, the pull up resistor returns it to the logic high level.
Typical resistor values range from 2.2 kOhm to 10 kOhm. Many sensor breakout boards include pull ups on the PCB. When several modules are connected, the total resistance can become to low, which leads to communication errors. In those cases, extra pull ups should be removed or disabled.
Using I2C on Arduino and ESP32
Arduino boards include Wire library, which simplifies communication with I2C devices. The library provides functions for scanning the bus, reading values and sending configuration commands. Most Arduino boards use dedicated pins for SDA and SCL.
ESP32 boards offer additional flexibility because they support two independent I2C buses and allow the pins to reassigned. This makes it easier to design complex systems with many peripherals.
Popular I2C components in maker projects
BME680 enviromental sensor [link to product]
LSM6DSO accelerometer & gyroscope sensor [link to product]
PCF85063A Real time clock [link to product]
ADS1115 16-bit 4-channel ADC [link to product]
SSD1306 OLED Display [link to product]
Troubleshooting I2C Problems
Even though I2C is considered simple, a few issues can appear frequently.
Incorrect addresses
Different manufacturers sometimes use different default addresses for the same type of sensor. If a device is not responding, use an I2C scanner to detect its real address.
Missing or excessive pull ups
If the bus behaves unpredictably or devices do not acknowledge commands, check the pull up resistors. Multiple modules with built in resistors can lower the combined resistance too much.
Cable lenght
I2C is intended for short distances. Long cables add capacitance, which degrades the signal. Keeping wires short or lowering the communication speed can fix this problem.
Address conflicts
It two modules share the same address and it cannot be changed, the devices cannot be used on the same bus. Many of the soldered breakout boards offer solder jumpers for address selection.