The problem is that your memory in your arbitrary waveform generator is too small to store the waveform. Also, they chose a strange format for arbitrary waveforms. Seems to me they had pretty specific waveforms in mind when they designed how waveforms are stored!
So, as Neil very correctly points out your problem is universally solved when you get a DAC and attach it to something that feeds it with digital samples: you can truly generate any arbitrary waveform (given that it is low in bandwidth enough to fit through the reconstruction filter at the output of the DAC).
The good news is that you don't need an FPGA board (and learn how to use the tools and languages to design a digital implementation of how to get the samples to the DAC for an FPGA), because your bandwidth is pretty low: You end at approximately 2 MHz, and if we wanted to produce any waveform that has energy between 0 and 2 MHz, the Nyquist-Shannon Sampling theorem tells us that any sampling rate > 4 MHz suffices to fully represent the signal.
Due to how hard it is to filter in analog, you would want to higher than the critical 4 MHz, to at least 5 MHz sampling rate.
If you can then feed samples directly from a PC into the DAC at that rate, you'd be fine!
So, you'd need roughly this:
+----Device----------+ +------------+
+--------+ | | | Low-Pass |
|software| | +--------+ +-----+ | | Filter |
|running |---------->|-| Buffer |-| DAC |-|-------->| |------> Analog out
| on PC | | +--------+ +-----+ | | (recon- |
+--------+ | | | struction) |
+--------------------+ +------------+
USB or
similar Buffer because Reconstruction
bus computer will deliver Filter:
data in packets, so DAC produces
need to make sure DAC "images" (copies)
doesn't rum "dry" on of signal spec-
samples. trum at multiples
of sampling rate.
You only want the
O Hz–2 MHz image,
not the F_sample
to F_sample+2 MHz
copy. Hence, you
filter out every-
thing above 2 MHz
OK, I trust you can throw together a 2 MHz low-pass filter (using an opamp, one to three resistors and a capacitor), but you wouldn't want to build Device
from this figure.
Luckily, you don't have to; such things are commercially available. They exist in the shape of Software-Defined Radios (like, say, an Ettus N210 with a LFTX daughterboard), or, even simpler: USB VGA adapters!
VGA is an analog signal, high bandwidth, and for each of the red, green and blue signals, amplitude of the signal on the cable pretty much the brightness of the color on the screen, when you scan the screen in a zigzag pattern. Now, every PC has its pixels in digital form, so there's a DAC in your good olde graphics card that takes a stream of digital brightness values and converts them into a continuous stream of analog brightness signal. Most USB cards won't let you just stream pixels as to be directly played back via the DAC – instead you write the pixels to a Buffer, and then there's logic that reads the buffer, adds blanking samples to the end of each row and at the end of each frame (because VGA monitors had to reposition a beam at that point).
But: there's at least one class of very cheap USB-to-VGA "adapters" that puts the whole task of precomputing these values on the CPU of the host computer and just let that stream continuously samples as to be directly converted to analog by the hardware.
"FL2000 based devices" by steve-m, on the osmocom wiki, CC-by-SA 3.0
The osmocom osmo-fl2k
project has written a driver for that so you can directly just send samples of your desired waveform to the frontend!
It's relatively easy to use. You'll need cmake
and a C compiler (GCC, clang) and libusb
(which exists for everything from Linux to Windows and Mac).
git clone https://osmocom.org/projects/osmo-fl2k/wiki/Osmo-fl2k osmo-fl2k
cd osmo-fl2k
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=$HOME/prefix
cmake --build build
That installs the fl2k_file
tool. It's easy to use:
build/src/fl2k_file -s 8e6 signal.samples
to play back the samples in the file signal.samples
at 8 MS/s. (If I remember correct, the samples are simply signed 8-bit integers, so trivial to produce using numpy
or your favourite programming language)