Skip to the content
4 layers90 × 100 mmHarp.device.quad.dac, the printed circuit board in 3D

0364: This repository contains the hardware, firmware, and software related to the Harp quad DAC

Size
90 × 100 mm
Copper layers
4
Thickness
1.57 mm
Parts
291
Nets
177
Pads
1,009
Tracks, vias
1,665, 423
Pours
37
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
14 Aug 2025
Updated
30 Oct 2026

Overview

Harp.device.quad.dac is an open-source printed circuit board by AllenNeuralDynamics, from the AllenNeuralDynamics/harp.device.quac repository on GitHub, published under the MIT licence. It is a 4-layer board of 90 × 100 mm with 291 parts on 177 nets, routed with 1,665 tracks and 423 vias.

It is built around the INA630DDF, TPS65131RGE and W25Q16JVUXIQ, with the RT6150B-33GQW, SN74LVC2T45DCTR and ADUM4160BRW among its other parts. Its parts include 99 resistors, 92 capacitors, 31 ICs, 24 diodes and 18 connectors. It belongs with the audio and music boards and the RP2350 boards of this library.

Main components

12

README

README.md

harp.device.quac

hardware, firmware, and software source files for a Harp-compatible 4-channel Digital-to-Analog Converter.

Specs

  • Analog Output Channels: 4
  • Bit depth: 16-bit
  • Update Rate: 2.288 [KHz] to 500 [KHz] (selectable per-channel)
    • this is the rate at which a new output value is selected.
  • Voltage Swing: ±10 [V]
  • RMS noise at the zero voltage setting: ~±2.5 [mV]
  • absolute deviation from 0 [V]: ±2.5 [mV]
  • Power Input: 12-24 [V]
  • Power Input Plug: 2.1 x 5.5mm barrel jack (positive center)
  • External Trigger and Blanking (aka "Mute") option.
    • Any of the devices 4 digital inputs can be mapped to one or more Analog Outputs to either trigger or mute/unmute those channels.
  • Reverse Polarity protected.
  • Additional M4 ground lug provided for de-noising.
  • Open source hardware, firmware, and software.
  • Cost-effective at < $300 USD to manufacture a single unit.
  • Preview the hardware design online with KiCanvas.
  • Enclosure CAD Model

Trigger Specs

  • Trigger options
    • external trigger
    • software trigger
  • User-selectable external trigger mapping, i.e: any input trigger can be setup to trigger any number of analog output channels.
  • True simultaneous triggering in cases where multiple waveforms are triggered at the same time.

Waveform Player Specs

The device features 3 ways to play waveforms: either through the two built-in primitive waveform generators or by playing waveforms pre-uploaded to an SD card.

File Player Specs
  • Max Data Storage: limited by size of SD card
  • Max file length for a single file: 4GB
  • File names: user-specifiable with a 32-character limit.
  • Format: 16-bit Pulse Code Modulation (PCM)
    • -10 Volts corresponds to 0
    • 0 Volts corresponds to ~32768
    • 10 Volts corresponds to 65535

Harp Specs

The Quac board is a fully Harp-protocol-compliant device built on top of the Harp Pico Core.

  • Harp Device ID: 1411
  • Harp Events
    • Waveform Start (per-channel)
    • Waveform Finished (per-channel)

Alternates

The harp.device.quac board follows a legacy of many other devices that came before it. For similar devices, have a look at:

Ordering ➡ 💸

Order fully-assembled boards directly from PCBWay.

These printed circuit boards are made on-demand.

Generating Waveforms ﮩ٨ـﮩﮩ٨ـ

There are two ways to generate waveforms: either with one of two primitive waveform generators or by playing files from the SD card. These options are referred to as waveform Players.

Setting up and playing a waveform is a simple process for each Analog Output (AO) channel.

  1. Specify any external input trigger conditions for the output channel.
  2. Specify the waveform Player.
  3. Specify the Player's settings.
  4. Wait until the Player is ready (< 50[ms] of wait time for the player to apply the settings and arm the waveform).
  5. Trigger the Player either via software command or by applying external input to the corresponding external input pins.

For fully worked examples of the above steps, see the examples in the software folder.

[!NOTE] While waveforms on the SD card will remain on the card until they are deleted, Player settings for any Player do not persist across device power-cycles or resets.

Player Settings are detailed below for each Player.

