Julia bindings for Digilent's WaveForms SDK — Analog Discovery, Digital Discovery, ADP and DPS hardware.
using WaveFormsSDK, Unitful
Device() do dev
scope = AnalogIn(dev)
configure!(scope[1]; enabled = true, range = 5u"V")
configure!(scope; frequency = 100u"kHz", samples = 4096)
trigger!(scope; source = TriggerSource.DetectorAnalogIn, level = 0.5u"V", slope = Slope.Rise)
data = acquire(start!(scope)) # 4096×2 Matrix of volts
endInstall the WaveForms application (which bundles the SDK), then:
] add https://github.com/notthetup/waveformssdk.jlThe library is located at load time: ENV["WAVEFORMS_DWF_PATH"] if set, otherwise
/Library/Frameworks/dwf.framework/dwf (macOS), libdwf.so (Linux) or dwf.dll
(Windows). isavailable() tells you whether it was found without throwing.
The SDK ships virtual devices that simulate acquisition, generation and even a W1 → 1+ loopback. The entire test suite runs on them.
devices(demo = true) # 11 virtual devices
Device(demo = "Analog Discovery 3") # open one- Channels are 1-based.
scope[1]is the first channel; the 0-based index the C API wants never surfaces. - Units in, units out. Any Unitful quantity of the right dimension is accepted, and a
bare number is taken to already be in the natural unit —
1u"MHz",1e6and1000u"kHz"are the same sample rate. Sample buffers come back asVector{...V};ustrip(data)aliases the same memory, so dropping the units is free. - Instruments are their channels.
AnalogIn,AnalogOutandDigitalOutareAbstractVectors, sofor ch in scope,length,mapand friends work. configure!batches. Each keyword is one SDK setter, but the whole call is a single device round trip rather than one per keyword.- Failures throw. Every SDK call is checked;
DwfErrorcarries the driver's message and the C function that produced it.
AnalogIn |
oscilloscope — configure!, trigger!, start!, wait, acquire, record |
AnalogOut |
waveform generator — standard and custom waveforms, AM/FM via node = |
AnalogIO |
supplies, references and monitors — supplies(dev), aio["System Monitor"][:Temp] |
DigitalIO |
static pins — dio[1], configure!(dio; outputenable, output) |
DigitalIn |
logic analyzer — acquire(la, UInt16) |
DigitalOut |
pattern generator — configure!(pg[1]; frequency = 1u"MHz", duty = 0.5) |
Devices trade buffer depth between instruments, and the choice is fixed at open. On an Analog Discovery 3 the AnalogIn buffer ranges 4096…32768 across six configurations:
info = only(i for i in devices() if i.name == "Analog Discovery 3")
configurations(info) # the table
Device(info; config = 1) # 32768-sample scope bufferSupply channels are found by asking the device, not by index — an AD3 reports V+/V-,
a DPS3340 reports Output 1…3, an ADP3450 reports only DVCC.
ps = supplies(dev)
configure!(ps["V+"]; voltage = 3.3u"V", enabled = true)
ps["V+"][:current]
reset!(ps) # clears a latched overcurrent tripclose(dev) stops the instruments by default, rather than inheriting whatever the
WaveForms GUI last set. Use onclose!(dev, :continue) to leave outputs live, or
:shutdown to power the device down. closeall() runs at exit; the do-block form of
Device closes on the way out either way.
Measured on an Analog Discovery 3 (rev 3, SDK 3.23.4) — things the API cannot hide:
- Supply rails ramp. Reading a supply back immediately after setting it returns a mid-ramp value. A 1.8 V → 3.3 V step reads 3.20 V at 250 ms and settles to 3.31 V by 500 ms. Sleep before you assert.
recordloses samples if you outrun USB. Two channels stream cleanly at 100 kHz; at 20 MHz roughly a third are lost. Losses leave a gap — the returned rows are no longer evenly spaced — sorecordthrowsSampleLossunless you passonloss = :warnor:ignore.- One process at a time. The WaveForms GUI holds the device exclusively;
Device()will tell you so rather than failing obscurely. AnalogInre-enables channels on start, soacquirereturns every channel rather than trusting the enable flags. Useacquire(scope[1])for just one.
Protocol engines (UART/SPI/I²C/CAN/SWD), the impedance analyzer, FDwfSpectrum*
(DSP.jl and FFTW.jl do it better), FIR/IIR channel filters, 16-bit raw status readers,
compressed digital capture, and 64-bit DIO masks for Digital Discovery's 40+ pins.
] test WaveFormsSDKRuns entirely on demo devices; skips with a warning if the SDK is not installed.
examples/wavegen_loopback.jl is the hardware smoke test — wire W1 to 1+ and run it with
WAVEFORMS_HW=1.