

Panel
An rp2040-based acquisition board for pulse-echo ultrasound
- Size
- 87 × 22.3 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 46
- Nets
- 34
- Pads
- 162
- Tracks, vias
- 547, 154
- Pours
- 4
- Routed
- Yes
- KiCad
- KiCad 8.0 (file 20240108)
- Created
- 31 Mar 2024
- Updated
- 24 Oct 2026
Overview
Panel is an open-source printed circuit board by kelu124, from the kelu124/pic0rick repository on GitHub. It is a 2-layer board of 87 × 22.3 mm with 46 parts on 34 nets, routed with 547 tracks and 154 vias.
It is built around the R2D-0524/P-R, MD1213K6-G and TC6320TG-G, with the BAV99, ILSB1206ER6R8K and 150080GS75000 among its other parts. Its parts include 16 capacitors, 7 connectors, 6 ICs, 4 resistors and 3 diodes. It belongs with the RP2040 boards of this library.
Main components
6R2D-0524/P-R
SMD-6P,15.2x10.7mmIsolated Power ModulesRECOM PowerMD1213K6-G
QFN-12-EP(4x4)-40℃~+85℃ 0V~300mV 2 2A 2A 3V~5V 4.5V~13V 550uA 6ns 6ns 7ns 7ns MOSFET QFN-12-EP(4x4) Gate Drivers ROHSMicrochip TechnologyGate DriversTC6320TG-G
SOIC-8-55℃~+150℃ 1 N-Channel + 1 P-Channel 110pF 1V 200V 23pF 2A 8Ω@10V SOIC-8 MOSFETs ROHSMicrochip TechnologyMOSFETsBAV99
SOT-231 Pair Series Connection 1.25V@150mA 100V 215mA 250mW 4A 4ns 500nA@80V SOT-23 Switching Diodes ROHSNexperiaSwitching DiodesILSB1206ER6R8K
120625mA 34MHz 45@4MHz 6.8uH 800mΩ ±10% 1206 Inductors (SMD) ROHSVishay IntertechnologyInductors (SMD)150080GS75000
0805-40℃~+85℃ 140° 20mA 3.2V~3.5V 450mcd 515nm 525nm Discrete Diode Green Water Clear 0805 LED Indication - Discrete ROHSWürth ElektronikLED Indication - Discrete
README
README.md
the pic0rick project
The pic0rick is a very central board for an ultrasound pulse-echo system. It is composed of a main board, based on the RP2040 (or RP2350) and easy to solder SMD, to which a single, and a double PMOD connector can connect to addons:
- The main board is equipped with a 60Msps, 10bit ADC. Front end is protected against high-voltage pulses, and features a proven time-gain compensation system consisting in a AD8331 (7.5 dB to 55.5dB) with a controlling (MCP4812) SPI DAC.
- The single PMOD connector can plug to the Pulser board, which can be equipped with a simple +-25V generation board. Together, they generate the pulse on behalf of the pic0rick main board. The setup can generate three-level pulses ( with a pair of MD1210 + TC6320 ).
- The double PMOD connector can be used for virtually anything. The current code allows for a VGA to be connected, which displays acquisitions from the board.
The current system uses both PIOs (one for the acquisition, the other for the VGA) which leaves the other resources of the rp2040 relatively free to use for your own priorities.
Published documents include:
- KiCad design files for the main board
- KiCad design files for the pulser + hv boards
- KiCad design files for the MUX
- KiCad design files for other boards =)
- rp2040/rp2350 firmware for the microcontroller.
I know the PMODs aren't strictly speaking PMODs, I needed to have 5V facility on the header =)
And if you want to discuss the project - meet us on our chat.
Repository layout
| Path | Contents |
|---|---|
firmware/ | The unified RP2040/RP2350 firmware (CMake project adc-pulse). One source tree with -DMUX / -DDSP build options. hw/ = shared acquisition + pulser + spi1 DAC; dsp/ = RP2350 DSP (CMSIS-DSP Hilbert envelope + binary protocol); max/ = MAX14866 mux. version.yaml + CHANGELOG.md track the firmware version; build.sh builds all 6 variants into dist/. |
python/ | Host stack (pic0rick package): device.py (serial driver), dsp.py (binary frame protocol), ndt_acquisition.py (echo/thickness analysis + HDF5), and the example_*.ipynb notebooks. |
hardware/ | KiCad design files and build.sh fabrication outputs — main board (adc/), pulser + HV (pulser/), MUX (mux/), VGA (vga/), PSRAM (psram/). |
docs/ | Documentation: dsp_output_formats.md, dsp_test_guide.md, images/, data/, fw_history/ (maintainer-curated reference .uf2 baselines), and claude/ (cross-session engineering notes). |
.github/workflows/ | CI: builds all firmware variants and publishes a release on push to main. |
Getting Started
Prerequisites
- pic0rick main board + pulser board + HV board (assembled)
- USB-C cable
- Python 3.9+
- A piezoelectric transducer (e.g. 5 MHz single-element contact probe)
Building the firmware
The firmware is a single source tree (firmware/) with build options:
-DMUX(default on) — MAX14866 HV multiplexer support.-DDSP(RP2350/pico2only) — on-board Hilbert-envelope DSP + binary protocol (see DSP build below).
cd firmware && ./build.sh # builds all 6 variants into firmware/dist/:
# rp2040-{mux,nomux}, rp2350-{mux,nomux}, rp2350-{mux,nomux}-dspPrebuilt firmware/rp2040.uf2 / firmware/rp2350.uf2 are the default (mux,
non-DSP) builds. CI publishes all variants as release assets.
Flashing the firmware
- Hold the BOOTSEL button on the RP2040/RP2350 while connecting USB — the board mounts as a USB mass-storage device. (After the first flash you can instead send the
reboot-dfucommand over serial to re-enter the bootloader without the button.) - Copy the compiled
.uf2file into the drive. The board reboots automatically. - Verify: open a serial terminal at 115,200 baud. You should see the
run>prompt (stdio build). Sendversionto confirm the firmware version, board and options.
Installing the Python library
pip install pyserial numpy h5py scipy matplotlibClone this repo and add python/ to your path, or run notebooks from the python/ directory.
Quick start
The examples below target the DSP build (-DDSP, RP2350) — the recommended
firmware, which streams CRC-checked binary frames. For the plain stdio build
see Serial commands.
from pic0rick.device import Pic0rick
from pic0rick.ndt_acquisition import UltrasonicAcquisition
probe = Pic0rick() # auto-detects the USB serial port
print(probe.version()['raw'])
# Set TGC gain (raw DAC value 0–1023; higher = more gain)
probe.set_gain(300)
# Configure and arm the pulser so the capture transmits
probe.configure_pulse(negative_ns=200, damp_ns=2000, positive_ns=200,
order="pos-first")
probe.arm_pulser()
frame = probe.read_raw() # 8000-sample raw ADC frame (CRC-checked)
signal = frame.samples() # numpy uint16, 0..1023
# envelope = probe.read_fft().samples() # 4096-sample Hilbert envelope
probe.disarm_pulser()On the stdio (non-DSP) build instead use
probe.dac(gain),probe.pulse_adc_trigger(pon, poff, damp),probe.read().
Or use the higher-level acquisition wrapper (drives the DSP build for you):
acq = UltrasonicAcquisition.from_probe(
Fech=60e6,
pon=70, # pulse-on duration [ns]
poff=70, # pulse-off duration [ns]
damp=6000, # damping duration [ns]
gain=300, # raw DAC value (0–1023)
target="1018 steel 25 mm",
h5_path="my_scan.h5",
)
acq.plot()Serial commands (stdio / non-DSP build)
The stdio build exposes a text protocol at 115,200 baud (USB CDC), with a run>
prompt:
| Command | Arguments | Description |
|---|---|---|
start acq <pon> <poff> <damp> | nanoseconds | Fire pulse, DMA-capture 8000 samples |
write dac <N> | 0–1023 | Set TGC gain (MCP4812 10-bit DAC) |
read | — | Return last captured buffer (hex, comma-separated 10-bit values) |
write mux <hex> | hex word | Write the MAX14866 shift register (MUX builds) |
set mux / clear mux | — | Pulse the MAX14866 SET / CLR line (MUX builds) |
version | — | Print firmware version, board/chip, options, git hash, release URL |
reboot-dfu | — | Reboot into the USB bootloader (BOOTSEL) for reflashing |
The DSP build uses different commands (
dac write,read_raw,read_fft, …) and a binary protocol — see DSP build.
Parameter details
pon / poff / damp — expressed in nanoseconds from Python. The firmware converts them to 125 MHz clock cycles internally (divides by 8).
gain — raw 10-bit DAC value (0–1023) controlling the VGAIN pin of the AD8331 TGC amplifier (7.5 dB to 55.5 dB range). The example notebook uses values in the 0–500 range.
DSP build (RP2350)
Building with -DDSP=ON (RP2350/pico2) adds an on-board DSP path: a float32
CMSIS-DSP Hilbert envelope. Instead of the text REPL it speaks a binary framed
protocol (64-byte header + CRC32) with two capture modes:
read_raw— 8000 raw ADC samples (no FFT).read_fft— 4096-sample Hilbert envelope.
plus acq raw|envelope|alaw, stream start|stop, dsp scale|selftest,
dac write <0..1023>, pulse config <neg_ns> <damp_ns> <pos_ns> <neg-first|pos-first>,
pulser arm|disarm, status, help, version, reboot-dfu.
Drive it from Python with pic0rick.dsp and these Pic0rick methods:
version(), status(), set_gain(n), configure_pulse(...),
arm_pulser()/disarm_pulser(), read_raw(), read_fft(), capture(payload).
The frame and status formats are documented in
docs/dsp_output_formats.md; see
docs/dsp_test_guide.md and the
python/example_dsp.ipynb / python/example_simple.ipynb notebooks.
Signal chain
Transducer
│
├──► TX path: PIO pulser GPIO11/12 (P+/P-) + GPIO16/17 (PDAMP/OE) → MD1213 + TC6320 → ±25V three-level pulse
│
└──► RX path: T/R protection → AD8331 TGC (gain set by MCP4812 DAC)
→ 60 Msps 10-bit ADC (PIO + DMA, 8000 samples/acquisition)
→ USB CDC → PythonThe ADC samples are 10-bit unsigned (0–1023, mid-scale = 512). The ndt_acquisition wrapper normalises them to float32 in the range ≈ [−1, 1]:
signal = (adc_count - 512) / 512.0Setup
The three boards assemble look like this

