Debugging I2C with a Logic Analyzer

I2C scanner finds nothing and re-checking wiring isn't helping? Learn to capture I2C with a logic analyzer, read START/address/ACK/STOP on screen, and diagnose the six failure signatures behind nearly every student I2C problem: NACKs, hung buses, pull-ups, level shifting, and address conflicts.

Written by Projectech8 min readPublished
For B.E./B.Tech Electronics and E&TC students interfacing I2C sensors and peripherals with Arduino, ESP32, or STM32 in academic and final-year projects Topics: I2C, Logic Analyzer, Microcontrollers
Illustration of a logic analyzer capture showing I2C start, address, ACK, data bytes and stop conditions on SDA and SCL lines.
Illustration generated for this guide.
In this guide

The sensor is wired correctly — you're sure of it. VCC to 3.3V, GND to ground, SDA to SDA, SCL to SCL. You run the I2C scanner and get... nothing. No devices found. Or worse: the scanner finds the sensor once, then hangs, and now nothing works until you power-cycle the whole board. Guessing at I2C problems by re-checking wiring is slow and frustrating. A logic analyzer turns the invisible bus traffic into something you can see — and I2C is one of the easiest protocols to decode visually.

This guide walks through capturing I2C traffic with a low-cost logic analyzer, reading the transaction on screen, and diagnosing the six failure signatures that cover nearly every student I2C problem.

I2C in 90 seconds (just enough to decode)

I2C uses two wires, both open-drain with pull-up resistors:

  • SDA — data, changes only while SCL is low (except start/stop)
  • SCL — clock, always driven by the master (with one exception below)

A transaction: START (SDA falls while SCL is high) → 7-bit address + R/W bit → ACK (slave pulls SDA low on the 9th clock) → data bytes, each followed by ACK/NACK → STOP (SDA rises while SCL is high). Every byte is 8 data bits plus 1 acknowledge bit. The acknowledge bit is the protocol's built-in diagnostic: it tells you, per byte, whether anyone is listening.

Speed grades you'll meet: Standard (100kHz), Fast (400kHz), Fast-plus (1MHz). Most student sensors work at 100 or 400kHz.

For the full protocol background — multi-master, clock stretching, 10-bit addressing — see I2C vs SPI vs UART Explained.

Setting up the capture

A USB logic analyzer (the ubiquitous 8-channel 24MHz type is fine for I2C) connects:

  • Channel 0 → SDA, Channel 1 → SCL (any two channels work; label them)
  • GND → circuit ground — this connection is mandatory; without a common ground reference the capture is garbage

Sample rate rule: capture at at least 4× the SCL frequency, preferably 10×. For 400kHz I2C, sample at 4MHz or higher. The 24MHz analyzers handle this easily. Set a trigger on the SDA falling edge (the START condition) so the capture begins exactly when a transaction starts.

Note: A logic analyzer shows digital logic levels only — it won't show you analog problems like weak pull-ups directly. But weak pull-ups do show up as slow rise times if your analyzer's software has an analog view, and they always show up as NACKs and garbage in the decoded data. When the digital decode looks inexplicable, switch to the oscilloscope: the oscilloscope debugging guide covers probing I2C properly.

Reading a healthy transaction

A good capture of writing one byte (0xAB) to register 0x10 of a sensor at address 0x68 looks like this in the decoded view:

START | 0x68+W | ACK | 0x10 | ACK | 0xAB | ACK | STOP

Learn to recognize the anatomy on the waveform:

  1. START: SDA drops while SCL stays high.
  2. Address phase: 7 address bits + 1 R/W bit on SDA, each clocked by an SCL pulse. Note: the analyzer shows the 7-bit address (0x68); the raw 8th bit is the direction (0 = write, 1 = read).
  3. ACK slots: on the 9th clock of every byte, SDA should be pulled LOW by the slave. This is the single most informative bit on the bus.
  4. Data bytes: same 8+1 structure.
  5. STOP: SDA rises while SCL is high.

NACK (SDA stays HIGH in the ACK slot) after the address byte means no device with that address responded. NACK after a data byte during a read is normal — the master NACKs the last byte to tell the slave to stop sending.

The six failure signatures

1. NACK on the address byte — "device not found"

The decoded view shows START | 0x68+W | NACK | STOP. Nobody answered.

Checklist:

  • Address wrong? Many sensors have address-select pins (ADO/SDO, A0–A2) that change the address. A sensor marked "0x68/0x69" might be at 0x69 with the pin pulled high. Read the datasheet's address table — see the datasheet guide.
  • 7-bit vs 8-bit confusion. Datasheets sometimes list the 8-bit write byte (e.g. 0xD0) instead of the 7-bit address (0x68). 0xD0 >> 1 = 0x68. If your scanner uses 7-bit addresses, halve the datasheet value.
  • Sensor not powered or in reset. Check VCC at the sensor's pin with a multimeter, and check any reset/shutdown pins are in the active state.
  • SDA/SCL swapped. It happens to everyone. The analyzer shows which line is clocking — if "SCL" never toggles, you've got the wrong wire.

