10 Resistor Arduino Waveform Generator




About: I am a retired Electronic Systems Engineer now pursuing my hobbies full time. I share what I do especially with the world wide student community.

If you have an Arduino UNO this project is practically free!

It also makes a great Arduino Nano project.

What you need (only passive components):

  1. Just 10 Resistors
  2. One filter capacitor

What you get:

  1. A Direct Digital Synthesis (DDS) Waveform Generator
  2. True 50 kHz Sin-Wave capability
  3. Sin, Triangle, Ramp Up ,Ramp Down outputs
  4. And Arbitrary Waveform Generation (AWG)


  1. 50 kHz seen on an Analog Oscilloscope
  2. Arbitrary waveform created using a sum of f and 2f
  3. The arbitrary waveform spectrum
  4. An a compact version implemented using an Arduino Nano

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: Breadboard and Circuit Schematic

The circuit implements a 6-Bit Digital to Analog Converter (DAC) using a 8-4-2-1 Resistor combination.

Arduino Uno Output pins 13 to 9 form the 6-Bits PB5 to PB0.

The Ideal resistors for the 8-4-2-1 network should have been:

1.1 K, 2.2 K, 4.4 K, 8.8 K, 17.6 K and 35. 2 K

However this has been simplified to

1.0 K, 2.2 K, 2.2 K + 2.2 K, 8.2 K + 560, 15 K + 2.7 K and 33 K + 2.2 K

The first 1.0 K instead of 1.1 K has been used to take care of the loading on the PB5 output.

A 0.01 uF filter capacitor is added to the resistor DAC output for smoothing the waveforms.

Step 2: Something for Nerds

A basic DDS waveform generator needs a phase_accumulator to be incremented by a phase_step at a frequency f_clock.

Earlier Waveform Generators using the Arduino Uno have implemented DDS generators with a f_clock frequency based on a timer interrupt at 100 kHz. This limits the practically usable DDS waveform output frequency to f_clock /8 or waveforms to 12.5 kHz.

The current approach attempts to maximize the f_clock. By implementing the DDS loop using a while function wherein a minimum number of instructions cycles are utilized.

Exit from the while loop is based on a variable updated based on the USART Rx interrupt

The current while loop takes 43 cycles and the f_clock would be 16 MHz/43 = 372.09 kHz

The best we could have done if the Arduino Uno exit from while was based on a Reset would have been 40 instructions or 400 kHz.

f_clock/8 is 372 kHz/8 = 46.5 kHz which is practically 50 kHz!

The code is implemented in ' c' using Atmel Studio 6.0

The c-code implements a 24-Bit phase_accumulator of which the higher order 7-Bits are used as an address to a 128 step waveform table containing 6-Bit waveform data with values from 0x00 to 0x1F Hex.

Use the 007DDS.Hex to program the Arduino Uno using Avrdude.

Step 3: Perf-board Circuit & Connections

The 10-Resistor circuit is wired on a standard perf-board in such a way that the PB5-PB0 terminals are on one side and two ground pins are on the opposite side. All pins match with the Arduino Uno output connectors.

Additional socket pins are soldered for the output connections.

  • Sq Output Reference
  • DDS Waveform Out
  • Gnd

The connections are shown clearly in the figure.

Step 4: Operating the Waveform Generator

Connect the perf-board 10 Resistor network to the Arduino Uno.

Connect the Arduino Uno to a PC USB port.

Open up the Windows based GUI program attached.

The GUI program is easy to use:

  1. It permits selection of the virtual com port
  2. (Try a second time if the port is not connected the first time)
  3. Setting the output frequency
  4. Selecting the waveform type
  5. And running the program

In the special case of the DDS_Arb (0-50kHz) arbitrary waveform selection

  1. The open file dialog looks for a .csv file which defines the arbitrary waveform
  2. Once this is selected the waveform points are automatically uploaded
  3. Run the arbitrary waveform at the frequency value selected.
  4. Once loaded the waveform points remain in memory and if the same waveform need to be re-run we can cancel .csv selection.

The third figure is a typical screen-capture showing combined GUI of the Aj_SignalGen and my earlier "USB Oscilloscope in a Matchbox " https://www.instructables.com/id/DIY-USB-OSCILLOSC... which has been used for capturing all the wave-forms in this Instructable.

To install the Windows GUI:

  1. Extract the Windows GUI.rar to a suitable location on the PC to be used
  2. Run the .exe file
  3. That's it!

The Windows GUI needs .Net 2.0 and has been tested on Win XP and Win 8.1

Step 5: Amplitude Control

Output waveforms swing from 0 V to a maximum value corresponding to the 5 V supply voltage. In many applications it may be necessary to reduce the amplitude and generate waveforms which have a positive to negative swing.

This is accomplished using a external circuit where the DDS Generator output is capacitively coupled to a trimmer potentiometer and the final output taken from the potentiometer wiper point.

Considering that the 8-4-2-1 DAC has an output impedance less than 1 kilo-Ohm a potentiometer of 5 kilo-Ohm is chosen. The coupling capacitor needs to be changed depending on the frequency being used for test.

The figures show the bread-board implementation and the circuit schematic.

A 1 kHz 2V p-p waveform is shown as an example.

Step 6: Typical Sin, Triangle and Ramp Waveforms

Figures show a 25 kHz Sin, 10 kHz Triangle and two 1 kHz Ramp waveforms.

