Skip to the content
PCBKitNew board
4 layers42.8 × 67.5 mmPCB Interface, the printed circuit board in 3D

PCB Interface

Domfunkle/NHP_Synth

This project implements a dual-channel Direct Digital Synthesis (DDS) signal generator on the ESP32 platform. It features:

Size
42.8 × 67.5 mm
Copper layers
4
Thickness
1.36 mm
Parts
80
Nets
77
Pads
244
Tracks, vias
426, 125
Pours
6
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
8 Jul 2025
Updated
5 May 2026

Overview

PCB Interface is an open-source printed circuit board by Domfunkle, from the Domfunkle/NHP_Synth repository on GitHub. It is a 4-layer board of 42.8 × 67.5 mm with 80 parts on 77 nets, routed with 426 tracks and 125 vias.

It is built around the LM324DT, TPS65131RGER and ZX-PM2.54-1-20PY, with the CESD3V3D3, MBR120LSF and AO3401A among its other parts. Its parts include 30 resistors, 24 capacitors, 7 diodes, 5 ICs and 2 inductors. It belongs with the interfaces and adapters boards of this library.

Main components

6

README

README.md

NHP_Synth: ESP32 Dual DDS Synthesizer

This project implements a dual-channel Direct Digital Synthesis (DDS) signal generator on the ESP32 platform. It features:

  • Two independent sine wave outputs (via DACs on GPIO25 and GPIO26)
  • Precise square wave output (GPIO18) synchronized to DDS phase
  • UART command interface for real-time control
  • Phase, frequency, and amplitude control for each channel
  • Odd harmonic mixing with amplitude and phase control per channel (total 8 simultaneous harmonics across both channels)
  • External sync input (GPIO19, rising edge)
  • High-resolution timer for accurate waveform generation

Features

  • Frequency Range: 20 Hz to 8 kHz (configurable)
  • Amplitude Ramping: Smooth amplitude changes to prevent clicks
  • Phase Control: Set phase offset for each channel
  • Harmonic Mixing: Add odd harmonics (3rd, 5th, 7th, etc) to either channel, with amplitude and phase control. Up to a total of 8 harmonics can be active across both channels at once.
  • UART Commands:
    • wf[a|b]<freq>: Set channel A or B frequency (Hz)
    • wp[a|b]<deg>: Set channel A or B phase (degrees, -180 to +180)
    • wa[a|b]<ampl>: Set channel A or B amplitude (0-100)
    • wh[a|b]<order>,<pct>[,<phase>]: Mix odd harmonic to channel A or B (e.g. wha3,10 for 10% 3rd harmonic, or wha7,20,-90 for 20% 7th harmonic at -90° phase)
    • whcl[a|b]: Clear all harmonics for channel A or B
    • help: Show help message

Hardware Connections

  • DAC Channel A: GPIO25
  • DAC Channel B: GPIO26
  • Square Wave Output: GPIO18
  • Sync Input: GPIO19 (rising edge, with pulldown)

Project Structure

text
NHP_Synth/
├── firmware/           # ESP32 firmware (ESP-IDF project)
│   ├── main/          # Main application source
│   ├── .devcontainer/ # ESP-IDF development container
│   └── .vscode/       # ESP32-specific VS Code settings
├── host/              # Python host control interface
│   ├── synth_control/ # Python control library
│   ├── examples/      # Usage examples
│   ├── .devcontainer/ # Python development container
│   └── .vscode/       # Python-specific VS Code settings
├── tools/             # Shared utilities and scripts
└── .vscode/           # Root workspace configuration

Build & Flash

Firmware (ESP32)

Navigate to the firmware directory and use ESP-IDF:

bash
cd firmware
idf.py build
idf.py -p /dev/ttyUSB0 flash

Or use the convenient script for multiple devices:

bash
./tools/flash_multiple.sh

Host Control (Python)

A Python interface is provided for programmatic control:

bash
cd host
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# Run examples
python examples/basic_control.py
python examples/harmonic_sweep.py

UART Usage

Connect to the ESP32 UART (default 115200 baud) and type commands as described above. Type help for a list of commands.

Linux commands to test UART

bash
# Generate a square wave on Channel A at 50Hz
printf "wha3,33\r" > /dev/ttyUSB1
printf "wha5,20\r" > /dev/ttyUSB1
printf "wha7,14\r" > /dev/ttyUSB1
printf "wha9,11\r" > /dev/ttyUSB1
printf "wha11,9\r" > /dev/ttyUSB1
printf "wha13,8\r" > /dev/ttyUSB1
printf "wha15,7\r" > /dev/ttyUSB1
printf "wha17,6\r" > /dev/ttyUSB1
bash
# Clear all harmonics for Channel A and B
printf "whcla\r" > /dev/ttyUSB1
printf "whclb\r" > /dev/ttyUSB1
bash
# Rolling harmonic phase for Channel A and B
ph=-180
while true; do
    printf "wha5,20,%d\n" "$ph" > /dev/ttyUSB1
    invph=$((ph * -1))
    printf "whb3,10,%d\n" "$invph" > /dev/ttyUSB1
    sleep 0.03
    ph=$((ph + 1))
    if [ "$ph" -gt 180 ]; then
        ph=-180
    fi
done

Development

VS Code Workspace

Open the multi-root workspace for unified development:

bash
code .vscode/NHP_Synth.code-workspace

DevContainers

Each component has its own development container:

  • Firmware: ESP-IDF container with all tools
  • Host: Python container with analysis libraries

Tools

  • tools/flash_multiple.sh - Flash firmware to multiple devices
  • tools/uart_test.py - Test UART communication

