Arduino Waveform Generator Shield




About: I'm a Research Engineer at Adobe. Previously, I was a grad student at the Center for Bits and Atoms at MIT Media Lab. Before that, I worked at Instructables, writing code for the website and iOS apps and m...

Waveform generators (also called function generators) are useful for testing and debugging circuits. They can be used to test the frequency response of electronic components like op amps and sensors or to characterize and troubleshoot audio effects boxes and pedals. This waveform generator shield is powered by an Arduino. It outputs four waveforms: sine, triangle, pulse, and saw, each waveform ranges in frequency from 1Hz-50 kHz. The frequency, pulse width, and overall amplitude (gain) of the waveforms is controlled by three potentiometers. Four indicator LEDs let you know which type of wave is currently being sent to the output. This Instructable describes how to put together the Arduino Waveform Generator Shield Kit I designed, if you're interested you can also check out my original post about the Arduino Waveform Generator.

Parts List:

(x4) momentary push buttons Jameco 119011
(x3) linear taper 10kOhm potentiometer Jameco 286273
(x3) 0.25" knobs Jameco 136241
(x4) white LED Jameco 334502
(x4) 220Ohm 1/4Watt resistors Jameco 2157183
(x1) female header sockets Jameco 70755
(x4) male header pins Jameco 103393
(x1) LM386 op amp Jameco 24133
(x1) 8 pin socket Jameco 51626
(x11) 10kOhm 1/4Watt resistor Jameco 2157167
(x10) 20kOhm 1/4Watt resistor Jameco 691171
(x2) 220uF capcitor Jameco 606820
(x1) 2.2kOhm 1/4Watt resistor Jameco 2160981
(1x) Arduino Uno (Duemilanove is fine, but make sure it is ATMEL328P) Jameco 2151486
(1x) Shield PCB (Buy the shield and all the components here)

Additional Materials:
battery snap Jameco 109154
9V battery Jameco 198731
9V battery and battery snap or other power supply

This Instructable will show you how to put the Waveform Generator Shield together, if you want a more detailed description of the circuit check out my Arduino Waveform Generator Instructable.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Header Pins

Solder two groups of 8 and two groups of 6 header pins to the PCB.  Make sure to solder the header pins to the bottom of the board (the side that does not have any words).  Here are some tips to keep the pins straight while soldering them down.  The shield should fit nicely on an Arduino.

Step 2: Tact Switches

Press fit four tact buttons onto the side of the PCB, solder all four leads to the pads of the PCB.

Step 3: 8 Pin Socket

Solder one 8 pin socket to the part of the PCB labelled U2.  Here are some tips for soldering the socket on straight.

Step 4: 220uF Capacitors

Solder two 220uF electrolytic capacitors inside the large circles printed on the PCB.  Make sure to line up the negative lead of the capacitor with the "-" label on the PCB.

Step 5: 10kOhm Resistors

Solder 11 10kOhm resistors to the PCB.  Four of the resistors go in the spots labelled R1-R4 and seven go in R9-R15.  Remember, the orientation of the resistors does not matter.

Step 6: 20kOhm Resistors

Solder nine 20k Resistors in the spots labelled R16-23, R22, and R24.

Step 7: Voltage Divider

Solder one 20kOhm resistor in the spot labelled R28 and one 2.2kk resistor in the spot labelled R29.  (Note: the color bands of the 2.2k resistor in the picture are wrong, they should be red red red gold).

Step 8: 220 Ohm Resistors

Solder four 220ohm resistors in the remaining spots labelled R25-26, and R7-8.

Step 9: Potentiometers

Solder the three 10kOhm potentiometers to the spots labelled AMP, PULSEWIDTH, and FREQUENCY.

Step 10: LEDs

Solder four LEDs to the PCB as shown in the image above.  Make sure to line up the flat edge of the LED with the mark on the PCB.

Step 11: 9V Battery Snap

Solder the battery clip to the Vin and GND of the PCB as shown in the image above.  Also solder leads or female header sockets to the ground and signal pins of the board, these are your outputs.

Step 12: LM386

Press the LM386 into the 8 pin socket.  Make sure that the top of the IC (pins 1 and 8) are facing toward the potentiometers.

Step 13: Firmware

Download Arduino IDE and upload the code at the bottom of this step onto the Arduino.  The code uses a timer interrupt at a frequency of 100kHz to send new data out to the digital to analog converter (DAC).  The rest of the code monitors the state of the buttons and knobs and adjusts variables accordingly.  Since the interrupts occur at such a high frequency, I had to keep the interrupt routine, the piece of code encapsulated in the ISR(TIMER1_COMPA_vect){} as short as possible. Time intensive operations like mathematical operations with floats and using the sin() function take too much time to complete.  I used several work arounds to get by this:

For triangle and saw I created the variables sawByte, triByte, sawInc, and triInc.  Every time the frequency changed I calculated the amount that the triangle and saw function would have to increment at a sampling rate of 100kHz:

