An I2C scanner for Arduino and ESP32, and what to check when it finds nothing
Or see every lesson.
- 455parts on the bench
- 43boards running now
- 1.00xreal time, on every board
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.
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("I2C scanner");
}
void loop() {
int found = 0;
for (byte address = 1; address < 127; address++) {
Wire.beginTransmission(address);
byte error = Wire.endTransmission();
if (error == 0) {
Serial.print("Found a device at 0x");
if (address < 16) Serial.print("0");
Serial.println(address, HEX);
found++;
}
}
if (found == 0) {
Serial.println("No I2C devices found");
} else {
Serial.print(found);
Serial.println(" device(s) found");
}
delay(5000);
}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.
Keep going
Where the facts on this page come from
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.