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.
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
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
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.
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.
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.
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.
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
Questions about this product
See what other owners have asked, and read their solutions.
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.