How to use I2C on Arduino
What is I2C?
I2C (said "I squared C", short for Inter-Integrated Circuit) is a way for chips to talk to each other over just two wires. Philips developed it in the early 1980s, and NXP, its successor, still publishes the official specification. Sensors, small screens, clocks and memory chips use it, and many devices can share the same two wires. New to the boards themselves? Start with our guide to what Arduino is.
- SDA (serial data) carries the bits.
- SCL (serial clock) carries the timing pulses, so both ends know when to read each bit.
- A shared ground gives both ends the same 0 V reference.
One device, the controller (your Arduino), starts every conversation. The others, called targets, answer only when called by their address. Older guides call these master and slave. Standard-mode runs at 100 kbit/s and Fast-mode at 400 kbit/s, with faster modes for chips that support them.
Arduino I2C pins
| Board | SDA | SCL |
|---|---|---|
| Uno R3 and Uno R4 | A4 (also the pin marked SDA near AREF) | A5 (also the pin marked SCL) |
| Nano (classic) | A4 | A5 |
| Mega 2560 | 20 | 21 |
| Leonardo | 2 | 3 |
| ESP32 DevKit (Arduino core default) | 21 | 22 |
On an Uno, the SDA and SCL pins near the USB socket are connected to A4 and A5, so use either pair, not both for different things. Once you use I2C, A4 and A5 can't be used as analog inputs. On an ESP32 you can move I2C to other pins with Wire.begin(sda, scl).
How to wire an I2C device
- Power: connect the module's VCC (or VIN) to 5 V or 3.3 V, whichever it is rated for.
- Ground: connect GND to the Arduino's GND.
- Data: connect SDA to SDA (A4 on an Uno).
- Clock: connect SCL to SCL (A5 on an Uno).
- More devices: connect every device's SDA to the same SDA line and every SCL to the same SCL line. Each device needs a different address.
Pull-up resistors
Devices on an I2C bus never drive the lines high. They can only pull them low, and resistors, called pull-ups, pull the lines back up to the supply voltage. Without pull-ups, the lines float and nothing works reliably. Most breakout boards already have pull-ups fitted, often 4.7 kΩ or 10 kΩ. For a bare chip, add one resistor from SDA to the supply and one from SCL to the supply, with 4.7 kΩ a common choice at 100 kHz. With several modules on one bus, the pull-ups add in parallel and the total resistance can get too low, so you may need to remove some.
5 V and 3.3 V
An Uno uses 5 V logic. Many sensors use 3.3 V and can be damaged by 5 V on their pins. Use modules with a built-in regulator and level shifter, or put a small I2C level shifter between them. On a 3.3 V board like the ESP32, the reverse applies: keep the pull-ups to 3.3 V.
Step 1: find the address with an I2C scanner
Every I2C device has a 7-bit address, usually written in hexadecimal like 0x3C. The datasheet gives it, but modules often allow two choices, so the quickest check is a scanner sketch. It calls each possible address and reports the ones that answer.
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("Scanning...");
for (byte address = 1; address < 127; address++) {
Wire.beginTransmission(address);
if (Wire.endTransmission() == 0) { // 0 means a device answered
Serial.print("Found device at 0x");
Serial.println(address, HEX);
}
}
Serial.println("Done");
}
void loop() {}Open the serial monitor at 9600 baud to see the results. If nothing is found, check the wiring, the power and the pull-ups before anything else.
| Common module | Typical address |
|---|---|
| SSD1306 OLED display | 0x3C or 0x3D |
| BME280 temperature and pressure sensor | 0x76 or 0x77 |
| DS3231 real-time clock | 0x68 |
| MPU-6050 accelerometer and gyro | 0x68 or 0x69 |
| PCF8574 backpack for character LCDs | Often 0x27 or 0x3F |
Two devices with the same address can't share a bus unless one can be switched to its other address, usually with a jumper or an address pin. Otherwise, use an I2C multiplexer or a second bus.
Step 2: write to and read from a device
Most I2C sensors work like a small set of numbered boxes, called registers. To read one, you write the register number, then ask for bytes back. This sketch reads the MPU-6050's identity register, 0x75, which the register map says should hold 0x68. It is a quick way to prove the wiring works.
#include <Wire.h>
const byte MPU_ADDR = 0x68;
void setup() {
Wire.begin();
Serial.begin(9600);
Wire.beginTransmission(MPU_ADDR); // start talking to the device
Wire.write(0x75); // the register we want
Wire.endTransmission(false); // keep the bus for the read
Wire.requestFrom(MPU_ADDR, (byte)1); // ask for 1 byte
if (Wire.available()) {
byte id = Wire.read();
Serial.print("WHO_AM_I = 0x");
Serial.println(id, HEX); // expect 68
}
}
void loop() {}Wire.beginTransmission(addr)starts a message to one device.Wire.write(value)queues a byte to send, such as a register number or a setting.Wire.endTransmission()sends it and returns 0 if the device acknowledged. Passingfalseholds the bus so a read can follow straight away.Wire.requestFrom(addr, n)asks the device for n bytes, andWire.read()takes them one at a time.
For real projects, use the device's library from the Arduino IDE's library manager, such as one for the BME280 or the SSD1306. Libraries do the register work for you, but they all use Wire underneath, so this sketch is what they do inside.
Try wiring a module to the right pins, then press Mark to check it in our Micro Controllers course, which also compares I2C with UART and SPI.
Match each module pin to the board pin it wires to: I2C, UART and SPI modules (MatchPairs).
Press Mark to have your answer marked in the Micro Controllers course.
Worked examples
Example 1: 7-bit and 8-bit addresses
A datasheet lists a device's address as 0xD0 for writing and 0xD1 for reading, but the scanner says 0x68. Which is right? Both. On the wire, the 7-bit address is followed by one bit that says read (1) or write (0). Shifting 0x68 left one place gives 0xD0, and adding the read bit gives 0xD1. The Wire library wants the 7-bit form, 0x68, and adds the last bit itself.
Example 2: how fast is I2C?
Each byte takes 9 clock pulses: 8 for the data and 1 for the acknowledge bit. At 100 kHz, that is 9 ÷ 100,000 = 90 microseconds per byte, so at most about 11,100 bytes a second, before counting start, stop and address bytes. Switching to Fast-mode with Wire.setClock(400000), if every device on the bus supports it, raises that to about 44,400 bytes a second. Plenty for sensors, but slow for a large screen, which is why big displays often use SPI instead.
I2C vs SPI vs UART
| I2C | SPI | UART (serial) | |
|---|---|---|---|
| Wires | 2 (SDA, SCL) plus ground | 4 (MOSI, MISO, SCK, plus one select line per device) | 2 (TX, RX) plus ground |
| Devices | Many, picked by address | Many, picked by select lines | Usually two |
| Speed | 100 or 400 kbit/s typical | Several Mbit/s | Up to about 115,200 bits/s typical |
| Good for | Sensors, small displays, clocks | Fast displays, SD cards | GPS modules, talking to a computer |
Troubleshooting I2C
- Scanner finds nothing: check SDA and SCL aren't swapped, the module is powered, the grounds are joined and pull-ups are present.
- Scanner finds every address: usually SDA or SCL shorted to ground, or a missing pull-up.
- Works, then freezes: long wires, too many devices or weak pull-ups. Keep wires short, and try 4.7 kΩ pull-ups or a lower clock speed.
- Wrong values: check the address and register numbers against the datasheet, and whether the device needs waking up first. The MPU-6050, for example, starts in sleep mode.
Common mistakes
- Swapping SDA and SCL. Check the labels on both boards.
- Forgetting the common ground. Without it, the signals have no shared reference.
- Putting 5 V logic on a 3.3 V sensor. Use a level shifter or a module that handles it.
- Using the 8-bit address in Wire. Wire expects the 7-bit address, such as 0x68, not 0xD0.
- Using A4 and A5 as analog inputs as well. On an Uno they are the I2C pins.
Common questions
Which pins are I2C on an Arduino Uno?
Do I need pull-up resistors for I2C on Arduino?
How many devices can I connect to one I2C bus?
How do I find the I2C address of my device?
What does Wire.endTransmission() return?
Can I use I2C on an ESP32 with the Arduino IDE?
Revision cards
Say the answer first, then flip the card to check it.
Where to go next
- Learn it
Micro Controllers
Arduino, ESP32 and programming hardware at the lowest level
Start the course