Skip to the content
PCBKitNew board
2 layers75 × 80 mmLogic Analyzer, the printed circuit board in 3D

6-channel USB logic analyzer on Raspberry Pi Pico with UART/SPI/I2C decoders

Size
75 × 80 mm
Copper layers
2
Thickness
1.6 mm
Parts
24
Nets
72
Pads
136
Tracks, vias
106, 2
Pours
4
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
12 Jul 2026
Updated
12 Jul 2026

Overview

Logic Analyzer is an open-source printed circuit board by mdeepesh232-design, from the mdeepesh232-design/usb-logic-analyzer repository on GitHub. It is a 2-layer board of 75 × 80 mm with 24 parts on 72 nets, routed with 106 tracks and 2 vias.

Its parts include 21 resistors, 1 diode and 1 connector. It belongs with the sensors and measurement and interfaces and adapters boards and the RP2040 boards of this library.

README

README.md

USB Logic Analyzer (Raspberry Pi Pico)

A 6-channel USB logic analyzer built on the Raspberry Pi Pico H, using PIO + DMA for capture and a custom binary protocol over USB serial. Includes protocol decoders for UART, SPI, and I2C, each verified against real hardware.

A custom 2-layer PCB was designed in KiCad for this project (fab-ready gerbers included), but has not yet been manufactured. All functional testing and protocol verification below was done on breadboard, using the same firmware that targets the PCB -- fabbing the board is the natural next step once further validated on breadboard hardware.

Status

ProtocolDecoderVerified against real hardware
UARTdecode_uart.pyYes -- ESP32 sending "Hi" at 115200 baud
SPIdecode_spi.pyYes -- ESP32 VSPI master, "Hi" payload
I2Cdecode_i2c.pyYes -- ESP32 + MPU6050 (WHO_AM_I register read, repeated START)

How it works

  1. Capture (firmware, firmware/) -- A PIO state machine samples 6 GPIO pins every cycle and pushes them into the RX FIFO. DMA moves samples from the FIFO into a RAM buffer with no CPU involvement in the sampling loop itself, so capture timing is not affected by anything else the Pico is doing.
  2. Transfer -- Once a capture completes, the Pico sends a binary frame over USB serial: a SAMP magic marker, a 4-byte little-endian sample count, then the raw packed samples (1 byte per sample, low 6 bits = the 6 channels). No text parsing, no ambiguity about where the data ends.
  3. Host tools (host-tools/) -- Python scripts read that binary frame, save it as .bin and .csv, and decode it according to the target protocol.

The I2C debugging story

The I2C decoder initially looked broken -- captures came back completely flat, zero transitions on SDA/SCL, no transactions found. Chasing this down turned into a real debugging exercise worth documenting:

  1. Confirmed pull-up resistor wiring (4.7k to 3.3V on SDA/SCL) was correct.
  2. Rebuilt the breadboard wiring from scratch -- same result.
  3. Removed the Pico from the circuit entirely, tested ESP32 + resistors only -- still failing (Wire.endTransmission() returning error code 4).
  4. Ran a bare-board I2C scanner sketch with zero wiring connected -- worked cleanly. This proved the ESP32 pins and I2C library were fine in isolation.
  5. Reconnected full wiring, re-ran the scanner -- still worked. This proved the wiring wasn't the problem either.
  6. Went back to the custom sketch and bisected it line by line: address-only probe (worked), added setClock() (worked), added a single write() byte (failed, error 4).

This isolated the fault to a known regression in recent versions of the arduino-esp32 core's rewritten I2C driver, not the hardware or the wiring at all -- multi-byte Wire.write() calls were triggering spurious bus timeouts on this core version. Once identified, testing continued on a known-stable core version, and the bus began working correctly.

Separately, the very first "working" captures still came back flat because the test sketch used delay(500) between transactions -- with such a low duty cycle, a fixed-length trigger-based capture window had low odds of landing inside the brief active period. Removing the delay (keeping the bus continuously busy) fixed this immediately.

Both of these turned out to be more interesting than the decoder logic itself, which worked correctly the whole time.

Repository structure

text
firmware/         Pico C firmware (PIO capture + DMA + USB binary protocol)
host-tools/        Python capture + decode scripts
test-sketches/      ESP32 Arduino sketches used to generate known-good UART/SPI/I2C traffic
debug-tools/        spi_diag.py -- per-channel activity check, used to separate
                    wiring/mapping issues from decode logic bugs (same technique
                    used in the I2C bisection above)