Example of acquisitions

Demo of output to VGA
Beware. This is not a standard development, more of a proof of concept. It lives on a separate branch here.
Only using the pico to setup gain and trigger acquisitions. The screen displays the gain value (0 to 9, with a 100x divider). Displays raw buffer of acquisition.

Example of a compact assembly
Within a game card footprint

Along with the other boards

Assembly
What you get :

Before assembly
You will need to get a few headers, a raspberry pico, and SMA connectors

Focus on the Pulser connector

Once assembled
Top view

Bottom view

License
This work is based on three previous TAPR projects, the echOmods project, the un0rick project, and the lit3rick project - their boards are open hardware and software, developped with open-source elements as much as possible.
Copyright Luc Jonveaux (kelu124@gmail.com) 2024
- The hardware is licensed under TAPR Open Hardware License (<www.tapr.org/OHL>)
- The software components are free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- The docs is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Disclaimer
This project is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE.
Parts
46| Qty | Value | Footprint | References |
|---|---|---|---|
| 7 | 100nF | Capacitor_SMD:C_1206_3216Metric | C1, C3, C7, C8, C14, C15, C16 |
| 4 | 1uF | Capacitor_SMD:C_1206_3216Metric | C2, C6, C12, C13 |
| 3 | 10K | Resistor_SMD:R_1206_3216Metric | R2, R3, R4 |
| 3 | 10nF | Capacitor_SMD:C_1206_3216Metric | C4, C5, C9 |
| 2 | 120Ohm 3 A | Inductor_SMD:L_1206_3216Metric | FB1, FB2 |
| 2 | 4.7uF | Capacitor_SMD:C_1206_3216Metric | C10, C11 |
| 2 | BAV99 | Package_TO_SOT_SMD:SOT-23 | D1, D2 |
| 2 | LOGO | ICTAMKY_V8:qr_pic0rick | G***, G*** |
| 2 | MD1213K6-G | PMOD_PULSER:MD1213 | IC2, IC5 |
| 2 | SN74LVC2G04DBVT | PMOD_PULSER:SN74LVC2G04DBV | IC1, IC4 |
| 2 | TC6320TG-G | PMOD_PULSER:SOIC127P600X175-8N | IC3, IC6 |
| 1 | 1K | Resistor_SMD:R_1206_3216Metric | R1 |
| 1 | 6.8uH | Inductor_SMD:L_1206_3216Metric | L1 |
| 1 | 61300611021 | Connector_PinHeader_2.54mm:PinHeader_1x06_P2.54mm_Horizontal | J3 |
| 1 | AMPHENOL_132357-11 | PMOD_PULSER:AMPHENOL_132357-11 | J1 |
| 1 | Conn_01x02 | Connector_PinHeader_2.54mm:PinHeader_2x01_P2.54mm_Horizontal | J2 |
| 1 | Conn_01x02_Pin | Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical | J6 |
| 1 | Conn_01x02_Socket | Connector_PinSocket_2.54mm:PinSocket_1x02_P2.54mm_Vertical | J7 |
| 1 | Conn_01x03_Pin | Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical | J4 |
| 1 | Conn_01x03_Socket | Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_Vertical | J5 |
| 1 | Green LED | Diode_SMD:D_0805_2012Metric | D3 |
| 1 | LOGO | ICTAMKY_V8:OSHW_mask_1 | G*** |
| 1 | R2D-0524_P | SamacSys_Parts:R2D0524P | PS1 |
| 1 | TC74VHC08F_EL,K,F_ | PMOD_PULSER:SOIC127P780X190-14N | H1 |
| 1 | VAL** | Panelization:mouse-bite-3mm-slot | mouse-bite-3mm-slot |
The 45 most common of 46 parts.
More from kelu124/pic0rick
7- 4 layers87.1 × 78.2 mm

