Arduino Waveform Generator

Picture of Arduino Waveform Generator
function generator_schem.png
Screen shot 2012-11-29 at 12.32.37 PM.png
Waveform generators (also called function generators) are useful for testing and debugging circuits.  I often use them to test the frequency response of electronics components like op amp and sensors.  This waveform generator is powered by an Arduino.  It outputs four waveshapes: sine, triangle, pulse, and saw, each waveshape ranges in frequency from 1Hz-50kHz.  The frequency, pulse width, and overall amplitude (gain) of the waveforms is controlled by three potentiometers.  I've also included (optional) indicator LEDs that let you know which type of wave is currently being sent to the output.

Parts List:

(4x) Mini SPST 1.5-Amp Momentary Pushbutton Switch (2 packages) Radioshack #275-1556
(8x) 10K Ohm 1/4-Watt Carbon Film Resistor  (2 packages) Radioshack #271-1335
(9x) 20K Ohm 1/4-Watt Carbon Film Resistor (2 packages)
(1x) 50K-Ohm Linear-Taper Potentiometer Radioshack #271-1716
(1x) 10K-Omh Audio-Taper Potentiometer Radioshack #271-1721
(1x) 10K-Ohm Audio Control Potentiometer with SPST Switch Radioshack #271-215
(1x) 1/8" Stereo In-Line Audio Jack Radioshack #274-274
(1x) 10.01µf 50V Ceramic Disc Capacitor Radioshack #55047551
(1x) 4.7K Ohm 1/4-Watt Carbon Film Resistor Radioshack #271-1330
(1x) 8 Pin Socket Radioshack #276-1995
(1x) LM386 Low Voltage Audio Power Amplifier Radioshack #276-1731
(2x) 220µF 35V 20% Radial-lead Electrolytic Capacitor (or anything between 200 and 300 uF) Radioshack #272-1029
(1x) Arduino Uno REV 3 Radioshack #276-128
(1x) Arduino Proto Shield Radioshack #276-140
(4x) White Super-bright LED Indicator Radioshack #55050633
(4x) 740 ohm 1/4W 5% Carbon Film Resistor (1 package) Radioshack 271-1317
(1x) 300Ohm resistor

Additional Materials:

Heat Shrink Radioshack #278-1611
22 Gauge Wire Radioshack #278-1224
Solder Radioshack #64-013
Hot Glue
Black diffusor material (tissue paper, plastic, etc)
Remove these adsRemove these ads by Signing Up

Step 1: Prepare Arduino Proto Shield

Picture of Prepare Arduino Proto Shield
IMG_1779 1.JPG
IMG_1781 copy.jpg
IMG_1783 copy.jpg
IMG_1782 1.JPG
The Arduino Proto Shields are a convenient way to attach circuits to an Arduino, but I like to trim them down a little bit first so they do not take up so much room in the project enclosure.   Start by trimming the pins down with a pair of wire cutters.  Next, cut off the six pin socket.  Finally, cut the sockets from the top of the board.
1-40 of 106Next »
hemalchevli made it!21 days ago

Here is my version. I made a standalone system, no shields, blog

amandaghassaei (author)  hemalchevli20 days ago
TAGAPAW3 months ago

can i use this method to make a synth :)

amandaghassaei (author)  TAGAPAW3 months ago

yes it could be a starting point, that was my thought

maxwelljets5 months ago

When I open these files, all I see is a box. I don't see any of the laser cuttable panels. Could you please make these available, or, alternatively, if they are there and I'm just not able to see them, could you please show me how to access them?

amandaghassaei (author)  maxwelljets4 months ago

try the .cdr, you may have to instal corel draw.

Are the resistors for the four LEDs 740 ohm or 470 ohm? The instructions and part list are inconsistent so I'm not sure.

It doesn't really matter.

Everything between 100 and 1k ohm will do the job.

sorry about that, anything between 220 and 1k is fine, I think I actually used 470.
cyates35 months ago

First, I love your instructables! I was interested in making a barebones "arduino" with just the ATMEGA328 chip and the additional electronics necessary to run this device. I looked at some other DIYs but they're all aimed at making a complete arduino, which costs as much as or more than an uno these days. Do you have any suggestions?

amandaghassaei (author)  cyates35 months ago
hope that helps!
TeslaRox1 year ago
How can one make this able to drive a flyback transformer. I know there is a way to do it, a vid of a guy on youtube does it but doesn't show how. I ordered a DDS function generator and just cant put 2 and 2 together to figure out how to drive a flyback with it and I would like to be past this.. simple set back.

You'd need to have a high current transistor in line with the primary coil of the flyback, and use the generator to drive the base of the transistor.

Kris Jacobs6 months ago

Hello Amanda, thank you for this Instructable. I just got my Rigol DS1102E this week, and this is the first thing I'm using it on.

That said, I think your capacitor value for the low-pass filter is off by a factor of ten -- when I do the calculation for a cutoff frequency of 50kHz, I get 1nF (0.001uF) -- not 10nF (0.01uF).

When I work the formula backwards with your capacitor value, I get a cutoff frequency of 5kHz.

Does that make sense? Thanks!

Ahhhh! Nevermind - my software tool was choosing 1nF with a 3.3k ohm resistor when I told it I wanted a 50kHz cutoff.

When I did it backwards in the tool to solve for frequency, I was telling it to use a 330 ohm resistor.

I'm all good - figures I screwed up - old brain, too much beer. ;)

amandaghassaei (author)  Kris Jacobs6 months ago
No worries!
Drumroll6 months ago

Thanks a lot for this tutorial, I wanted to try this to get some insight of arduino. I made the electronics for this but im really new to arduino. Could you possibly give me a hint how to change the interrupts to get The code running on a Mega 2560? Thanks!