Because of the limitation of my DIY Oscilloscope the 50 kHz Sin waveform as seen on an analog oscilloscope is shown at step-1.

Step 7: Arbitrary Waveforms

Arbitrary waveform data should be created as a .csv file containing one column of data with length 128. The data values should be in decimal whole numbers in the range 0 to 63.

These values when loaded to the Arduino Uno are converted to Hex values between 0x00 and 0x1F and output as arbitrary waveforms.

Three typical waveforms with their corresponding .csv files are provided as examples.

Step 8: Implementation on the Arduino Nano

A small two layer pcb has been created using EAGLE CAD software.

The Eagle files are attached.

Unfortunately the output bits of Port_B got reversed as compared to the circuit implemented on the Arduino UNO.

This reversal in hardware is taken care by reversing the bits in software before the data is output.

This requires a changed Hex file.

008_DDS.hex to be programmed on the Arduino Nano.

The Windows GUI program remains unchanged.

1 Person Made This Project!


  • CNC Contest

    CNC Contest
  • Make it Move

    Make it Move
  • Teacher Contest

    Teacher Contest

23 Discussions


2 years ago

Hi, I'm having a problem with the signal generating software. Every time I go to select a COM port it keeps timing out. I was wondering has anyone else encountered this problem and if so what do I do

4 replies

Reply 2 years ago

Pl check through device manager that the driver is installed correctly and what com port the Arduino is connected to. Try to connect to this port. Sometimes I find it connects only on the second attempt. Which version of windows are you on? Do normal sketch uploads work with your setup?


Reply 2 years ago

I'm running on windows 10 and this is the first sketch I've tried as I'm new to Arduino. I made sure the drivers were up to date and that the arduino is connected to the right port and it still isn't working is there anything else I can try to fix it? Thanks


Reply 2 years ago

Sorry, I have checked the GUI only on Win 7 and Xp. However if the GUI opens it should work. I suggest you check the Arduino system by confirming that the 'Blinking-LED' sketch works. Then load the file I have provide or the alternative compiled by ThomasK19 and confirm the loading is OK. Close the Arduino IDE as it may still hold on to the com port. Then try the GUI I have provided. Meanwhile, I will try to check on Win 8.1 and Win 10 if possible. Feedback on Win 10 usage from other members is welcome.


Reply 10 months ago

same problem happening with me.can u help please??


Question 10 months ago

can you upload a short video of how u are opening window gui, uploading csv files and operating dds generator.is will be very helpful.reply asap


10 months ago

what is window gui.is this any software?if any then from where to install for window 10


Question 1 year ago

What is your (mathematical) definition for phase step? How do I convert my frequency values to phase step values and use the rest of your codes to generate the waves?

1 answer

Reply 1 year ago

This is the theory of DDS:

N-bit phase accumulator will have 2^N steps

Each phase step = n

Using a clock frequency = fclock

fout = n X fclock/ 2^N "use this for your calculation"

The frequency resolution would be = fclock/2^N

and the number of sample points on the waveform generated ~ 2^N/n = fclock/fout

In this instructable we use a 24-bit phase-accumulator with a fclock of 372kHz, the upper 7-bits go to the look-up table which has 6-bit waveform data which is output to the 6-bit d/a. We would get ~15 waveform samples at 25 kHz


1 year ago

I'm testing it with your version of the linux program, available on your other project,


and using arduino for compilation, everything worked perfectly.

P.S. I tested the compilation of DDS with arduino, and I have an error on

get_switch(uint8_t duty){


2 years ago

what is i dont want to use the GUI software and i want make its function executed by hardware?

7 replies

Reply 2 years ago

Thanks for your comments. I have now implemented a stand-alone mode / USB PC GUI dual mode project.



Reply 2 years ago

Good idea ! Rig up a PC1602 16X2 LCD display and increment/decrement the frequency to be set using two switches. Another switch could select the waveform type. The calculation for phase step corresponding to the frequency is currently done in the VB program this needs to be done on the Arduino. Everything should be good except the arbitrary function may not be possible. Could you work on this and share?


Reply 2 years ago

Im not much of a programmer, but i love the simplicity of the hardware. I might be able to add a display and controls. I'd want to use I2C and a rotary encoder. I cant make any promises i cant keep, except if i do come up with anything, I'll post it here.


Reply 2 years ago

Also consider an option using thumb-wheel switches.


Reply 2 years ago

I do like that idea. I'll have to look around to see whats available these days. That would add a nostalgic look to it, and make it easy to change frequency. Electricaly, I think it will require one output per digit and 5 inputs if i multiplex. Ill have to do an I/O count to see if an Arduino has enough.


Reply 2 years ago

Thanks for your comments. I have now implemented a stand-alone mode / USB PC GUI dual mode project.



Reply 2 years ago

Check out this link: http://www.edn.com/design/analog/4439796/Read-multiple-switches-using-ADC . If you use a BCD switch then only 10 combinations need to be decoded. As we use ADCs the number of pins should be sufficient. Plan for frequencies up-to 19999 Hz. 4 BCD switches and the other digital pins can be used for selection 0/1 for the 10 Thousands, Sin/Triangle and to initiate the setup frequency.

LuisLopezMA 1966

3 years ago

Hi.only have One question.You Check the wave Outside,wear you have a lot Electromagnetic fields.You even Check
If the wave you mini arduino Make can be use directional ground post.If you can do This
Please posted.We working in That and Any Help Count.