- 4 layers85 × 54 mm

- 2 layers63.3 × 22.3 mm

PMOD Pulser update
kelu124/pic0rick
An rp2040-based acquisition board for pulse-echo ultrasound
33 parts116 - 2 layers63 × 23.5 mm

- 2 layers20.7 × 22.3 mm

- 2 layers47.3 × 16.3 mm

- 2 layers18.8 × 16.3 mm

Similar boards
- 4 layers120 × 80 mm

- 4 layers200 × 100 mm

- 2 layers47 × 52.1 mm

- 2 layers79.5 × 79.5 mm

Esp32-energymeter V2
ElektorLabs/esp32-energymeter
The Elektor ESP32 Energy Meter project, featuring schematics, PCB designs, and ESPHome integration for advanced energy monitoring
116 parts48MIT - 2 layers40 × 50 mm

Wired sculpt
chadaustin/wired-sculpt-pcb
KiCad design files for the Wired Sculpt conversion mod
39 parts35 - 4 layers127 × 76.2 mm

Payload pcb
austindriggs/urc-payload-pcb
All-purpose control and interface board designed to manage mission-critical sensors and electronics for University Rover Challenge at WVU.
114 partsMIT - 2 layers50 × 70 mm

- 2 layers152.1 × 70.1 mm

Questions
How big is the Panel PCB?
It measures 87 × 22.3 mm and has 2 copper layers, 1.6 mm thick.
What parts does the Panel use?
46 parts, built around the R2D-0524/P-R, MD1213K6-G, TC6320TG-G and BAV99. 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 Panel KiCad files?
From the kelu124/pic0rick repository on GitHub, at the commit this page was made from: the board is hardware/pulser_panel/panel.kicad_pcb and its schematic hardware/adc/PICO_ADC_Test.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the Panel design in my own project?
Its repository states no licence, so its author keeps all rights: ask kelu124 before reusing the design.