xenonion6 months ago

Hello Amanda,

Thank you for putting this together it is great code! I have a few questions about this. I am only interested in a single square wave, and have been able to modify the code to do this. However, I am having a hard time navigating the interrupts to do other functions. Namely, I would like to put a delay held on a specific output and then start the generator. Will this be possible or do you have suggestions on which direction to go?

Thank You!

amandaghassaei (author)  xenonion6 months ago

yeah delay() will get messed up by the interrupts. If you're only interested in square waves, then I would check out the tone library, I think they might have solved that problem.


Thank you for the reply. The tone library doesn't have variable amplitude capability which I need for my application. Any suggestions?

Thank You.

amandaghassaei (author)  xenonion6 months ago

use an amplifier set up like this, use a pot to replace r2, then you can control amplitude with a potentiometer. If you need to create a signal that's less than 5V use a voltage divider instead.

RodCastler9 months ago
Hi Amanda, will the output range between 0 and +9V? What if you needed it to center the oscillation at zero volt for component signature testing for example? Good tutorial, thanks!
amandaghassaei (author)  RodCastler9 months ago
it will range between 0 and whatever voltage your amplifier can get to. it could definitely be amplified above 9v. I'm not exactly sure what component signature testing is, can you explain?
Sorry, I meant voltages in the positive range (oscillate between 0v and +whatever). Component testing requires AC, which means oscillate between for example +12V and -12V (or 12VAC for that matter). What needs to be changed in this project at the software level (or maybe at the amplification stage) for this to provide AC? (PS: For more on component signature testing search for "Simple Component Tester" on youtube and click on the first result you get).
amandaghassaei (author)  RodCastler9 months ago
the arduino only outputs positive voltages between 0-5v, you'll need to dc offset by -2.5V to get +/-2.5 and then amplify to +/-9v
alan5061 year ago
I still got an error after selecting the correct board, the error is
"avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_command(): failed miserably to execute command 0x13
avrdude: stk500v2_paged_write: write command failed
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_command(): failed miserably to execute command 0x1d
avrdude: stk500v2_cmd(): failed to send command
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_command(): failed miserably to execute command 0x1d
avrdude: stk500v2_cmd(): failed to send command
avrdude: stk500v2_ReceiveMessage(): timeout
I have searched this error on the internet and people said this problem related to timer interrupt. But I really don't know how to fix it as i am not an expert of arduino. Can you help me?
have the same problem. Do you have the correct code now?
amandaghassaei (author)  alan5061 year ago
the mega and the uno use different ic's. you will either have to read the documentation for the mega and rewrite my interrupts to work with a mega, or use an uno.
Soyuz409 months ago
Hi Amanda,
I'm very excited about this project, but I have a question:
Will it work any better with the new(er) Due board because of the much higher sampling rate?
amandaghassaei (author)  Soyuz409 months ago
the Due has a completely different processor, so the interrupt stuff will not work. You can do it on a due, but you will have to figure out how to create timer interrupts for that.
Pythag10 months ago
Hi there; this has been a great project so far!

I just wanted to ask about one hiccup im having. For some reason, the signal coming out from my amp is clipped clean in half, only going up to about half the voltage it should be before just flattening off. The signal coming into the amp is nice and clean, and im fairly sure ive got everything wired up with the same components you used, although my amp is an lm386n-1; do you suppose that could be what's making the difference? I couldnt find anything different about it's specs, but I'm really just a beginner, so I wouldnt know for sure.

Anyway, thanks for a brilliant tutorial!
Pythag Pythag10 months ago
Ah, my mistake actually; got confused with the AC readings from my oscilloscope. It actually is getting the full voltage from the amp, but it's still clipping. I put 3 20k resistors in series with the frequency coming from the arduino, and it's fixed the clipping, but it hardly seems an ideal solution. Is there something else I could be doing to lower the gain on the amplifier?
amandaghassaei (author)  Pythag10 months ago
what op amp are you using?
amandaghassaei (author)  amandaghassaei10 months ago
oh i see, a lm386. you should wire it up like this:
cgarzon10 months ago
Hello Amanda:
Excellent project, Do you have any idea on how to build all this generator but without the pots? I mean, only computer controlled with an ethernet shield or maybe a netduino?
amandaghassaei (author)  cgarzon10 months ago
yeah it's definitely possible. you will have to use software serial to do serial communication over pins other than digital pins 0 and 1 since they are already being used in the dac:
alternatively, you could get a mega and use one of it's other serial ports.
basically you need to update the frequency and pulseWidth variables via serial instead of analogeRead()
dadavincicode11 months ago
Can you clarify the op amp configuration? You use 2.2k on one schematic and 4.7k on the other. Does it matter? Also, does this circuit work with any regular off-the-shelf opamp?
amandaghassaei (author)  dadavincicode11 months ago
do you have a rough estimate on price? and is there a way to shift the freq range? for example i need something along the lines of 0.1-100Hz. also, is there a way to somehow make this programmable to include duty cycle information? like if i wanted a square pulse for something like 2 sec on, 1 sec off etc?

and lastly, what are the maximum outputs in terms of V and I? I'm trying to build something that'll be able to swing 20Vmax and 10Amax.

sorry for the lotsa questions!
amandaghassaei (author)  alexandrubenza1 year ago
including the arduino, maybe $50. Yes you can make those adjustments, but you'll have to learn about how the code works to do that. You will need external amplification to get the power output you are looking for, the Arduino does a max output of 5V and ~40mA, the amp i suggest using supplies slightly more current, but not anything near 10A
1-40 of 106Next »

Get More Out of Instructables

Already have an Account?


PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!