2. SDA stuck low — the hung bus

SCL keeps clocking but SDA never rises; every transaction fails. A slave is holding SDA low — usually because it was mid-byte when the master reset or the transaction was interrupted, and it's still waiting to finish clocking out its byte.

Recovery procedure (no rewiring needed): configure SCL as a GPIO output and manually pulse it up to 9 times while SDA is an input. Each pulse lets the stuck slave advance one bit; after at most 9 clocks it releases SDA. Then issue a STOP. Many MCU I2C peripherals have a bus-clear feature that does exactly this — check your reference manual.

// Bus recovery: clock out a stuck slave (Arduino-style pseudocode)
// SDA as input, SCL as GPIO output
for (int i = 0; i < 9; i++) {
  digitalWrite(SCL_PIN, LOW);  delayMicroseconds(5);
  digitalWrite(SCL_PIN, HIGH); delayMicroseconds(5);
  if (digitalRead(SDA_PIN) == HIGH) break;  // slave released the bus
}
// Now issue a STOP: SDA low -> SCL high -> SDA high

3. Missing or wrong pull-up resistors

I2C lines idle HIGH — the pull-ups do the rising, the chips only pull down. With no pull-ups, both lines float and nothing works; with pull-ups too weak (too high resistance), rise times get slow and Fast-mode (400kHz) fails while 100kHz limps along.

Sizing: the pull-up must source enough current to pull the line high fast, but not so much that a chip can't pull it low (I2C specs: max 3mA sink for standard mode). Practical values:

Bus condition Pull-up value
Short bus, one or two devices, 100kHz 4.7kΩ – 10kΩ
400kHz or several devices / longer wires 2.2kΩ – 4.7kΩ
Long cables (>30cm) at 400kHz 1.5kΩ – 2.2kΩ (check 3mA limit)

Quick check: with the bus idle, both lines should read solid VCC on a multimeter. If SDA/SCL sit at some mid voltage, a device is fighting the pull-up — or the pull-ups are missing entirely.

Warning: Many sensor breakout boards include pull-ups already. Adding your own in parallel lowers the total resistance — two 4.7k in parallel is 2.35k, still fine, but stacking several boards' pull-ups can exceed the 3mA sink limit. When in doubt, measure the idle current or just remove duplicates.

4. Voltage-level mismatch

A 5V Arduino talking to a 3.3V sensor without level shifting: the sensor's SDA/SCL pins see 5V, which exceeds their absolute maximum ratings. It might work for weeks, then the sensor dies mysteriously. The capture looks fine right up until the hardware fails.

Fix: a bidirectional level shifter (the classic MOSFET-based 4-channel shifter, or a TXS0108E) between the 5V and 3.3V sides. Never use a resistive divider on I2C — it fights the pull-ups and breaks the open-drain signalling. (Dividers have their own failure modes — see the voltage dividers guide.)

5. Clock stretching confusion

A slow slave may hold SCL low to pause the master (clock stretching). On the analyzer you'll see SCL stuck low with the master waiting. This is legal I2C — but some software (bit-banged) I2C masters don't implement it and time out, blaming the sensor. If your hardware-I2C code works but bit-banged code fails with the same sensor, suspect clock stretching.

6. Address collision

Two devices with the same address on one bus: both ACK, both drive SDA during reads, and you get garbage data or bus contention. The analyzer shows clean-looking transactions with corrupt data bytes. Fix: change one device's address via its select pins, or put them on separate I2C buses (many MCUs have two).

A systematic debug workflow

  1. Multimeter first: VCC at the sensor, SDA/SCL idle HIGH, no shorts between SDA and SCL.
  2. Scanner sketch: run the standard I2C scanner. Found? The bus is electrically fine — the problem is in your register protocol (wrong register addresses, missing init sequence). Not found? Continue.
  3. Logic analyzer: capture the scanner's attempts. Match what you see against the six signatures above.
  4. Oscilloscope if needed: check rise times, voltage levels, and noise on SDA/SCL — the analog truth behind digital symptoms.
  5. Datasheet: verify the address, init sequence, and timing requirements. Sensors often need a specific wake-up or configuration write before they respond to reads.

Common mistakes

  • Probing without connecting the analyzer's ground — the #1 wasted hour.
  • Forgetting pull-ups because "the breakout board probably has them" (verify, don't assume).
  • 5V-to-3.3V I2C without a level shifter — works until it kills the sensor.
  • Long jumper wires at 400kHz — drop to 100kHz for bring-up, then raise the speed.
  • Reading the 8-bit address from the datasheet as a 7-bit address (off by a factor of two).
  • Giving up at "device not found" without looking at the ACK bit — the bus is telling you what's wrong.

Where to go from here

More project guides

More in Electronics / E&TC