Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Arduino & Microcontrollers

Arduino I2C Tutorial: Wire Library, Scanner & Multiple Devices

Arduino I2C Tutorial: Wire Library, Scanner & Multiple Devices

March 11, 2026 /Posted byJayesh Jain / 0

I2C (Inter-Integrated Circuit) is one of the most popular serial communication protocols in the electronics world. With just two wires, you can connect multiple sensors, displays, and other peripherals to your Arduino and communicate with all of them. This tutorial covers everything you need to know about Arduino I2C — from the underlying concept to reading multiple sensors simultaneously.

Table of Contents

  • What Is I2C and How Does It Work?
  • I2C Pins on Arduino Boards
  • Using the Wire Library
  • I2C Address Scanner Sketch
  • Reading I2C Sensors: BMP280 and DHT20 Examples
  • Connecting Multiple I2C Devices
  • Troubleshooting I2C Issues
  • Frequently Asked Questions

What Is I2C and How Does It Work?

I2C was invented by Philips (now NXP) in 1982 as a way for a master device (like an Arduino) to communicate with multiple slave devices (like sensors) using only two signal wires:

  • SDA (Serial Data Line): Carries the actual data bits
  • SCL (Serial Clock Line): Carries the clock signal that synchronizes data transfer

The I2C protocol works like this:

  1. The master sends a START condition (pulls SDA LOW while SCL is HIGH)
  2. The master transmits the 7-bit address of the target slave device plus a Read/Write bit
  3. The addressed slave acknowledges (pulls SDA LOW during the 9th clock pulse)
  4. Data bytes are transferred, with the receiver acknowledging each byte
  5. The master sends a STOP condition to end the transmission

Each device on the I2C bus has a unique 7-bit address (0–127). In practice, addresses 0–7 and 120–127 are reserved, leaving addresses 8–119 for user devices. Some devices have configurable addresses (via pins or internal registers), allowing you to use multiple identical chips on the same bus.

Standard I2C speeds:

  • Standard Mode: 100 kHz (most common for hobbyist use)
  • Fast Mode: 400 kHz
  • Fast Mode Plus: 1 MHz
  • High Speed Mode: 3.4 MHz (rarely used with Arduino)

Both SDA and SCL lines require pull-up resistors (typically 4.7kΩ for 100 kHz or 2.2kΩ for 400 kHz) connected to VCC. Many breakout modules include these resistors on board, but if you connect bare chips you must add them externally.

Recommended: BMP280 Barometric Pressure and Altitude Sensor I2C/SPI Module — a perfect first I2C sensor to learn with. Supports both I2C and SPI, runs at 3.3V, and includes onboard pull-up resistors.

I2C Pins on Arduino Boards

The I2C pins vary by board. Here are the most common ones:

Board SDA Pin SCL Pin Logic Level
Arduino Uno R3 A4 (18) A5 (19) 5V
Arduino Nano A4 A5 5V
Arduino Mega 2560 20 21 5V
Arduino Leonardo 2 3 5V
Arduino Nano 33 IoT A4 A5 3.3V
Arduino Nano RP2040 A4 A5 3.3V

Important voltage note: The Arduino Uno, Nano, and Mega operate at 5V logic. Many modern sensors (BMP280, BME280, DHT20) use 3.3V. Most breakout boards include a level shifter or voltage regulator, but always verify the module’s operating voltage before connecting. Connecting a 3.3V sensor directly to a 5V I2C bus without level shifting can damage the sensor.

Recommended: Arduino Nano 33 IoT with Header — runs at 3.3V natively, making it directly compatible with modern I2C sensors without level shifting. Includes built-in Wi-Fi and Bluetooth for IoT sensor projects.

Using the Wire Library

Arduino’s built-in Wire library handles all the low-level I2C signaling. You never need to manually generate START/STOP conditions or manage acknowledgements. Here are the essential functions:

Initializing I2C

#include <Wire.h>