Common Settings

The following settings are common to each Player.

  • cycles: number of iterations of the current settings (will probably be 1 in most cases).
  • duration_us: duration in microseconds to play the waveform or 0 to either play-forever (if the source is infinite ie: periodic functions) or play-to-completion (if the source is finite i.e: files on the SD card).
  • update_frequency_hz: rate at which samples are produced (max 500 [KHz]).

SinePlayer Waveforms

Settings
  • frequency_hz: sine wave frequency in hertz
  • amplitude_volts: "center-to-peak" amplitude in volts
  • vertical_shift_volts: vertical shift in volts
  • normalized_phase_shift: period shift normalized to -1.0 (max right shift) to 1.0 (max left shift)
Example Settings: play a 10Hz sine wave for 3 seconds
SettingValueNote
cycles1play the following settings once
duration_us3000000play for 3 seconds
update_frequency_hz10000rate at which to produce new samples
frequency_hz10sine wave frequency
amplitude_volts0.5result will be 1 [V] peak-to-peak
vertical_shift_volts0.5result will span 0 [V] to 1 [V]
normalized_phase_shift0no phase shift
Example Settings: play a 10Hz sine wave forever
SettingValueNote
cycles1
duration_us0play forever (until aborted)
update_frequency_hz10000
frequency_hz10
amplitude_volts0.5
vertical_shift_volts0
normalized_phase_shift0

TrapezoidPlayer Waveforms

Settings

