0-40Mhz, Sine Wave Generator for $25.





Introduction: 0-40Mhz, Sine Wave Generator for $25.

About: Totally committed to learning more about all the stuff.

Recently some very cheap boards ($4-6) have been coming out of china containing a chip known as the AD9850 which is a Direct Digital Synthesis sine wave generator.

With only 4 control wires we can control the board via the arduino. This gives us a variable sine wave generator that we can control to give us a very nice sine wave from 0 Megahertz up to around 40 Megahertz at almost a full volt peak to peak.

I decided to use a $7 LCD keypad to give some on screen visual indication of the frequency plus a means of controlling the frequency quickly and easily.

The code to upload to the Arduino, can be relatively straight forward.

I have been using libraries to simplify the toggling of the control pins to set the frequency on the sub board. Also cause i'm not that smart yet!  The dds.h library is from Anthony Good - K3NG

So simple to use, the command to set the frequency is simply;


Could it be any easier?

To get the board up and running, find Anthony's library here.

Place the DDS directory in your arduino sketches/library folder with all the other libraries. That way when you compile/upload the IDE will find the file automatically.

The board has a clock pin, a load pin, a data pin and a reset pin. The other 4 pins of use are the sin wave output and a square wave output.

Step 1: A Discussion on Code..

In the setup code you will just need to define what pins you have used for what job between the DDS board and the Arduino.

#define data_pin 12
#define load_pin A5
#define clock_pin A4
#define clock_hz 120000000LL

dds ddschip(DDS9850, data_pin, load_pin, clock_pin, clock_hz);

This sets my dds up with its 120mhz onboard crystal. I am substituting the pin numbers with words to make it easier to understand. For example the word data_pin would be replaced everywhere it is found at compile time with the number 12. this is what the #define command does

Now the chip pins have been defined, we can just use the ddschip.setfrequency(Frequency); command to set the frequency to any frequency we desire, within the capabilities of the device.  The AD9850 boards i have used are pretty good for about 0-40mhz, beyond that they are a little sketchy.

I figured that i would use the up and down buttons to raise or lower the frequency.

I decide to use the left and right buttons to cycle the amount the frequency would increment on raising or lowering. I chose, 1Hz, 10Hz, 100Hz, 1KHz, 10KHz, 100KHz and 1MHz.

I cobbled together some code, some of which i hacked out of a previous LCD keypad project (Morse coder). I have kept the interface reasonably simple, after all we only have 16 characters on two lines.

After I had it built up on the bench and had tested it extensively I decide to put it all in a box.  Initially i wanted to put a battery pack inside the box as well, but decided to leave access to the power jack so i could just plug in a battery pack externally if i wanted to.  The result are the photos you see here. The LCD keypad shield is designed to be used in the open and not really designed to go in a case, but i shoehorned it in with lots of cutting. I used a terminal block on the side for the sine wave output and I also decided to break out the square wave output and its associated adjustment pot, the LCD contrast adjustment pot and the DDS board power light.

Step 2: All Done. Here Is the Code.

Attached here is the code I came up with;

If you improve upon it, please let me know!

If you want more info, check out my blog entry here..



    • Creative Misuse Contest

      Creative Misuse Contest
    • Oil Contest

      Oil Contest
    • Water Contest

      Water Contest

    14 Discussions

    Hi Megatronics, Do you have much programming experience with the Arduino IDE?

    This picture is from the PDF schematic of the board you said you have. It shows the way the buttons are connected.

    They are all connected back to pin A0, via different resistors for each.

    This means analog input A0 sees a different voltage depending on which button is being pushed.

    The value of AO will vary from 0 to 1023.

    Serial.println(analogRead(A0)); //will show its actual value on the serial port

    The code needs to choose a button depending where A0 is.

    A0 is between 100-200 // pushed up?

    A0 is between 200-400 // pushed down?

    A0 is between 400-600 // pushed left?

    A0 is between 0 -100 // pushed right?

    Here is where it does it...

    Change it around to suit your board!!

    if(analogRead(buttonPin)>=100 && analogRead(buttonPin)<=200){ // we have pushed up




    if(analogRead(buttonPin)>=200 && analogRead(buttonPin)<=400){ // we have pushed down




    if((analogRead(buttonPin))<=50){ // we have pushed right




    if(analogRead(buttonPin)>=400 && analogRead(buttonPin)<=600){ // we have pushed left





    3 years ago

    Thankyou for your information, but have you tried to make the variable amplitude output of dds, would you like to tell me how?

    Great guide! Can I make a "Sinewave 220v Power-Inverter)" out of it? Let us say replacing the regular square wave multivibrator with this sinewave generator. This way the Mosfets will produce a clean amplified output for the step-up transformer.

    4 replies

    Sinewave inverters do not actually use sinewave at the MOSFETs... they synthesize the pseudo-sinewave by PWM methods. The MOSFET's still operate as digital ON/OFF switches, and keep their switching power losses low by doing this. Then the PWM output power is filtered by large inductors and capacitors to eliminate the high frequencies, leaving just the sinewave-like output.

    The microcontroller in grid-tie inverters contains the code for the PWM-to-sinewave generation. The output waveform is generated by monitoring the inverter output current, since you need to generate in-phase. The inverter will always need to generate slightly higher output voltage than exists on the grid (ie household power), so that it pumps power onto the grid. It's no small task...

    OFF-grid inverters are much simpler...

    That's a great answer psron. This frequency generator is for low power experimentation in higher frequencies, not really as a inverter signal source.

    In our country the standard is 60hz, so yeah I'l go with the 60hz. Sinewave power inverters are expensive these days.

    hi, is it possible to build 3 phase sine wave following same idea?

    1 reply

    I found this application note on the AD9850 specifically talking about this.


    The resolution is so great that i could not see any steps when zoomed in. This is not so much for audio as audio is only up to about 20khz, this more for radio frequency applications as the range is up to 40Mhz!

    Thanks stubbsonic, i think for $6, you'd agree that it's a great simple device for testing things. I have started to investigate things like resonance and filters and the effects of different components. Next thing would be to build an amplifier for it..

    What is the quality of the waveform? Is it 16-bit or 24-bit? Or is it ultimately an analog waveform (perhaps with digitally controlled frequency?) You may be able to tell I don't know much about this stuff :)

    2 replies

    The waveform is very high quality. The AD9850 has a high speed DAC. I couldn't find the actual bit depth. The data sheet is here..


    Thanks for your response and that link. I looked at the pdf and there's a pin-out diagram that shows the DAC to be 10-bit. So even though the clock resolution and tuning resolution are very very high; the would be stair steps in amplitude based on 10-bit amplitude. Still with that frequency range, it seems like this could be handy for all kinds of audio applications.