void setup() {
  Wire.begin();          // Initialize as master (no address argument)
  Wire.setClock(400000); // Optional: set to 400kHz Fast Mode
}

Writing Data to a Device

// Write a value to a register in a slave device
void writeRegister(uint8_t deviceAddr, uint8_t regAddr, uint8_t value) {
  Wire.beginTransmission(deviceAddr);  // Start transmission to device
  Wire.write(regAddr);                 // Send register address
  Wire.write(value);                   // Send value to write
  Wire.endTransmission();              // End transmission, send STOP
}

Reading Data from a Device

// Read a byte from a register in a slave device
uint8_t readRegister(uint8_t deviceAddr, uint8_t regAddr) {
  Wire.beginTransmission(deviceAddr); // Select device
  Wire.write(regAddr);                // Tell device which register to read
  Wire.endTransmission(false);        // Repeated START (false = no STOP)
  
  Wire.requestFrom(deviceAddr, 1);    // Request 1 byte
  if (Wire.available()) {
    return Wire.read();               // Read and return the byte
  }
  return 0;
}

I2C Address Scanner Sketch

Before writing device-specific code, it is essential to know the I2C address of your device. The I2C scanner sketch tries every address from 1 to 126 and reports which ones respond:

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial);  // Wait for Serial on Leonardo/Nano 33
  
  Serial.println("I2C Scanner — scanning...");
  Serial.println();
  
  int deviceCount = 0;
  
  for (byte address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    byte error = Wire.endTransmission();
    
    if (error == 0) {
      Serial.print("Device found at address 0x");
      if (address < 16) Serial.print("0");  // Leading zero
      Serial.println(address, HEX);
      deviceCount++;
    } else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16) Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  
  Serial.println();
  if (deviceCount == 0) {
    Serial.println("No I2C devices found.");
    Serial.println("Check wiring and pull-up resistors.");
  } else {
    Serial.print(deviceCount);
    Serial.println(" device(s) found.");
  }
}

void loop() {
  // Scanner only runs once in setup
}

Upload this sketch, open Serial Monitor at 9600 baud, and you will see the addresses of all connected I2C devices printed in hexadecimal. Common addresses you will encounter:

  • 0x3C or 0x3D: OLED display (SSD1306)
  • 0x76 or 0x77: BMP280 / BME280 pressure sensor
  • 0x38: DHT20 temperature and humidity sensor
  • 0x48: ADS1115 analog-to-digital converter
  • 0x68 or 0x69: MPU-6050 gyroscope/accelerometer

Reading I2C Sensors: BMP280 and DHT20 Examples

Reading the BMP280 Pressure Sensor

The BMP280 measures barometric pressure and temperature. It communicates via I2C at address 0x76 (or 0x77 if the SDO pin is tied to VCC).

Install the Adafruit BMP280 library via the Library Manager, then use this code:

#include <Wire.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp;

void setup() {
  Serial.begin(9600);
  
  if (!bmp.begin(0x76)) {  // Use 0x77 if 0x76 doesn't work
    Serial.println("BMP280 not found! Check wiring.");
    while (1);
  }
  
  // Recommended settings for indoor navigation
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
                  Adafruit_BMP280::SAMPLING_X2,
                  Adafruit_BMP280::SAMPLING_X16,
                  Adafruit_BMP280::FILTER_X16,
                  Adafruit_BMP280::STANDBY_MS_500);
}

void loop() {
  Serial.print("Temperature: ");
  Serial.print(bmp.readTemperature());
  Serial.println(" *C");
  
  Serial.print("Pressure: ");
  Serial.print(bmp.readPressure() / 100.0F);
  Serial.println(" hPa");
  
  Serial.print("Altitude: ");
  Serial.print(bmp.readAltitude(1013.25));  // Standard sea level pressure
  Serial.println(" m");
  
  Serial.println();
  delay(2000);
}

Reading the DHT20 Sensor

Unlike the older DHT11/DHT22 (which use a single-wire protocol), the DHT20 uses I2C at address 0x38. Install the DFRobot DHT20 or Aosong DHT20 library and use:

#include <Wire.h>
#include <AHTxx.h>  // AHT20/DHT20 compatible library

AHTxx dht20(AHTXX_ADDRESS_X38, AHT2x_SENSOR);

void setup() {
  Serial.begin(9600);
  Wire.begin();
  
  if (!dht20.begin()) {
    Serial.println("DHT20 init failed!");
    while (1);
  }
}

void loop() {
  float temperature = dht20.readTemperature();
  float humidity    = dht20.readHumidity();
  
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.println(" *C");
  
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");
  
  delay(2000);
}
Recommended: DHT20 SIP Packaged Temperature and Humidity Sensor — the upgrade from DHT11/DHT22 with I2C interface, better accuracy (±0.3°C, ±2% RH), and no need for a data pin resistor. Ideal for I2C multi-sensor projects.

Connecting Multiple I2C Devices

The real power of I2C is connecting many devices on the same two-wire bus. Since each device has a unique address, the master can talk to each one independently.

Wiring Multiple Devices

Simply connect all SDA pins together and all SCL pins together. Connect the shared SDA and SCL lines to the Arduino’s SDA and SCL pins. Use a single pair of pull-up resistors (4.7kΩ to VCC) — you do NOT need separate pull-ups for each device. Adding too many pull-up resistors lowers the effective resistance and can cause signal integrity issues.

Reading Multiple Sensors in One Sketch

#include <Wire.h>
#include <Adafruit_BMP280.h>
#include <AHTxx.h>

Adafruit_BMP280 bmp;
AHTxx dht20(AHTXX_ADDRESS_X38, AHT2x_SENSOR);

void setup() {
  Serial.begin(9600);
  Wire.begin();
  
  // Initialize BMP280 (address 0x76)
  if (!bmp.begin(0x76)) {
    Serial.println("BMP280 not found!");
  }
  
  // Initialize DHT20 (address 0x38)
  if (!dht20.begin()) {
    Serial.println("DHT20 not found!");
  }
}

void loop() {
  // Read from BMP280
  float pressure    = bmp.readPressure() / 100.0F;
  float bmpTemp     = bmp.readTemperature();
  
  // Read from DHT20
  float temperature = dht20.readTemperature();
  float humidity    = dht20.readHumidity();
  
  Serial.println("--- Sensor Readings ---");
  Serial.print("BMP280 Temp: ");    Serial.print(bmpTemp);    Serial.println(" *C");
  Serial.print("BMP280 Pressure: ");Serial.print(pressure);   Serial.println(" hPa");
  Serial.print("DHT20 Temp: ");     Serial.print(temperature);Serial.println(" *C");
  Serial.print("DHT20 Humidity: "); Serial.print(humidity);   Serial.println(" %");
  Serial.println();
  
  delay(3000);
}

Handling Address Conflicts

If two identical devices have the same fixed address, you have two options:

  1. Use address pins: Many chips have ADDR or SDO pins you can tie HIGH or LOW to select between two available addresses. For example, BMP280 can be 0x76 or 0x77.
  2. Use an I2C multiplexer (TCA9548A): This chip lets you switch between 8 separate I2C buses, each with its own set of devices, allowing many identical chips on one Arduino.
Recommended: GY-BME280-3.3 Precision Altimeter Atmospheric Pressure Sensor Module — the BME280 adds humidity measurement to the BMP280. Use alongside DHT20 on the same I2C bus for a complete weather station.

Troubleshooting I2C Issues

Problem: I2C scanner finds no devices

  • Check SDA and SCL connections — swapping these is a common mistake
  • Ensure pull-up resistors are present (4.7kΩ to VCC)
  • Confirm VCC voltage matches the device’s operating voltage
  • Some devices need a few milliseconds after power-up before responding — add delay(100) before scanning

Problem: Garbage data from sensor

  • Double-check the I2C address — run the scanner sketch to confirm
  • Verify you are using the correct library for your specific sensor variant
  • Check the SCL frequency — some sensors max out at 100 kHz; lower speed with Wire.setClock(100000)

