Source: https://mokxi.com/learn/i2c-scanner
Updated: 2026-10-26

Learn

# An I2C scanner for Arduino and ESP32, and what to check when it finds nothing

Written by the Mokxi team, updated October 26, 2026

Start building free

Or see every lesson.

- 455 parts on the bench
- 43 boards running now
- 1.00x real time, on every board

Click to open it in the editor

The Uno asks every address from 1 to 126 and prints the two that answer, 0x27 and 0x3C.

An I2C scanner is the first sketch to run on any new I2C build. It asks every address from 1 to 126 whether a device is there and prints the ones that answer. If your display, sensor or clock shows up, the wiring is right and the address is the one to put in your code. If nothing shows up, the problem is the wires or the power, and no change to the display code will fix it.

The circuit above is an Arduino Uno with two common modules on its bus: a 16x2 LCD with a PCF8574 backpack and an SSD1306 OLED. It runs Mokxi’s i2cscan program, which checks the bus before it scans and then prints "idle bus: SDA HIGH, SCL HIGH", "found 0x27", "found 0x3C" and "2 device(s), 126 addresses in 51 ms". A logic analyzer sits on the same two wires, decoding each address as it goes out.

Below is the plain scanner most tutorials use, run on an Uno and on ESP32 boards, then each way a scan comes back empty, made on purpose on the same two modules.

## The scanner sketch

For each address, the sketch starts a transmission, sends nothing, and ends it. Wire.endTransmission() returns 0 when a device pulled SDA low on the ninth clock to say "that is me", and 2 when nobody did. So the whole scan is a loop over the addresses and one if. Addresses 0 and 127 are left out, because 0 is the general call address and the top of the range is reserved.

The same sketch builds for an Uno and for every ESP32 board without a change. With the LCD and the OLED on A4 and A5 of an Uno it printed "I2C scanner", then "Found a device at 0x27", "Found a device at 0x3C" and "2 device(s) found". With the same two modules on GPIO 8 and 9 of an ESP32-C3, on GPIO 21 and 22 of an ESP32 DevKit and on GPIO 8 and 9 of an ESP32-S3, it printed the same two addresses. It scans again every five seconds, so you can plug a module in while it runs and watch it appear.

An I2C scanner for Arduino and ESP32

## Which pins Wire.begin() uses on each ESP32

Wire.begin() with no arguments uses the board’s default I2C pins, and they are not the same on every ESP32. This is the most common reason an ESP32 scan finds nothing: the modules are on the pins a tutorial for a different board used. Printing SDA and SCL in Mokxi gives these, which are the defaults the Arduino ESP32 core sets for the same boards: the ESP32 DevKit uses SDA 21 and SCL 22, the ESP32-S3 DevKitC and the ESP32-C3 DevKitM use SDA 8 and SCL 9, and so does the ESP32-C3 SuperMini. The ESP32-C6 DevKitC uses SDA 23 and SCL 22. The XIAO boards follow their silkscreen: SDA 6 and SCL 7 on the XIAO ESP32-C3, SDA 22 and SCL 23 on the XIAO ESP32-C6.

We put the two modules on GPIO 8 and 9 of an ESP32-C6, the C3’s pins, and the scan printed "No I2C devices found". On an ESP32-C3 with the modules on GPIO 4 and 5 it printed the same. Nothing was wrong with either module. Changing one line to Wire.begin(4, 5);, which names SDA first and SCL second, and the C3 found 0x27 and 0x3C again. Any two free GPIO pins can carry I2C on an ESP32, so when in doubt, name them.

On the C3 SuperMini, GPIO 8 also drives the blue on-board LED and GPIO 9 is the BOOT button. In Mokxi a scan on 8 and 9 of a SuperMini still finds both modules. If a SuperMini of yours behaves oddly with I2C on those two pins, move the bus to two others with Wire.begin(sda, scl) and check again.

## It finds nothing: SDA and SCL swapped

Swap the two bus wires on the Uno, so the modules’ SDA goes to A5 and their SCL to A4, and the scan prints "No I2C devices found". Every module is still powered, still at its address and still has its pull-ups. It just never sees a start condition it recognizes, because the line it reads as the clock is carrying data. Nothing is damaged. Swap them back and both addresses return.

