logic analyzer/Turning edges back into bytes/10. Your first I²C capture
Turning edges back into bytes · 10 of 11

Your first I²C capture

Two channels, one ground, and a sketch that asks a sensor who it is once a second. The ninth clock of the first frame answers the question everybody actually has, which is whether anything is on the bus at all.

What to wire

Three clips. SDA on CH0, SCL on CH1, and ground — fitted first, before either of the other two.

Leave the remaining six channels unclipped. They cost nothing: all eight inputs are read and sent as one byte per tick whether or not anything is attached, so an unused channel is genuinely free.

Set the sample rate from the bus rather than from the top of the list. A 400 kHz I²C bus has a 2.5 µs bit period, so 4 MS/s is ten samples a bit — comfortably more than any decoder needs, and a sixth of the USB traffic of running flat out.

Something to capture

A bus that is idle produces an empty screen, and an empty screen tells you nothing about whether the setup works. So give it something predictable: the sketch above asks the device at 0x68 for its identity register once a second and prints the answer.

Two views of the same event is the point. When the serial monitor and the capture agree, you know where you are; when they disagree, the disagreement is the finding.

The nine clocks that matter

Start the capture, let it run for a couple of seconds, stop it, and zoom into the first burst of activity.

The nine clocks that answer “is it there”
idle
Clocks in the frame
9
Bits the master sent
8
Bits the device sent
0
Press it. The frame is 0x68 being addressed for a write, which is the first thing every I²C sensor library does and the first thing worth capturing.

Everything before the ninth clock was sent by your board. The master transmits the address whether or not anything is listening, so a capture full of addresses proves that the sketch is running and nothing else.

The ninth clock is the evidence. The master lets SDA float up and waits; a device that recognised its address holds the line down. Low there is an ACK and something on the bus answered to that address. High is a NAK — and a NAK is not a fault in the capture, it is a result, and it narrows the problem to the bus rather than the firmware.

Adding the decoder

In Logic 2, add an I²C analyzer and tell it which channel is SDA and which is SCL. In PulseView, add the I²C decoder and do the same. A row appears under the traces with the transaction spelled out: start, address, direction, acknowledgement, data bytes, stop.

Check that row against what you know. If your sketch asked device 0x68 for register 0x75, the decoded row should say exactly that — and if it says an address you have never heard of, the channels are probably the wrong way round rather than the sensor being strange.

Reading the repeated start

The sketch ends its write with endTransmission(false), which is deliberate. It tells the library not to release the bus, so instead of a stop condition followed by a fresh start you get a repeated start — a second start condition without an intervening stop.

You will see it in the capture as SDA falling while SCL is high, part way through what looked like one transaction. It is what almost every sensor library does for a register read, and recognising the shape is worth the two minutes it takes.

What you have proved

If the ninth clock is low and the decoded address matches the sketch, then: the analyzer works, the ground is right, the channels are the right way round, the sample rate is sufficient, the bus is wired, the sensor has power, and it answers to the address you think it does.

That is seven things settled in one capture, which is why this is the first thing to do when a sensor will not talk — before reading any more of the library's source.

The code

i2c_traffic.ino

Something predictable to capture. It asks the device at 0x68 for its identity register once a second and prints what came back, so the serial monitor and the analyzer are two views of the same event and you can line them up. Any I²C sensor will do — change the address and the register to match whatever is on your bench.

// Logic analyzer wiring for this sketch.
//
//   CH0 -> SDA        GPIO 8 on an ESP32-S3, A4 on an Uno
//   CH1 -> SCL        GPIO 9 on an ESP32-S3, A5 on an Uno
//   GND -> GND        fit this one first; it is not optional
//
// Two channels is all this needs. Leave the other six unclipped — they
// cost nothing, because all eight are read and sent as one byte per tick.
//
// Sample rate: 4 MS/s is ten samples per bit at 400 kHz and a sixth of the
// USB load of running at 24. There is no advantage here in going faster.

#include <Wire.h>

const uint8_t ADDR = 0x68;  // change to your device
const uint8_t REG  = 0x75;  // its identity register

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000);
}

void loop() {
  Wire.beginTransmission(ADDR);
  Wire.write(REG);
  // endTransmission(false) holds the bus and issues a repeated start,
  // which is the shape you will see in the capture.
  uint8_t err = Wire.endTransmission(false);

  if (err != 0) {
    Serial.printf("no ACK from 0x%02X (error %u)\n", ADDR, err);
  } else if (Wire.requestFrom(ADDR, (uint8_t)1) == 1) {
    Serial.printf("0x%02X reg 0x%02X = 0x%02X\n", ADDR, REG, Wire.read());
  } else {
    Serial.println("addressed, but no data came back");
  }

  delay(1000);
}

If the serial output says “no ACK” and the capture shows SDA staying high on the ninth clock, the two agree and the fault is on the bus rather than in the sketch: wrong address, a wire on the wrong pin, no power to the sensor, or missing pull-ups. If the serial output says nothing at all, the sketch is not running and the analyzer is not the suspect.

When it does not work

The capture is empty and the sketch is definitely running

Check which two pins the board actually uses for I²C. Wire.begin() with no arguments picks the board's default pair, and on an ESP32 that is not the same pair on every variant — the sketch may be talking on two pins you have not clipped anything to. Print them, or pass them explicitly.

SDA and SCL both sit high and never move

Nothing is driving the bus. Either the sketch has not reached Wire.begin(), or the pins in the sketch are not the pins you probed. If they are correct, look for the pull-up resistors: an I²C bus with none has nothing to pull the lines high and nothing to pull them low against, and most sensor breakout boards fit them but a bare chip does not.

The address on screen is half my device's address

You are looking at a 7-bit address and thinking of an 8-bit one, or the reverse. The wire carries seven address bits followed by a read/write bit, so 0x68 on the bus appears as 0xD0 or 0xD1 in documentation that quotes the whole first byte. Both decoders here report the 7-bit form.

The ninth clock is high — a NAK

That is the useful result, not a failure of the capture. Nobody on the bus recognised the address, which narrows it to four things: the wrong address, a wire on the wrong pin, a sensor with no power, or a bus with no pull-ups. It is not a firmware bug, and you have just saved yourself an afternoon of looking for one.

Where this goes next

The decoder does not report errors when it has been told the wrong two channels. It reports bytes, and they look entirely plausible.

When the decode is wrong

Edit this page — content/books/logic-analyzer/your-first-i2c-capture.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

Logic Analyzer Kit, 8-Channel 24 MHz

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum