Unit D - Sensors & Buses

17. I2C, Address Scanning & I2C LCD

Share a two-wire bus and simplify display wiring.

Estimated time 4 hours

Learning outcomes

  • Explain SDA, SCL, addresses and pull-ups on the Uno
  • Compare parallel LCD wiring with an I2C backpack
  • Scan or confirm a backpack address (often 0x27 or 0x3F)
  • Drive a 16x2 I2C LCD with LiquidCrystal I2C by Frank de Brabander

Parts and preparation

Uno, I2C LCD backpack/display and jumper wires. Install LiquidCrystal I2C by Frank de Brabander (see Libraries box).

Before power: inspect wiring, confirm supply voltage and ensure all connected circuits share GND.

Libraries for this lesson

In Arduino IDE 2 open Tools → Manage Libraries…. Search by the Library Manager name and install the package by the exact author below. Similar names from other authors can use different APIs and will break the example.

IncludeLibrary Manager nameAuthorInstall note
Wire.hWireArduinoBuilt into the Arduino core. No Library Manager install required.
LiquidCrystal_I2C.hLiquidCrystal I2CFrank de BrabanderInstall via Library Manager. Other LiquidCrystal_I2C packages use different APIs (init vs begin).
I2C, Address Scanning & I2C LCD instructional connection diagram

What I2C adds

I2C is a two-wire serial bus: SDA carries data and SCL carries a shared clock. On the Uno, SDA is A4 and SCL is A5.

Several devices can share those same two wires because each device has its own address. The Uno (master) calls a device by address; only that device answers.

Uno master connected to shared SDA and SCL lines with an LCD backpack at 0x27, an RTC at 0x68 and another device on the same bus
One SDA and one SCL for every device. Addresses keep them separate. Share GND.

Parallel LCD vs I2C backpack

Lesson 16 drove the HD44780 with RS, E and four data lines. An I2C backpack sits on the LCD and talks over SDA/SCL instead, so the Uno only needs VCC, GND, SDA and SCL.

The character grid is still 16 columns by 2 rows. setCursor(column, row) works the same way.

Comparison of parallel LCD needing six signal pins versus I2C backpack needing only SDA and SCL plus power
Same display glass; I2C cuts the signal wiring to two pins.

Pull-ups

SDA and SCL are open-drain: devices only pull a line LOW. Pull-up resistors to 5 V hold the idle state HIGH. Most LCD backpacks already include those resistors.

Many modules on one bus can make the combined pull-up too strong. If the bus becomes unreliable with several devices, check module documentation and pull-up strategy.

Schematic showing pull-up resistors from 5 V to the SDA and SCL lines
Idle HIGH via Rpu; devices pull LOW. Backpacks usually include Rpu.

Addresses and scanning

The constructor includes the backpack address, columns and rows: LiquidCrystal_I2C lcd(0x27, 16, 2). Common backpack addresses are 0x27 and 0x3F; solder pads on the backpack can change this.

If the screen stays blank, run an I2C scanner sketch, match the constructor to the reported address, and adjust the backpack contrast potentiometer.

Three cards showing constructor address, common 0x27 and 0x3F values, and blank-display checklist with scanner and contrast
Scan first if the display is blank. Then match the constructor address.
ItemCourse practice
LibraryLiquidCrystal I2C by Frank de Brabander
Init APIlcd.init() and lcd.backlight()
Default try0x27, then 0x3F if needed
Uno pinsSDA A4, SCL A5, shared GND

Same 16x2 coordinates

setCursor(column, row) is still zero-based: columns 0-15, rows 0-1. The worked sketch prints a heading on row 0, then updates an ADC field on row 1. Pad with spaces when numbers get shorter so leftover digits do not remain.

16 by 2 character grid showing I2C connected on row 0 and ADC 512 on row 1 with setCursor 0,1 highlighted
Same grid as lesson 16. Highlighted cell is setCursor(0, 1).

Library variation

Several Library Manager packages use similar names. This course uses LiquidCrystal I2C by Frank de Brabander (init/backlight). A different author's package may expect begin() instead and will not compile or run with this sketch.

Wiring and safe build sequence

Breadboard wiring for lesson 17: I2C, Address Scanning & I2C LCD
Breadboard layout for this lesson. Match colours and pins before powering the circuit. Click the image for a larger view.
  1. LCD VCC -> 5 V
  2. LCD GND -> GND
  3. LCD SDA -> A4
  4. LCD SCL -> A5
Power rule: switch off before moving wires. Arduino I/O pins are control signals; high-current loads require a driver and suitable external supply.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  Wire.begin();
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("I2C connected");
}

void loop() {
  lcd.setCursor(0, 1);
  lcd.print("ADC ");
  lcd.print(analogRead(A0));
  lcd.print("    ");
  delay(250);
}

How the code works

  1. Change 0x27 only if a scanner reports another address.
  2. All devices on the bus share SDA, SCL and GND.
  3. Trailing spaces clear leftover ADC digits when the value gets shorter.

Test and record evidence

Expected result: The LCD shows a heading and live A0 reading using only two signal wires.

Practical evidence checklist

Common faults and checks
  • Run an I2C scanner if the display is blank.
  • Adjust the backpack contrast potentiometer.
  • Confirm the installed library's initialization API (init vs begin).
  • Check A4/A5 are not swapped and GND is common.
Extension challenge: Connect an RTC on the same bus and explain why no extra SDA/SCL pins are required.

Check your understanding

Q1. Why can devices share SDA and SCL?

Show answer

Each device responds to its own I2C address.

Q2. Which Uno pins are SDA and SCL?

Show answer

A4 is SDA and A5 is SCL.

Q3. What should you do if 0x27 shows nothing?

Show answer

Scan the bus, try the reported address, and adjust contrast.

Q4. Does I2C change the 16x2 cursor rules?

Show answer

No - columns are still 0-15 and rows 0-1.