I2C, Two Wires and Many Devices

Draft. This tutorial has not been checked against the physical product yet. Confirm wiring, pin assignments and voltage limits against the product documentation before building it.
DifficultyIntermediate
CategoryConcepts
Supported boardsArduino Uno R3 and compatible ATmega328P boards
Time needed40 minutes
PrerequisitesMaking a Button Behave
Tested boardNot yet verified
Tested onNot yet verified
Arduino IDE versionNot yet verified
LibraryNot yet verified

What this covers

An Uno has fourteen digital pins. A character display can want six of them, and that is before you add a clock, a sensor and a display driver.

I2C solves that. One pair of wires carries as many devices as you like, each answering to its own address. This explains how to wire it, how to find out what is on the bus, and the four things that go wrong.

Most of the modules Siratek sells that do anything complicated use it: the LCD backpack, the OLED display, the real-time clock, the pressure sensor, the accelerometer.

Before you begin

Any I2C module and an Uno. The scanner sketch below works with whatever you have and is worth running before any device-specific tutorial.

How it works

Two wires, plus a shared ground.

  • SDA, the data line.
  • SCL, the clock line, which the Arduino drives to pace the conversation.

The Arduino is the controller. It starts every exchange by putting an address on the bus. Every device hears it; the one whose address matches answers, and the rest stay quiet.

Addresses are seven bits, so 0x00 to 0x7F, and in practice 0x08 to 0x77. The address is set by the manufacturer, sometimes with solder pads or jumpers to change a bit or two so you can run several identical devices together.

On an Uno

Signal Uno pin Notes
SDA A4 Also available on the dedicated SDA pin near AREF
SCL A5 Also available on the dedicated SCL pin
GND GND Required. Both ends need the same reference
VCC 5V or 3.3V Whatever the module wants, not whatever is nearest

A4 and A5 are the same physical pins as the ones beside AREF, not extra ones. Using I2C costs you those two analog inputs.

Devices share the wires

Every device connects to the same SDA and the same SCL. You do not need a pin per device, and you do not need a hub. Wire the second module to the same two lines as the first.

Two modules sharing one SDA line, one SCL line and a common ground, each with its own address
A third module joins the same two wires and costs no extra pins.

Pull-up resistors

Both lines need pull-up resistors to work. Almost every breakout module Siratek sells has them fitted, so for one or two modules you do nothing.

The catch arrives with several modules at once. Each one adds its own pull-ups in parallel, and the combined pull-up gets stronger until the bus stops working reliably. Four or five modules on one bus is where this starts to show, as intermittent failures that look like bad wiring.

The fix is to remove or cut the pull-ups on all but one module. Most boards mark them.

Finding what is on the bus

This is the first thing to run with any new I2C device. It answers “is it wired correctly and what address is it at” in one step, before any library is involved.

// Siratek: list every device answering on the I2C bus.

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial) {
    ;   // Wait for the Serial Monitor on boards that need it.
  }
  Serial.println("Siratek: scanning the I2C bus.");
}

void loop() {
  int found = 0;

  for (byte address = 8; address < 120; address++) {
    Wire.beginTransmission(address);

    // 0 means the device acknowledged its address.
    if (Wire.endTransmission() == 0) {
      found++;
      Serial.print("device at 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.println(address, HEX);
    }
  }

  if (found == 0) {
    Serial.println("nothing found: check SDA, SCL, power and ground");
  } else {
    Serial.print("devices found: ");
    Serial.println(found);
  }

  Serial.println();
  delay(5000);
}

Wire is part of the Arduino core, so there is nothing to install.

Expected result

With one module wired, you should see a single address, repeating every five seconds:

Siratek: scanning the I2C bus.
device at 0x27
devices found: 1

0x27 and 0x3F are the usual addresses for the LCD backpack, 0x3C for a small OLED, 0x68 for a real-time clock or accelerometer. Yours may differ, which is exactly why you scan rather than assume.

An address appearing here means the wiring and power are right. If a device-specific sketch then fails, the problem is the library or its configuration, not the bus. That is worth a great deal when something is not working.

The four things that go wrong

Nothing found at all. Nearly always SDA and SCL swapped, or a missing ground. Check those two before anything else.

Wrong voltage. A 3.3 V device on an Uno’s 5 V bus may work, may read unreliably, or may be damaged. Check what the module wants. Some have a regulator and level shifting and are happy on 5 V; some are not.

Two devices, one address. Identical modules often share a fixed address, and two on one bus will conflict. The scanner shows one device where you expected two. Look for address-select pads on the board.

Long wires. I2C was designed for signals travelling across a circuit board. Past about 50 cm, or near a motor, it becomes unreliable. Keep the runs short, keep them away from motor leads, and make sure the ground is solid.

Check yourself

  1. You add a second I2C module. How many more Arduino pins does it use?
  2. The scanner finds nothing. What are the first two things to check?
  3. Two identical sensors on one bus. What will the scanner show?
  4. A device appears in the scanner but its library fails. Where is the fault?

Answers in order: none, it shares the same two wires. SDA and SCL swapped, and the ground connection. One address, because they conflict. In the library or its configuration, since the bus and wiring are proven.

Troubleshooting

Symptom Likely cause Check or fix
Nothing found SDA and SCL swapped SDA to A4, SCL to A5
Nothing found, wiring confirmed Missing ground, or module unpowered Join the grounds, check VCC
Address differs from the tutorial Different board revision Use the address the scanner reports
Found, then intermittent Too many pull-ups, or long wires Remove pull-ups on extra modules, shorten the run
One device where two are wired Address conflict Change one with its address pads
Works alone, fails with a motor running Electrical noise Route away from motor leads, improve the ground
Analog reads stopped working I2C uses A4 and A5 Move the analog input to A0 to A3
Scanner hangs SDA shorted to ground Unplug and check for a wiring short

Next steps

  • Easier first: Seeing What Your Program Is Doing, since the scanner reports through it.
  • Next: the 16×2 LCD over I2C, which is the usual first I2C device.
  • Related products: the 0.96 inch OLED display, the DS3231 real-time clock and the BMP280 pressure sensor all share this bus.

Sources and attribution

All text and code in this tutorial are original Siratek work.

  • Arduino Wire library documentation for the function names and return values.
  • I2C addressing and the role of the pull-up resistors are described from the published bus specification.

Device addresses are given as the common ones for these module types and vary between revisions, which is why the tutorial directs you to scan rather than assume. No third-party tutorial text, diagrams, photographs or code has been reproduced here.

Shop
Sidebar
0 Wishlist
0 Cart