Check the labels on the module itself rather than a drawing. Some breakouts print SDA before SCL and some the other way around, and the four pins on an LCD backpack are in a different order from the four on an OLED.

## It finds one device but not the other: power and ground

Take the LCD backpack’s VCC wire off and run the scan again. It prints "Found a device at 0x3C" and "1 device(s) found": the OLED still answers and the backpack, with no supply, does not. Take both modules’ ground wires off and it prints "No I2C devices found". A module needs VCC and GND as well as the two bus wires, so check all four on every module, not only the two that carry data.

One thing this does not show: Mokxi does not check a module’s supply voltage. The backpack powered from a C3’s 3.3 V pin still answered at 0x27 here. On a desk, most 16x2 LCDs are 5 V parts and look faint or blank at 3.3 V, so power the backpack from the board’s 5 V pin. Its pull-ups then hold SDA and SCL at 5 V, which is more than an ESP32’s pins are rated for. A small I2C level shifter between the two is the safe fix.

## Pull-ups, and what the simulation leaves out

I2C lines are never driven high. Every device only pulls a line low or lets go, and resistors to the supply bring it back up. Nearly every breakout carries its own pair, which is why the OLED and the LCD here work with nothing else on the breadboard. A bare chip has none. We put a bare PCF8574 on the Uno with no resistors and it still answered at 0x20, and the same on an ESP32-C3, because both boards’ Wire turns on the chip’s weak internal pull-ups.

Mokxi does not model bus capacitance or rise times. A bus with weak pull-ups, long wires or many modules works here even where it fails on a bench, so if your scan finds a device only some of the time, add 4.7 k resistors from SDA and SCL to the supply and keep the wires short. For how the pull-ups and the acknowledge work, and why two devices on one address look like one, see the I2C explainer.

## It finds the device, but the screen stays blank

Then the bus is fine and the fault is in the sketch. Put the address the scanner printed into the constructor, such as LiquidCrystal_I2C lcd(0x27, 16, 2); or display.begin(SSD1306_SWITCHCAPVCC, 0x3C), and call the library’s init() or begin() before printing. A backpack that answers at 0x3F instead of 0x27 is the usual surprise; the LCD guide below goes through every symptom of a blank display.

## Questions

What address does a 16x2 I2C LCD use?

Usually 0x27 for a backpack with the PCF8574 chip and 0x3F for the PCF8574A, but jumpers on the backpack can move it. Run the scanner and use the address it prints.

What is the I2C address of an SSD1306 OLED?

Most 128x64 and 128x32 modules answer at 0x3C, and some are set to 0x3D. The scan of the circuit on this page finds its OLED at 0x3C.

Why does my ESP32 I2C scanner find nothing?

Most often the modules are on different pins from the board’s defaults: 21 and 22 on an ESP32 DevKit, 8 and 9 on the S3 and C3, 23 and 22 on the C6. Name your pins with Wire.begin(sda, scl). Then check SDA and SCL are not swapped and that every module has power and ground.

What does the scanner print with nothing on the bus?

On an Uno in Mokxi it prints "No I2C devices found". A scan that instead finds every address, or hangs, is telling you a line is held low, usually by a short, a module wired backwards or a missing pull-up.

Related

## Keep going

I2C Explained: Addresses, Acknowledges and Pull-Ups Arduino I2C LCD Not Working: Blank, Blocks, No Text Arduino LCD I2C 16x2: Wiring, Code, Scrolling Text Arduino OLED Display (SSD1306) Tutorial Pull-Up Resistors and the Floating Input They Fix ESP32 I2C Pins: Custom Pins and Two I2C Buses The I2C simulator, with the bus decoded The I2C modules in the parts bin The ESP32-C3 simulator

Sources

## Where the facts on this page come from

- Arduino reference: Wire.endTransmission() and its return codes
- Arduino ESP32 core: each board’s default SDA and SCL in its pins_arduino.h

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building free Open the editor