triInc = 511/period;
if (triInc==0){
   triInc = 1;
sawInc = 255/period;
if (sawInc==0){
   sawInc = 1;

then all the needed to be done in the interrupt routine was some simple math:

case 1://triangle
if((period-t) > t);
    if (t == 0){
        triByte = 0;
        triByte += triInc;
    triByte -= triInc;
if (triByte>255){
    triByte = 255;
else if (triByte<0){
    triByte = 0;
wave = triByte;

case 2://saw
if (t=0){
wave = sawByte;

For the sine function, I wrote a simple python script which outputs 20000 values of 127+127sin(x) for one complete cycle:

import math

for x in range(0, 20000):
    print str(int(127+127*math.sin(2*math.pi*x*0.00005)),)+str(","),

I stored this array in the Arduino's memory called sine20000[] and recalled the values I needed to send to the DAC.  This is much faster than calculating the values individually.

Step 14: Output

Turn up the gain knob and attach a nine volt battery to the battery clip (the LM386 needs 9V to work properly).  Hook up the function generator to an oscilloscope.  Test out each of the waveforms and adjust the frequency and gain to make sure they are working properly.  Switch the output to pulse and check if the pulse width modulation knob works (figs 4-6).  The LEDs corresponding to each waveform should light up as each waveform is selected.

You will notice that the pulse wave is the only wave which truly ranges from 1Hz to 50kHz.  Since the sampling rate is 100kHz, the sine, triangle, and saw waves start to become somewhat unrecognizable at about 25kHz (they are only comprised of 4 samples per cycle- 100kHz/25kHz).  The saw and triangle waves only go down to about 100Hz, this is because the values of triInc and sawInc get so low that they are rounded to zero below this frequency.  The sine wave reaches all the way to 1 HZ but the resolution stays the same for anything under 5Hz, since the Arduino only has enough memory to store about 20 thousand samples.

Step 15: Troubleshooting

In case your project is not working try the following:

Check for continuity- Review the schematic and board layout above and check your connections for continuity.  It's possible that you could have accidentally short circuited something or you may have a loose connection.  Especially check that everything which should be grounded is connected to the Arduino's ground.  Make sure that solder is flowing on both the top and bottom of the board on the ground pin of the output as there are connections on both sides of the board.

Check the path of the wave- Try to pinpoint the problem area by checking various junctions of the PCB with an oscilloscope.  If you probe either end of R27 you should see the waveform oscillating between 0 and ~5V.  At the junction between R 28 and the first 220uF capacitor, you should see the same wave centered around 0V.  Next check pin 5 of the LM386, again, you will see the waveform centered around 0V.

Reheat your solder joints- If you just can't find anything wrong right by inspection, it's a good idea to reheat all your solder joints one by one so that you are sure they are nicely connected.  This is a great strategy for troubleshooting any PCB that you might work on in the future.

Be the First to Share


    • Made with Math Contest

      Made with Math Contest
    • Multi-Discipline Contest

      Multi-Discipline Contest
    • Robotics Contest

      Robotics Contest

    32 Discussions


    1 year ago

    hi, any chance I can add a 16x2 LCD with/without I2C interface with the current design?


    2 years ago

    i can use this grt project in mine, bt i need 2 outputs (sine and triangular) can you tell what changes in ckt and code will be done.

    thanx in advance


    4 years ago on Introduction

    Am I mistaken or is there no schematic file included in the Eagle files zipped above? I see a picture of the schematic in the introduction though.

    If anyone knows where I can find the schematic and would let me know I'd be appreciative. I wanted to look into making some modifications to the amplifier, and it would same me some time to not backtrack through eagle to re-create it.


    5 years ago

    hey amanda. :) can i change the maximum frequency to 20Mz? is it possible? im making a project about waveform generator that generates from 20Hz-20Mhz can u help me? thanks good day.

    3 replies

    Reply 5 years ago on Introduction

    Hi amanda. So, the arduino can only generate about maximum of 16Mhz of frequency? What is the maximum amplitude that the arduino can produce?
    Can it have a 24Vpp of amplitude?
    Hoping for you response. Thanks a lot amanda.


    6 years ago on Introduction

    Is it ok if the buttons stay closed all the time because i want to make it with one of thoose rotary type switches i forgot their names?

    1 reply

    Reply 6 years ago on Introduction

    yeah, you'll have to change the code where you digitalRead() from the pins, change it to if (digitalRead(pin)==0) for a selected state


    6 years ago on Introduction

    Quick question: Could you use the potentiometers in this build in place of the ones for the protoboard-based one? I'm following along the protoboard build (didn't realize that this build existed until now), and the 50k linear-taper and 10K audio-taper that are linked (in the parts list) are too large to fit inside your enclosure. Could I use the potentiometers listed on this parts list? Also, would I change out the 2 that doesn't fit, or should I change out all 3 potentiometers? Thanks!

    1 reply

    Any potentiometers are fine as long as they are the correct taper(linear/log) and the value is somewhere in the same range


    6 years ago

    Is there an image of the top and bottom traces? I want to print and etch this on my own.

    1 reply

    6 years ago on Introduction

    since my last comment was deleted which should be totally against the whole open source concept given the nature of my post -  which was offering a DIY waveform generator that anyone can make on stripboard and not have to spend loads + figure out how to use all the programming stuff I am going to post it again. bad show Instructables, bad show.
    here is the stripboard waveform generator