Function Generator

A decent function generator is one of the most important pieces of equipment any electronics tinkerer can have on his workbench. A decent function generator is also a piece of equipment that could set you back a pretty penny. It’s hard to spend less than $200 on an off-the-shelf sine-wave generator of any kind, let alone one with continuously-variable frequency, triangular and pulse waveforms, variable duty-cycle, and DC offset controls. For an experimenter on a budget, those cheesy signal generator apps for iOS and Android are probably looking pretty attractive right now.

Of course, sine waves are notoriously difficult to generate in a friendly manner. Making your own function generator is never as straight-forward as you think. You always need some obscure part, like a thermistor, or need to drive a lamp with a tiny power amplifier, or need to use a dual-gang pot with good tracking to get a sine wave that is stable, has low distortion, and can sweep over a decent frequency range. The goal of this project is to provide a usable (if not quite commercial-quality) function generator for your electronics bench out of cheap, readily available parts.

The Circuit

At its heart, this circuit is a standard integrator-comparator oscillator. X1A is an integrator, while U1A and U1B make up a non-inverting comparator with hysteresis. The output of the comparator is sent through a voltage divider and then buffered by U1B, providing a constant charging (or discharging) current for C1, which generates a ramping up (or down) voltage at the output of U1A. This charging/discharging cycle, produces a triangular waveform at the output of X1A and a pulse waveform at the output of X1B

I know I could have used another opamp stage instead of the double inverter shown, and it could have saved an extra chip, but using CMOS has one big advantage. CMOS output swings rail-to rail, and is stable over a very wide frequency range. When an opamp comparator uses positive feedback to set up hysteresis, the transition voltages are dependent on the opamp’s output swing, which is affected by the frequency of operation. The triangular waveform is bounded by the hysteresis of the comparator, and the quality of the sine wave is highly dependent on the amplitude of the triangular waveform. Using a CMOS gate ensures that you can have a nice sine wave at 100Hz, and also at 10kHz. 

VR1 controls the frequency of the oscillator, and with the resistor network shown, should provide just over one decade of frequency range, so that there is a little bit of overlap between ranges. Using a linear pot, resistor R2 provides a roughly logarithmic frequency sweep, and sounds more natural to the ear than a linear sweep would. VR2 allows you to vary the symmetry of the charging and discharging of C1, providing a variable duty cycle on the pulse output, or a range from sawtooth to triangle to ramp output with the triangular waveform, and a skewing ability for the sinusoidal waveform.

But what you are really here for is a sine wave. I searched high and low for reliable sine wave generation techniques, and the logarithmic distortion of a triangle wave kept coming up as a cheap, relatively simple, and stable option. Check out Ray Wilson’s many examples of using an OTA to achieve the same result, or look at this application note from TI for a pretty comprehensive list of the most common alternatives, and the advantages and disadvantages of each method.

In all honesty, I don’t fully understand how the triangle to sine wave shaping section of this circuit works. The basic idea is to drive the long-tailed pair into non-linearity, rounding off the peaks of the waveform… or something like that. With the values shown, you should be able to get a very nice, very low distortion sine wave with single-turn trimpots. Connecting the circuit output to an amplifier and speakers, you can get the distortion down to a few percent THD, by fiddling with the trimpots, but really low distortion will require an oscilloscope and some patience. TP1 controls how much the peaks of the triangular waveform are rounded off, and TP2 controls the symmetry of the waveform. I won’t get into it here, but will instead direct you to an ESP project that goes into great detail on accurately measuring low level distortion on sine waves.  Using this method, I was able to get my oscillator down to 1.4% distortion, but I am not very patient. Your mileage may vary. 

Output Section

The raw sine, triangle, and square waves produced by this oscillator are have different amplitudes. Resistors 14, 15, and 16 set up the gain for X2A to keep the peak-to-peak voltage roughly equal when switching between the different waveforms. VR3 sets the output amplitude, and VR4 allows you to adjust the DC offset of the output. You can use a linear or log pot for VR3, depending on whether you want it to be an “Amplitude” control, or a “Volume” control.

With the 6V supply rails shown, the full output swing will be nearly ±5V. If you want to be able to heavily clip the waveforms, you can either use a larger value pot (250k or 500k) in place of VR3, or use a higher value resistor for R19.

