DIY Function Generators: On DACs, Performance and Cost

After acquiring an oscilloscope, the first thing an electronics hobbyist wants to do is take it for a spin. With the wide availability of cheap microcontrollers and an assortment of analog electronics, this is actually not too hard. But an oscilloscope, no matter how fancy, is in essence just a tool to look at electronic signals in the time domain. It may be used to observe the frequency response of filters, the step response of PCB traces or other not-so-ideal behaviour of the non-ideal components that we are plagued with in the real world.

A great tool to aid in all this is the trusty old function generator. But, after spending a lot of money on an oscilloscope, buying a function generator may not be the first thing you want to do. After all, your wallet may never trust you again after that. So, you might consider designing and building one yourself. In this post, I will describe the up- and downsides of building such a device, discuss some components that are available to do so and the cost of such a device.

Just a DAC?

You may think that building a function generator is as simple as hooking a DAC up to an Arduino or other microcontroller and calling it a day. Some Instructables and projects on other blogs certainly do make it seem that way. Are they wrong? Well, not entirely.

It depends on your requirements. Take the very popular AD98331Find the datasheet here module2For example, this one with SMA jack mounting point here, for which there are quite a few DIY instruction examples, which generally are of the hook-it-up-and-you’re-done type. That is not to say that those DIY projects are not great or worth the effort, they may certainly be. In fact, I have been working on a similar device, which I hope to present in a future post.

However, there are important limitations to most of these designs. The first, and in my opinion the most important one, is the lack of signal conditioning. The signal from the AD9833 is always DC-coupled and in the case of the sine and triangle waves the output voltage is only about 600mVpp. This does not make it useless by any means, but having an adjustable amplitude and offset is almost as important as the ability of changing the frequency of a signal.

On top of this, the AD9833 is not capable of driving a wide variety of loads because of its limited internal buffer. Moreover, due to generally limited production quality of such function generator designs, the bandwidth is not always limited by what the DAC can provide but by what the connections within the device allow3All wires, PCB traces and other connections have transmission line behaviour and thus act as filters for high-frequency signals..

So, a proper function generator is not just a simple DAC controlled by a microcontroller. However, within their limitations, these devices can still be very useful for a wide variety of measurements that you may want to do as a hobbyist.

Arbitrary Waveforms

Any design based on the AD9833, AD98504Find the datasheet here or another similar device that features some sort of control interface to select between a set of pre-programmed waveforms misses the ability to create arbitrary waveforms. These arbitrary waveforms may not sound important at first because most examples shown in the internet are just wiggly lines drawn on a Canvas in a user interface. Still, arbitrary waveforms may be used for so much more. You may be able to use it create particular PWM pulses to control, say WS2812 RGB LEDs5Also known as NeoPixels or a (low-frequency) AM or FM modulated signal. These signals may be defined in a binary format and created using MATLAB, Python or some other tool you prefer.

Maybe even considering all this arbitrary waves don’t sound like your cup of coffee. If that is the case, then you may certainly be able to satisfy yourself with just the AD9833-or-similar-based solution. If not, then read on to find out how you may be able to still build a function generator capable of creating them, and whether it’s worth it.

FPGAs vs Microcontrollers: Controlling DACs

One of the important metrics in generating arbitrary waveforms is the sampling rate. The sampling rate in part determines the maximum frequency component of the arbitrary waveform generated, the rise time of possible steps in the signal and how smooth the signal looks at the output. If the sampling rate is low compared to the maximum frequency component of the wave you wish to create, a lot of harmonics will appear, distorting the signal, which, depending on the signal conditioning after the DAC may not do you any favours at the output of the function generator.

Finding a DAC with a high sample rate is not the hardest part. The hardest part is sending the data reliably to the DAC at the high rate. An Arduino Uno Microcontroller running at 16MHz will never be able to control a DAC with a sample rate of 100MSps at its maximum frequency. That is why most commercial function generators make use of FPGAs6If you are not familiar with the term, AllAboutCircuits has a great short explanation instead. These devices are often quite a bit more difficult to program and control, especially when combined with other hardware components like in the Xilinx Zynq series.

Take the MHS-5200A for example. It features a Lattice FPGA with a simple R2R ladder7A technical but very readable and usable explanation may be found here to create a DAC. The design actually also includes a microcontroller8As may be seen on the Sigrok page for it. It is just not used for the actual signal generation, because the STM8 running at 16MHz is not capable of the required 200MSps data rate.

Some microcontrollers are capable of such data rates though. Take the BeagleBone Black9A capable single-board computer of which the unique selling point is the two Programmable Realtime Units, like Arduinos on steroids for example. The BeagleLogic project that turns it into a 100MSps logic analyzer may be modified to make it control a high-speed DAC instead. With the 8k of shared RAM available for samples, it could actually be a very neat little device. BeagleLogic has been modified for other purposes before10Find the awesome PRUDAQ project here, so it is not outside the realm of possibility11The amount of time jitter (the accuracy of the clock signal in the device) might limit the purity of the output signal if the clock source is not accurate enough..

Bandwidth and PCBs

The bandwidth of the basic function generators without signal conditioning is generally limited by the quality of their assembly. As soon as signal conditioning is applied with op-amps and maybe PGAs12Programmable Gain Amplifiers are amplifiers of which the gain may be controlled, like the very-fun-to-play-around-with MCP6S2x or the fancy AD8253 or attenuation stages, other factors start to influence the frequency and step responses. I won’t pretend to be an an expert or even a novice on this subject, as I’m still doing research into this area, much in the same way as I did research that led to this post.

What I have concluded already, though, is that in order to achieve a nice bandwidth to the output is that at least a four-layer board is required to optimize the behaviour of the traces as transmission lines. If you want to learn more about this topic, I recommend going over the literature made available by Texas Instruments on the topic here, here and here. There are other sources out there, but that’s going off-topic for this post.

The main point for now is that designing a four-layer PCB for properly carrying analog signals is not only much more difficult than a simple two-layer board for your average Arduino project, but it is also more costly. This leads us nicely into the conclusion of this post.


Considering that building a proper function generator is quite a complicated and expensive endeavour, it is not always worth it to design and build your own. After all, if you are looking for a usable, functional piece of test equipment then given the price for which low-end models are available, there are some great value options out there. Considering that they generally contain at least an FPGA, some high-performance analog circuitry and at the very least a good amount of solid engineering -well, almost always -some of  the more popular and high-volume production devices are downright bargains for what they offer.

However, if you are looking for a fun project to work on and dip your toes in the water when it comes to analog electronics, then I think that building your own function generator, no matter what components and architecture you choose to use, is definitely one of the more challenging and fun options. Building a device with the signal quality of a commercial device or the sample rate is not something you can expect if you are still learning things, but that isn’t, after all, the point of such a project.

This conclusion has led me to the decision to also try my hand at building a function generator. My first prototype is ready, and I hope to document it here soon. In the meantime, I recommend doing lots of research and reading datasheets to at least push the limitations of DIY function generators to the boundaries of what is possible for hobbyists.

Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.