Problem: I2C works, then stops randomly

  • Check for bus lockup — if power is cut mid-transaction, a slave device may hold SDA LOW permanently. Toggle SCL 9 times to release it, or power cycle
  • Insufficient pull-up resistor values for the bus capacitance. With long wires or many devices, try 2.2kΩ instead of 4.7kΩ
  • Loose connections on a breadboard — I2C is sensitive to intermittent contacts

Frequently Asked Questions

How many I2C devices can I connect to one Arduino?

Theoretically, up to 112 devices with unique 7-bit addresses can share one I2C bus. In practice, the limit is set by bus capacitance (maximum 400 pF). Long wires and many devices add capacitance, slowing rise times and causing communication errors. For most hobbyist projects, you can comfortably connect 5–10 modules without issues. Use shorter wires and lower clock speeds for large numbers of devices.

What is the difference between I2C and SPI?

I2C uses 2 wires and supports multiple masters and up to 112 devices on one bus, but is slower (up to 3.4 MHz max, typically 100–400 kHz). SPI uses 4 wires (MOSI, MISO, SCK, and one CS pin per device), supports full-duplex (simultaneous send and receive), and is much faster (up to tens of MHz). SPI is preferred for high-speed data transfer (like TFT displays), while I2C is better for sensor networks where pin count matters.

Why does my 5V Arduino damage 3.3V I2C sensors?

Many modern sensors use 3.3V logic and have I/O pins rated for maximum 3.6V. When a 5V Arduino drives SDA or SCL HIGH at 5V, it exceeds this limit and can permanently damage the sensor. Most breakout modules (like the ones from Adafruit or DFRobot) include onboard level shifters or use I2C-safe open-drain outputs. Check the module’s datasheet, and use a bidirectional I2C level shifter (like the TXB0108 or BSS138-based modules) for bare chips.

Can the Arduino act as an I2C slave?

Yes. The Wire library supports slave mode. Call Wire.begin(address) with a slave address (1–127), then register callbacks with Wire.onReceive() and Wire.onRequest(). This is useful for multi-Arduino projects where a Nano 33 IoT collects sensor data and forwards it over I2C to an Arduino Mega acting as the master controller.

How do I speed up I2C for a faster data rate?

Call Wire.setClock(400000) in setup for 400 kHz Fast Mode. Make sure all devices on your bus support 400 kHz (check their datasheets). Use shorter wires and smaller pull-up resistors (2.2kΩ instead of 4.7kΩ) to support faster signal rise times. For speeds above 400 kHz, you need Fast Mode Plus (1 MHz) capable hardware — not all ATmega Arduinos support this without external hardware.

Build Your I2C Sensor Network Today

I2C is the backbone of modern Arduino sensor projects. With just two pins and the Wire library, you can connect pressure sensors, temperature sensors, OLED displays, gyroscopes, and much more — all at the same time. The I2C scanner sketch should be the first thing you upload whenever you add a new device to your project.

Explore the complete range of Arduino-compatible boards and I2C sensors at Zbotic.in. From the BMP280 and DHT20 to Arduino Nano 33 IoT, we stock everything you need to build your next sensor project in India.

Tags: arduino i2c tutorial, arduino sensors, arduino tutorial, BMP280, dht20, i2c scanner, two wire interface, Wire Library
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Arduino Library Writing: Creat...
blog arduino library writing create your own custom class and functions 594970
blog raspberry pi hat vs phat differences and compatibility 594974
Raspberry Pi HAT vs pHAT: Diff...

Related posts

Svg%3E
Read more

Arduino Batch Programming: Flash Multiple Boards Quickly

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Based Radar System with Ultrasonic Sensor

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Automatic Plant Monitor: Sunlight, Moisture, Temperature

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Lie Detector: GSR Sensor Polygraph Project

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Metal Detector: Build a Treasure Finder

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now