The TTL output is open-collector, so it can be used with any logic voltage up to 40V. It does a double inversion, so that the duty cycle is proportional to the rotation of VR2, and should provide much sharper pulse transitions than the normal output.

Power Supply

The power supply for this circuit was dictated by what I had on hand, and a few compromises. The maximum supply voltage for the CD40106 is 15V, I had an LM7812 voltage regulator, a 15V wall wart, and an extra opamp section available. The signal ground is the virtual earth provided at the output of X1D, and should be connected to the chassis of your chosen enclosure. (You are using a shielded case, right?)

THE NEGATIVE TERMINAL OF YOUR DC POWER SUPPLY MUST BE INSULATED FROM SIGNAL GROUND. If you use a metal enclosure, you will need to use a DC power jack that insulates the negative terminal from the chassis.

Of course, you are also free to make your own true bipolar power supply, or to only AC couple the output, and use the negative supply as ground. Just be aware that the power supply needs to be regulated to keep sine wave distortion low.

The power supply voltage really isn’t critical to this design, but it does affect the frequency of the oscillator and the amplitude of the waveforms. The opamps can only slew so fast, so a lower supply voltage will ultimately increase your maximum operating frequency. A supply voltage other than ±6V will need to be breadboarded to make sure that your frequency ranges overlap, and that TP1 provides enough range to properly tune your sine wave.

Layout and Construction

it’s ugly, but hey, it’s a prototype

The layout isn’t super critical, but be careful to keep pulsing currents away from other parts of the circuit when possible. I had the wires running to S2 from the PCB all twisted together when building my prototype. It kept the wiring tidy, but resulted in ugly spikes at the peaks of my sine and triangle waveforms.

Here is a ready-to-print PDF for making a toner-transfer PCB. In the interest of small board size, it is meant to use wires for off-board connections to the pots and switches. With the layout shown, you can have a single capacitor always connected, and/or up to three different capacitors to switch between. I used an 8-pin DIP socket in place of C1, so I could try out different values to get my ranges correct, and then solder them to the socket. This setup allows for one capacitor to be either by itself, or in parallel with one of up to three other capacitors.

If you only wanted two ranges, you could put a 150pF cap in the rightmost slot, a 1.2nF cap in another slot, and an SPST switch between them. This would give you a low range with the switch closed, of 100Hz to 1kHz, and a high range when open, of 1kHz to 10kHz, which is plenty for most audio applications.


My capacitor choices were based on what I had on hand. I put a 7pF capacitor (two 4.7pF in series, with a third in parallel) in the righthand slot on the PCB, with 147pF (100pF in parallel with 47pF), 1.5nF, and 15nF in the other spots. The 7pF cap is always connected, and it is either by itself or in parallel with one of the other capacitors. The ranges that result are:

15nF7Hz – 110Hz
1.5nF74Hz – 1.12kHz
154pF680Hz – 10.3kHz
7pF8.28kHz – 88.5kHz

And here are some examples of the output it is capable of.

sine wave

distortion residual before adjusting TP2

sine wave trimmed for minimal distortion

sine wave distortion residual

Note how much of the fundamental is still present in the distortion residual. My twin-T filter was made up of 1% resistors and off the shelf caps, and built on a breadboard, so the depth of the filter is suspect. The actual distortion is probably a little under 1%, but I didn’t feel it was worthwhile to get an exact measurement. There is no skew-defeat option in this circuit, and the pulsing currents really want to couple over to the sine wave signal path, so the sine-shaping distortion will almost always be swamped out by other distortions.

peak of the sine wave up close. Not quite perfect, but impressive when you consider this is coming from a triangular waveform.

sine waves skewed, and with DC offset

triangle, sawtooth, and ramp waveforms

square, and pulse with min/max duty cycle

I forgot to get screenshots of the TTL output. I will add some in the next day or so.

My DSO Nano isn’t fast enough to get a really clear image of what is going on at the highest frequencies, but my old analog scope was able to give me an idea of the quality of the output.

sine wave, 88kHz

square wave, 88kHz. Clearly, this is pushing the TL072/4 to the limit.