hardware/           KiCad project (schematic, PCB layout, fab-ready gerbers)

Building the firmware

Requires the Pico SDK set up per the standard Raspberry Pi Pico C/C++ SDK instructions.

text
cd firmware
mkdir build && cd build
cmake ..
make

Flash the resulting .uf2 to the Pico in BOOTSEL mode.

Running a capture

text
cd host-tools
python capture_read_binary.py      # triggers a capture, saves capture.bin / capture.csv
python decode_uart.py              # or decode_spi.py / decode_i2c.py

Each decoder has its channel mapping documented at the top of the file -- update SDA_BIT/SCL_BIT (I2C), channel constants (SPI), or CHANNEL (UART) to match your wiring.

Hardware

  • Custom 2-layer PCB, 75x80mm, designed in KiCad
  • 5V-tolerant voltage dividers on all 6 input channels
  • Onboard I2C pull-ups, status LED
  • Not yet fabricated -- design is complete and DRC-clean, gerbers are included in hardware/gerbers/. All testing to date was done on breadboard using the same firmware.

Future work

  • Fabricate and assemble the PCB
  • Add malformed-frame / truncated-capture handling to decoders
  • Support I2C clock stretching (not exercised by the MPU6050 test used here)
  • Automated regression tests against saved capture files

Parts

24
QtyValueFootprintReferences
610kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR1, R4, R7, R12, R15, R18
620kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR2, R6, R9, R10, R13, R16
6470Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR3, R5, R8, R11, R14, R17
24.7kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR19, R20
1330Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR21
1Conn_01x08Connector_PinHeader_2.54mm:PinHeader_1x08_P2.54mm_VerticalJ1
1LEDLED_THT:LED_D5.0mmD1
1RaspberryPi_PicoModule:RaspberryPi_Pico_Common_UnspecifiedA1

Questions

How big is the Logic Analyzer PCB?

It measures 75 × 80 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Logic Analyzer use?

24 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Logic Analyzer KiCad files?

From the mdeepesh232-design/usb-logic-analyzer repository on GitHub, at the commit this page was made from: the board is hardware/Logic_Analyzer.kicad_pcb and its schematic hardware/Logic_Analyzer.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Logic Analyzer design in my own project?

Its repository states no licence, so its author keeps all rights: ask mdeepesh232-design before reusing the design.

Similar boards

  • 2 layers56 × 65 mmSeaTalk1, the printed circuit board in 3D

    SeaTalk1

    dotnet/iot

    This repo includes .NET Core implementations for various IoT boards, chips, displays and PCBs.

    24 parts2.4kMIT
  • 2 layers26.2 × 45.5 mmPL18 multiprotocol, the printed circuit board in 3D

    PL18 multiprotocol

    pascallanger/DIY-Multiprotocol-TX-Module

    Multiprotocol TX Module (or MULTI-Module) is a 2.4GHz transmitter module which controls many different receivers and models.

    24 parts1.9kGPL-3.0
  • 2 layers58 × 35.5 mmHat, the printed circuit board in 3D

    Hat

    menloresearch/asimov-1

    v1 of Asimov, an open-source humanoid robot

    24 parts1.4kCERN-OHL-S-2.0
  • 2 layers21.6 × 19.5 mmMicron Logo LED, the printed circuit board in 3D

    Micron Logo LED

    DraftShift/StealthChanger

    Tool changing system for Vorons and other front mount printer motion systems, not just stealthburner.

    24 parts1.2kGPL-3.0
  • 2 layers158 × 11 mmRainbow Matchstick, the printed circuit board in 3D

    Rainbow Matchstick

    VoronDesign/Voron-Hardware

    Cool Hardware designed by the Voron Design group

    24 parts1.1kGPL-3.0
  • 2 layers85.6 × 54 mmTRACED wio1262-carrier, the printed circuit board in 3D

    TRACED wio1262-carrier

    hackclub/OnBoard

    💡 Join 1,000 teenagers and make your first PCB with a $100 grant!

    24 parts915
  • 2 layers36 × 20 mmCombined, the printed circuit board in 3D

    Combined

    adamb314/ServoProject

    Getting the most out of your hobby servo

    24 parts545