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 Deep Dive: Multiple Sensors on Two Wires

Arduino I2C Deep Dive: Multiple Sensors on Two Wires

March 11, 2026 /Posted byJayesh Jain / 0

One of the most elegant features of modern sensor modules is the ability to stack many of them on just two wires. If you want to run multiple temperature sensors, pressure gauges, and display modules simultaneously without consuming a dozen Arduino pins, the Arduino I2C multiple sensors technique is exactly what you need. I2C (Inter-Integrated Circuit) was designed by Philips in the 1980s precisely for this scenario — a shared bus where dozens of devices communicate through addressing rather than dedicated select lines. This deep dive covers the protocol, addressing, clock stretching, multi-master considerations, and real code for common sensors.

  • I2C Protocol Basics
  • I2C Pins on Arduino Boards
  • Device Addressing and Address Conflicts
  • Pull-up Resistors: The Critical Detail
  • The Wire Library in Depth
  • I2C Bus Scanner: Find All Devices
  • Connecting Multiple Sensors: Real Examples
  • Troubleshooting I2C Problems
  • Frequently Asked Questions

I2C Protocol Basics

I2C (also written I²C or IIC) uses only two bidirectional lines:

  • SDA (Serial Data): Carries data bits between master and slaves.
  • SCL (Serial Clock): Clock line driven by the master.

Both lines are open-drain (open-collector) — devices can only pull lines low; pull-up resistors bring lines high when no device is actively driving them. This architecture means multiple devices share the same lines without short-circuit risk.

A typical I2C transaction looks like this:

  1. START condition: Master pulls SDA low while SCL is high — this is the unique start signal.
  2. Address frame: Master sends 7-bit device address followed by a R/W bit (0 = write, 1 = read).
  3. ACK bit: The addressed slave pulls SDA low to acknowledge.
  4. Data frames: One or more 8-bit data bytes, each followed by an ACK from the receiver.
  5. STOP condition: Master releases SDA high while SCL is high — signals end of transaction.

Standard I2C runs at 100 kHz (Standard Mode) or 400 kHz (Fast Mode). Some devices support 1 MHz (Fast-Mode Plus) or 3.4 MHz (High-Speed), but most Arduino-compatible breakouts operate at 100 or 400 kHz.

I2C Pins on Arduino Boards

Board SDA SCL Notes
Uno / Nano A4 A5 Also on pin headers near USB on newer Uno R3
Mega 2560 D20 D21 Separate I2C header also available
Leonardo D2 D3 A4/A5 are analog-only on Leonardo
Nano 33 IoT A4 A5 3.3V logic only

On Uno Rev3 and later, there are dedicated SDA/SCL pins near the AREF pin (top of the board). These are electrically identical to A4/A5 — don’t connect both simultaneously.

Recommended: Arduino Nano 33 IoT with Header — Built-in WiFi and IMU, 3.3V I2C native — perfect for IoT sensor hub projects where you’re aggregating data from multiple I2C sensors over WiFi.

Device Addressing and Address Conflicts

Standard I2C uses 7-bit addresses, giving 128 possible addresses (16 are reserved, leaving 112 usable). Each device on the bus must have a unique address. Most common sensors have fixed addresses or allow one or two address bits to be configured via solder jumpers or address pins.

Common sensor default addresses:

Sensor Default Address Alt. Addresses
BMP280 0x76 0x77 (SDO high)
BME280 0x76 0x77
DHT20 0x38 Fixed
DS3231 (RTC) 0x68 Fixed
SSD1306 OLED 0x3C 0x3D
PCA9685 (PWM) 0x40 0x41–0x7F (A0-A5)

When you need two identical sensors (e.g., two BMP280 modules measuring pressure at different points), you have options:

  1. Use the alternate address: BMP280 has SDO pin — tie it high on one module, low on the other. Now you have 0x76 and 0x77 — problem solved.
  2. Use an I2C multiplexer: TCA9548A is an 8-channel I2C mux. It connects to your Arduino as a single I2C device (0x70), and you switch which sub-bus is active by writing a register. Each sub-bus can have duplicate addresses.
  3. Bit-bang a second I2C bus: Use a software I2C library on different pins to create a second independent bus. Speed is limited to ~50 kHz but works for slow sensors.

Pull-up Resistors: The Critical Detail

I2C is perhaps the most pull-up-sensitive protocol you’ll encounter. The pull-ups form an RC low-pass filter with the bus capacitance. Too high a value and the rising edges slow down to the point where data is corrupted at 400 kHz. Too low and devices can’t pull the bus down reliably.