(Inherits all Common Settings and Sine Player Settings)

  • ramp_on_us: time in microseconds to rise from lowest to peak value.
  • pulse_width_us: the total pulse width (including ramp-on and ramp-off duration of the waveform in microseconds.
  • ramp_off_us: time in microseconds to fall from peak to lowest value.

FilePlayer Waveforms from the SD Card 💾

Settings
  • path: filepath on the SD card (32-character limit max)
Example Settings: play a file once
SettingValueNote
cycles1play the following settings once
duration_us0play the file to completion
update_frequency_hz500000max update rate (might be different depending on file).
pathchannel_0.binassumes this file exists at the top level folder in the SD card
Example Settings: play a file multiple times
SettingValueNote
cycles3loop back and play the entire file 3 times
duration_us0
update_frequency_hz500000
pathchannel_0.bin

The quac board reads files in 16-bit little-endian Pulse-Code Modulation (PCM) format. There are a few options for generating waveforms in this format.

Upscaling Existing Files 💽

It's possible to convert existing audio files to a format compatible with the quac board using ffmpeg. To upscale an existing *.wav file to a 500KHz update rate, use:

bash
ffmpeg -i example.wav -f u16le -ar 500000 output.raw
With numpy 💻

For more complicated waveforms that do not derive from an existing audio file, we recommend using numpy.

Here's an example that generates the North American Ringing Tone, which is the sum of a 440Hz and 480Hz sine wave.

python
import numpy as np

NUM_SAMPLES = int(5e6) # 5 million samples @ 500KSs -> 10 seconds of data.
SAMPLES_PER_SECOND = 500000.
FULL_SCALE_RANGE = (1 << 16) - 1 # 16 bit resolution
SECONDS = NUM_SAMPLES/SAMPLES_PER_SECOND
FILENAME = f"channel_0.bin"

t = np.linspace(0, SECONDS, NUM_SAMPLES)
x = np.zeros(NUM_SAMPLES)

# make sine wave. offset it to uint16 range: 0-65535
for freq in [440, 480]:
    x += (np.sin(2 * np.pi * freq * t)+1)/2 * FULL_SCALE_RANGE/2

# Write result to file in 16-bit little-endian format.
with open(FILENAME, "wb") as file:
    x.astype("<u2").tofile(file)
Uploading Waveforms ♒︎➝💾

Currently waveforms must be uploaded to the SD card manually.

[!WARNING] Power down the device before removing or inserting the SD card.

Playing Waveforms 🎶

There are two ways to trigger a configured waveform to play: via software command or through the device's external triggers labeled DI0, DI1, DI2, and DI3.

Before triggering a waveform, you must

Software Triggering

For fully worked examples in both Bonsai and Python, see the software examples folder.

External Triggering

By default the device's power-on-reset behavior is setup to: setup external triggers such that pins DIO - DI3 correspond to playing output pins A0 - A3 respectively.

Trigger mapping is configurable! Any input trigger can be configured to trigger any number of outputs. To alter the trigger mapping, you must use software commands through either Bonsai or Python.

Compatible SD Cards 💾

During normal operation, up-to-four waveforms stored on the SD card are read (interleaved) at 4MB per second. With the extra overhead of switching between files, the SD card must be able to support read speeds ≥8MB per second. In theory, any Class 10 SD Card formatted in FAT32 format should be compatible.

But since card performance can vary, here's a list of tested cards:

VendorModel
SamsungPro Plus 8GB Smart Card
GIGASTONEIndustrial 8GB MLC

Working Principle

The following section details how the underlying firmware generates waveforms.

Selectable Player Architecture

Each channel features a modular approach to dividing up the work of playing waveforms.

The level closest to the hardware is a driver that wraps a custom PIO program to communicate over SPI to each LTC2641 DAC chip.

The next stage up is a shared double buffer and two DMA channels responsible for ensuring that the driver receives an uninterrupted, steady stream of bytes paced by a DMA Timer setup to match the user-requested playback rate. Inspecting the state of the double buffer is implemented by reading single registers native to the Pico's DMA peripherals to eliminate the need to implement mutex locks to check multiple locations in memory concurrently.

The layer above features one of multiple ways of generating data. These Players are responsible for producing a sequence of bytes up to the limits specified by the user's waveform settings. Each Player is derived from a base class that manages sending data to the corresponding available buffer from the downstream double buffer and manages sequence arming and termination.

In the full architecture, four copies of the above pipeline exist like so:

The MultiTransferManager connects to each double buffer and driver and handles triggering an armed transfer, and it guarantees that multiple simultaneous requests to start a transfer occur simultaneously.

FilePlayer Streaming Pipeline

Waveforms are read interleaved from their sources in "chunks" of 16384 samples at a time and then pushed into double buffers such that the resulting output plays waveforms concurrently without interruption.

Buffer size was selected to be large enough such that data from the SD card is can be read faster than it needs to sent to the downstream DAC drivers. This setup was tested in the worst-case scenario where 4 files are being read at once.

A single CPU core is dedicated to this task of reading waveform sources and topping off buffers while the other core handles Harp communication, settings configuration, and waveform start/stop inputs.

Updating the Firmware

New firmware is available on the Releases Page. To upload new firmware to the device, do the following:

  1. Ensure that the board is connected to a PC with the USB cable.
  2. Power down the board. (Note that power comes from the barrel jack, not the USB cable.)
  3. Power on the board with the BOOTSEL button held down. Then release the BOOTSEL button once the board has been powered up. The device will now appear on the connected PC as a flash drive. See the figure below to identify the BOOTSEL button. You may need to use a hex key to access this button with the case lid attached.

  1. Drag and drop the *.uf2 firmware file into the flash drive's top level directory. The flash drive should disappear indicating that the firmware upload worked. The device now has new firmware.

Known Limitations

Currently the device has some known limits, most of which are planned to be eclipsed by future firmware releases. This non-comprehensive list includes:

For a full list of issues, head over to the project's issues page.

Parts

291
QtyValueFootprintReferences
53100nFCapacitor_SMD:C_0402_1005MetricC10, C16, C17, C18, C19, C20, C21, C22, C23, C25, C26, C27, C29, C30, C31, C32 +37
2110KResistor_SMD:R_0402_1005MetricR1, R4, R5, R19, R22, R23, R24, R25, R26, R27, R28, R29, R30, R55, R56, R57 +5
16100KResistor_SMD:R_0402_1005MetricR59, R61, R62, R63, R64, R67, R68, R70, R88, R89, R90, R91, R92, R93, R94, R95
151KResistor_SMD:R_0402_1005MetricR2, R17, R18, R40, R41, R44, R45, R48, R49, R52, R53, R80, R82, R84, R86
14VBUS05N1-HD1-G3-08Diode_SMD:D_SOD-882D1, D2, D3, D4, D5, D6, D11, D12, D13, D14, D18, D19, D20, D21
12Conn_Coaxialkicad-lib:BNC_AmphenolRF_031-5329-52RFX_VerticalJ6, J7, J8, J9, J10, J11, J12, J13, J15, J16, J17, J18
1010uFCapacitor_SMD:C_0603_1608MetricC15, C63, C65, C74, C75, C76, C77, C79, C80, C81
831K6Resistor_SMD:R_0402_1005MetricR39, R42, R43, R46, R47, R50, R51, R54
747KResistor_SMD:R_0402_1005MetricR8, R9, R10, R11, R12, R13, R14
64.7uFCapacitor_SMD:C_0603_1608MetricC1, C2, C8, C13, C14, C64
66.8pFCapacitor_SMD:C_0402_1005MetricC43, C44, C45, C46, C70, C72
5100Resistor_SMD:R_0603_1608MetricR60, R72, R73, R74, R75
51uFCapacitor_SMD:C_0603_1608MetricC7, C24, C28, C48, C49
522uFCapacitor_SMD:C_0805_2012MetricC66, C73, C83, C84, C85
524Resistor_SMD:R_0402_1005MetricR3, R15, R16, R20, R21
5LOGOLOGOG***, G***, G***, G***, G***
40.05Resistor_SMD:R_0402_1005MetricR35, R36, R37, R38
418K9Resistor_SMD:R_0402_1005MetricR81, R83, R85, R87
41uFkicad-lib:C_Polarized_0805_2012MetricC3, C4, C11, C12
430KResistor_SMD:R_0402_1005MetricR31, R32, R33, R34
4INA630kicad-lib:TSOT-23-8U17, U18, U19, U20
4LMV393IDGKRkicad-lib:VSSOP-8_3x3mm_P0.65mm_TexasInstrumentsU13, U14, U15, U16
4LTC2642kicad-lib:MSOP-10_3x3mm_P0.5mm_AnalogDevicesU8, U9, U10, U11
4OPA2810IDGKTkicad-lib:VSSOP-8_3x3mm_P0.65mm_TexasInstrumentsU4, U5, U6, U7
4PESD12VL1BSLAZDiode_SMD:D_SOD-882D7, D8, D9, D10
4SN74LVC2T45DCTRkicad-lib:VSSOP-8_2.3x2mm_P0.5mm_TexasInstrumentsU22, U23, U30, U31
3FiducialFiducial:Fiducial_0.5mm_Mask1mmFID1, FID2, FID3
3Si2369DSPackage_TO_SOT_SMD:SOT-23Q1, Q2, Q3
227Resistor_SMD:R_0402_1005MetricR76, R77
24.7uHInductor_SMD:L_1210_3225MetricL2, L4
25-146281-3Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalJ1, J2
25.1kResistor_SMD:R_0402_1005MetricR6, R7
2CUS10S30,H3FDiode_SMD:D_SOD-323D16, D17
2LEDLED_SMD:LED_0603_1608Metric_Pad1.05x0.95mm_HandSolderLED1, LED2
110nFCapacitor_SMD:C_0402_1005MetricC68
1124Resistor_SMD:R_0402_1005MetricR78
113K7Resistor_SMD:R_0402_1005MetricR71
11K07Resistor_SMD:R_0402_1005MetricR79
11M05Resistor_SMD:R_0402_1005MetricR65
11M15Resistor_SMD:R_0402_1005MetricR66
12.2uHInductor_SMD:L_0603_1608MetricL3
1220nFCapacitor_SMD:C_0402_1005MetricC71
13.3uHkicad-lib:L_0806_2016MetricL1
139K2Resistor_SMD:R_0402_1005MetricR69
14.7nFCapacitor_SMD:C_0402_1005MetricC69
16.8uHkicad-lib:L_Bourns-SRP4030FAL5
1ADUM4160Package_SO:SOIC-16W_7.5x10.3mm_P1.27mmU3
1AudioJack3Connector_Audio:Jack_3.5mm_CUI_SJ-3524-SMT_HorizontalJ3
1BZV55B15Diode_SMD:D_MiniMELFD15
1Barrel_Jack_SwitchConnector_BarrelJack:BarrelJack_CUI_PJ-102AH_HorizontalJ14
1ECS-TXO-2016Crystal:Crystal_SMD_2016-4Pin_2.0x1.6mmXtal1
1LM2940IMPX-12/NOPBPackage_TO_SOT_SMD:SOT-223-3_TabPin2U27
1LM337_SOT223Package_TO_SOT_SMD:SOT-223-3_TabPin2U1
1LMR51430Package_TO_SOT_SMD:SOT-23-6U29
1Micro_SD_Card_Det_Hirose_DM3ATConnector_Card:microSD_HC_Hirose_DM3AT-SF-PEJM5J5
1MountingHole_Padkicad-lib:Terminal_Keystone_779x_EdgeMount_HorizontalH1
1REF2033Package_TO_SOT_SMD:SOT-23-5U21
1REF3525Package_TO_SOT_SMD:SOT-23-6U12
1RP2350_80QFNkicad-lib:RP2350-QFN-80-1EP_10x10_P0.4mm_EP3.4x3.4mm_ThermalViasU32
1SPST-NOkicad-lib:SW_Push_1P1T-SH_NO_Vertical_Wuerth_WS-TASVSW2
1TPD2EUSB30Package_TO_SOT_SMD:Texas_DRT-3TVS1
1TPD6E004kicad-lib:IC_TPD6E004RSERD29
1TPS65131RGEPackage_DFN_QFN:VQFN-24-1EP_4x4mm_P0.5mm_EP2.45x2.45mm_ThermalViasU25
1USB_C_Receptacle_USB2.0Connector_USB:USB_C_Receptacle_JAE_DX07S016JA1R1500J4
1W25Q16JVUXIQPackage_SON:Winbond_USON-8-1EP_3x2mm_P0.5mm_EP0.2x1.6mmU2
1https://github.com/AllenNeuralDynamics/harp.device.quacproject_lib:harp.device.quacQR*****
1rt6150b-33gqwkicad_component_library:WDFN-10-1EP_2.5x2.5mm_P0.5_EP1.25x2.1mmU24
1~Package_TO_SOT_SMD:SOT-23-6U26

The 285 most common of 291 parts.

Similar boards

  • 4 layers120 × 75 mmCuttlefish, the printed circuit board in 3D

    Cuttlefish

    AllenNeuralDynamics/harp.device.cuttlefish

    0414: an octal, TTL input/output device with programmable square wave output.

    195 parts
  • 4 layers70 × 168 mmValve controller, the printed circuit board in 3D

    Valve controller

    AllenNeuralDynamics/harp.device.valve-controller

    0368: a 16-channel valve controller

    224 parts
  • 4 layers80 × 50 mmHarp.device.lickety split, the printed circuit board in 3D

    Harp.device.lickety split

    AllenNeuralDynamics/harp.device.lickety-split

    0360: an ephys-compliant capacitive lick detector

    193 parts5MIT
  • 4 layers80 × 100 mmHarp treadmill, the printed circuit board in 3D

    Harp treadmill

    AllenNeuralDynamics/harp.device.treadmill-driver

    0326: a Harp-compatible device for controlling an instrumented mouse treadmill

    173 parts4
  • 4 layers80 × 50 mmSniff detector, the printed circuit board in 3D

    Sniff detector

    AllenNeuralDynamics/harp.device.sniff-detector

    0382: Signal conditioning board for an implanted thermistor

    114 parts3MIT
  • 4 layers39.9 × 28 mmEnvironment sensor, the printed circuit board in 3D

    Environment sensor

    AllenNeuralDynamics/harp.device.environment-sensor

    0357: harp-compliant humidity, pressure, and temperature sensor

    56 partsMIT
  • 4 layers80 × 50 mmUsb isolated, the printed circuit board in 3D

    Usb isolated

    AllenNeuralDynamics/harp.device.pico-template

    an RP2040-based Harp hardware/firmware project template

    76 parts
  • 4 layers180 × 110 mmPETER, the printed circuit board in 3D

    PETER

    dennowiggle/Retro-PETER

    3.3V Retro computer project => FPGA + RCBUS + CPU boards making a custom system.

    419 parts4LGPL-2.1

Questions

How big is the Harp.device.quad.dac PCB?

It measures 90 × 100 mm and has 4 copper layers, 1.57 mm thick.

What parts does the Harp.device.quad.dac use?

291 parts, built around the INA630DDF, TPS65131RGE, W25Q16JVUXIQ and RT6150B-33GQW. 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 Harp.device.quad.dac KiCad files?

From the AllenNeuralDynamics/harp.device.quac repository on GitHub, at the commit this page was made from: the board is hardware/harp.device.quad.dac.kicad_pcb and its schematic hardware/Block_Diagram.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Harp.device.quad.dac design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).