File Structure

  • firmware/main/main.c: Main ESP32 application source
  • firmware/build/: Build artifacts (ignored by git)
  • host/synth_control/: Python control library
  • host/examples/: Python usage examples
  • tools/: Shared utilities and scripts
  • .gitignore: Excludes build and config files from version control

License

MIT License (or specify your license here)

Parts

80
QtyValueFootprintReferences
710kResistor_SMD:R_0603_1608MetricR1, R2, R3, R4, R11, R12, R22
622u/16VCapacitor_SMD:C_0805_2012MetricC11, C13, C20, C21, C22, C24
5100nCapacitor_SMD:C_0603_1608MetricC1, C2, C5, C6, C12
547kResistor_SMD:R_0603_1608MetricR5, R6, R16, R24, R29
4100kResistor_SMD:R_0603_1608MetricR7, R8, R9, R10
4330Resistor_SMD:R_0603_1608MetricR17, R18, R19, R20
2100keasyeda2kicad:RES-ADJ-SMD_TC33X-2-104ER26, R27
2100keasyeda2kicad:RES-ADJ-TH_3296PRV1, RV2
210uCapacitor_SMD:C_0603_1608MetricC3, C4
215pCapacitor_SMD:C_0603_1608MetricC18, C23
21nCapacitor_SMD:C_0603_1608MetricC7, C8
222kResistor_SMD:R_0603_1608MetricR13, R14
222pCapacitor_SMD:C_0603_1608MetricC14, C15
2470pCapacitor_SMD:C_0603_1608MetricC9, C10
24k7Resistor_SMD:R_0603_1608MetricR23, R30
24u7easyeda2kicad:IND-SMD_L5.4-W5.2_FXL0530L1, L2
2CESD3V3D3easyeda2kicad:SOD-323_L1.8-W1.3-LS2.5-RDE1, E2
2LM324DTeasyeda2kicad:SOIC-14_L8.7-W3.9-P1.27-LS6.0-BLU3, U4
2LOGOLOGOG***, G***
2MBR120LSFeasyeda2kicad:SOD-123_L2.8-W1.8-LS3.7-RDD1, D5
2REDeasyeda2kicad:LED0805-R-RDLED2, LED3
2SMF9.0CA_C19077504easyeda2kicad:SOD-123FL_L2.7-W1.8-LS3.8-BID3, D4
2ZX-PM2.54-1-20PYeasyeda2kicad:HDR-TH_20P-P2.54-V-FU10, U11
1100Resistor_SMD:R_0603_1608MetricR15
110nCapacitor_SMD:C_0603_1608MetricC16
1220nCapacitor_SMD:C_0603_1608MetricC19
14n7Capacitor_SMD:C_0603_1608MetricC17
1560kResistor_SMD:R_0603_1608MetricR21
159kResistor_SMD:R_0603_1608MetricR25
1750kResistor_SMD:R_0603_1608MetricR28
1AO3401Aeasyeda2kicad:SOT-23_L2.9-W1.3-P1.90-LS2.4-BRQ1
1GREENeasyeda2kicad:LED0805-R-RDLED1
1TPS65131RGEReasyeda2kicad:QFN-24_L4.0-W4.0-P0.50-TL-EP2.6U9
1WJ15EDGRC-3.81-6Peasyeda2kicad:CONN-TH_WJ15EDGRC-3.81-6PCN1

The 76 most common of 80 parts.

Questions

How big is the PCB Interface PCB?

It measures 42.8 × 67.5 mm and has 4 copper layers, 1.36 mm thick.

What parts does the PCB Interface use?

80 parts, built around the LM324DT, TPS65131RGER, ZX-PM2.54-1-20PY and CESD3V3D3. 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 PCB Interface KiCad files?

From the Domfunkle/NHP_Synth repository on GitHub, at the commit this page was made from: the board is PCB_Interface/PCB_Interface.kicad_pcb and its schematic PCB_Interface/PCB_Interface.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the PCB Interface design in my own project?

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

Similar boards

  • 2 layers77 × 32 mmBananaSchplit, the printed circuit board in 3D

    BananaSchplit

    pms67/BananaSchplit

    Single rail DC (<12V) to split rail DC supply (+/-12V and +5V).

    53 parts66MIT
  • 4 layers100 × 100 mmPhmod, the printed circuit board in 3D

    Phmod

    gallicchio/AMOD-and-RFMOD

    The tutorial's 2x12 adapter (/mudd/133electronics/icepi-zero-dac-adc/adapterboard/) with a 2 x 6 right-angle Pmod socket on a 15 mm extension of its right-hand end, so an Icepi Zero can drive AMOD-A's and RF-MOD's Pmod…

    234 parts
  • 2 layers78.1 × 39.8 mmSingle to split rail dc power supply, the printed circuit board in 3D

    Single to split rail dc power supply

    kingMordred/single_to_split_rail_dc_power_supply

    PCB design using KiCad 10.0 for a single to split rail dc power supply, converting an input of +6V ~ +12V to a +5V rail or a +12V/-12V rail.

    50 parts
  • 2 layersFonte simetrica -12V +12V, the printed circuit board in 3D

    Fonte simetrica -12V +12V

    karistonf/template_kicad

    Some templates that are very useful for developing PCBs in KiCad

    23 parts1
  • 2 layers121 × 75.5 mmJlctest, the printed circuit board in 3D

    Jlctest

    cjheath/jlcbasic

    JLC Basic parts library for Kicad fetched and converted from EasyEDA

    46 parts5
  • 4 layers68.6 × 53.3 mmPcb main nautilus atmega4809, the printed circuit board in 3D

    Pcb main nautilus atmega4809

    apcountryman/pcb-main-nautilus-atmega4809

    A Microchip ATmega4809 based mainboard PCB.

    91 parts