General guidance:

  • 100 kHz, short bus (<30cm): 4.7 kΩ to 10 kΩ
  • 400 kHz, short bus: 2.2 kΩ to 4.7 kΩ
  • 400 kHz, longer bus or many devices: 1 kΩ to 2.2 kΩ

Most breakout boards include onboard pull-up resistors (often 4.7 kΩ). When you connect multiple modules, these pull-ups combine in parallel, reducing the effective resistance. With 4 modules each having 4.7 kΩ, the effective pull-up is ~1.175 kΩ — which is actually fine for 400 kHz. But with 10 modules the resistance drops to ~470 Ω, which can exceed the drive strength of slave devices trying to pull SDA low, causing ACK failures. In that case, remove the pull-up resistors from all but one module, or use a single external pull-up with an I2C bus driver.

Also: if mixing 5V Arduino with 3.3V sensors, use 3.3V pull-ups (to 3.3V, not 5V). Never pull I2C lines to 5V when 3.3V-only devices are on the bus — it will damage them.

Recommended: BMP280 Barometric Pressure and Altitude Sensor I2C/SPI Module — Supports both I2C and SPI, with configurable I2C address (0x76/0x77), making it one of the most flexible sensors to integrate in a multi-sensor I2C build.

The Wire Library in Depth

Arduino’s Wire.h library wraps the TWI (Two Wire Interface) hardware peripheral. Here’s a complete reference for multi-sensor operation:

#include <Wire.h>

void setup() {
  Wire.begin();           // Join bus as master
  Wire.setClock(400000);  // Set 400 kHz Fast Mode
  Serial.begin(9600);
}

// Write a byte to a device register
void i2cWrite(uint8_t addr, uint8_t reg, uint8_t value) {
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.write(value);
  uint8_t err = Wire.endTransmission();
  if (err != 0) {
    Serial.print("I2C write error: ");
    Serial.println(err);
  }
}

// Read bytes from a device register
void i2cRead(uint8_t addr, uint8_t reg, uint8_t* buf, uint8_t len) {
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.endTransmission(false); // false = repeated START (no STOP)
  Wire.requestFrom(addr, len);
  for (uint8_t i = 0; i < len; i++) {
    buf[i] = Wire.available() ? Wire.read() : 0;
  }
}

The Wire.endTransmission(false) call is critical when reading from devices that require a register pointer write followed immediately by a read without a STOP in between. Sending a STOP between the write and read (the default behaviour) causes many sensors to reset their internal read pointer, returning wrong data.

Wire.endTransmission() returns an error code: 0 = success, 1 = buffer overflow, 2 = NACK on address, 3 = NACK on data, 4 = other error. Always check this in production code.

I2C Bus Scanner: Find All Devices

Before writing sensor-specific code, always scan your bus to confirm which addresses are responding. Here’s a complete scanner:

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial); // Wait for Serial on native USB boards

  Serial.println("I2C Scanner");
  Serial.println("Scanning...");

  uint8_t count = 0;
  for (uint8_t addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    uint8_t err = Wire.endTransmission();
    if (err == 0) {
      Serial.print("Device found at 0x");
      if (addr < 16) Serial.print("0");
      Serial.println(addr, HEX);
      count++;
    } else if (err == 4) {
      Serial.print("Unknown error at 0x");
      if (addr < 16) Serial.print("0");
      Serial.println(addr, HEX);
    }
  }
  Serial.print(count);
  Serial.println(" device(s) found.");
}

void loop() {}

Run this whenever you add a new device to verify the address before writing driver code. If a device doesn’t appear in the scan, the issue is almost always wiring (SDA/SCL swapped, missing pull-ups, or wrong voltage level) rather than software.

Connecting Multiple Sensors: Real Examples

Let’s build a practical multi-sensor weather station reading temperature/humidity from a DHT20 (I2C, 0x38) and pressure/altitude from a BMP280 (I2C, 0x76) on the same bus.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <AHTxx.h> // DHT20 uses AHT20 protocol

Adafruit_BMP280 bmp;
AHTxx aht(AHTXX_ADDRESS_X38, AHT2x_SENSOR);

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.setClock(400000);

  if (!bmp.begin(0x76)) {
    Serial.println("BMP280 not found!");
    while (1);
  }
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
                  Adafruit_BMP280::SAMPLING_X2,
                  Adafruit_BMP280::SAMPLING_X16,
                  Adafruit_BMP280::FILTER_X16,
                  Adafruit_BMP280::STANDBY_MS_500);

  if (aht.begin() != true) {
    Serial.println("DHT20 not found!");
    while (1);
  }
}

void loop() {
  float temp_bmp  = bmp.readTemperature();
  float pressure  = bmp.readPressure() / 100.0F; // hPa
  float altitude  = bmp.readAltitude(1013.25);

  float temp_dht  = aht.readTemperature();
  float humidity  = aht.readHumidity();

  Serial.print("BMP280 Temp: "); Serial.print(temp_bmp); Serial.println(" C");
  Serial.print("Pressure: ");    Serial.print(pressure);  Serial.println(" hPa");
  Serial.print("Altitude: ");    Serial.print(altitude);  Serial.println(" m");
  Serial.print("DHT20 Temp: ");  Serial.print(temp_dht);  Serial.println(" C");
  Serial.print("Humidity: ");    Serial.print(humidity);  Serial.println(" %");
  Serial.println("---");

  delay(2000);
}

Both sensors sit on the same SDA/SCL lines with a single pair of 4.7 kΩ pull-ups to 3.3V. The Wire library handles arbitration — you simply call each sensor’s library in sequence and both respond to their own addresses.

Recommended: DHT20 SIP Packaged Temperature and Humidity Sensor — Unlike the DHT11/DHT22 (single-wire protocol), the DHT20 uses I2C at 0x38 — so it pairs cleanly on the same bus as BMP280 and other I2C modules for multi-sensor builds.
Recommended: GY-BME280-3.3 Precision Altimeter Atmospheric Pressure Sensor Module — The BME280 adds humidity measurement to BMP280 capabilities in the same I2C address space, making it a three-in-one sensor for compact weather station projects.

Troubleshooting I2C Problems

Device not found in scan

  • Check SDA and SCL are not swapped
  • Verify power (3.3V vs 5V) matches the module
  • Confirm pull-up resistors are present (test with 4.7 kΩ from SDA to VCC and SCL to VCC)
  • Some modules need an initial delay after power-on before responding

Intermittent data errors

  • Bus capacitance too high — remove duplicate pull-ups from modules, use lower resistance external pull-ups
  • Wire length over 1 metre — reduce clock to 100 kHz and add stronger pull-ups
  • Voltage mismatch — 5V pull-ups on 3.3V devices

Bus lockup (Wire.endTransmission never returns)

  • SDA stuck low — a device crashed mid-transaction. Power cycle all devices.
  • Add a clock recovery function: manually toggle SCL 9 times to release the bus
  • The Wire library on older Arduino cores has a known timeout bug — update to the latest Arduino core

Frequently Asked Questions

How many I2C devices can I connect to one Arduino?

Up to 112 devices at unique 7-bit addresses (128 minus 16 reserved). In practice, bus capacitance is the real limit — standard I2C specifies a maximum of 400 pF bus capacitance. Each device and each centimetre of wire adds capacitance. With typical module wiring you can reliably connect 10–20 devices; beyond that you need I2C bus extenders or repeaters.

Can I use I2C and SPI at the same time?

Yes, they use separate hardware peripherals on all AVR-based Arduino boards. I2C uses TWI (A4/A5 on Uno) and SPI uses the SPI peripheral (D11/D12/D13). They operate completely independently and can run simultaneously in interrupt-driven code.

What happens if two I2C devices have the same address?

Both devices will respond to the same address frame simultaneously, causing a bus collision. The data becomes corrupted and both responses conflict. The master cannot distinguish between them. Solutions: use alternate address configuration, an I2C multiplexer (TCA9548A), or a software I2C bus on different pins.

How do I speed up I2C reads?

Call Wire.setClock(400000) for 400 kHz Fast Mode. Verify your devices support Fast Mode (most modern modules do). Also use Wire.endTransmission(false) with repeated START instead of STOP between write and read — this eliminates bus turnaround time. For very fast requirements, consider SPI alternatives of the same sensor.

Why does my I2C work on a breadboard but fail on long jumper wires?

Longer wires add capacitance and resistance. Each 30 cm of wire adds roughly 50–100 pF to the bus. Reduce clock speed to 100 kHz and/or strengthen pull-ups (lower resistance) for longer runs. For distances over 50 cm, add a P82B96 I2C bus extender to maintain signal integrity.

Ready to build your multi-sensor I2C system? Shop our collection of Arduino boards and sensor modules at Zbotic — we stock the Nano 33 IoT, BMP280, DHT20, BME280 and dozens more I2C-compatible components shipped across India.

Tags: arduino i2c, bmp280 arduino, dht20, i2c sensors, multiple sensors arduino, Wire Library
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Arduino Rotary Encoder: Menu N...
blog arduino rotary encoder menu navigation and position sensing 594723
blog arduino fast analog read increase adc speed 10x 594725
Arduino Fast Analog Read: Incr...

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