Arduino DDS Sinewave Generator

D4p0up:
With this code, I have been able to operate my DIY 8 BIT SPI DAC at a frequency of 330kHz.

Very nice - I was wondering, from the page you referenced, 1% resistors are needed for 6 bit, and more precise for higher bits - has anyone had success using potentiometers to get more accurate resistances?

Just thinking about it, you reach a point where even the soldering flux has an impact on the total resistor of the resulting design...

integrated chip designers do nanometric adjusments of the R2R ladders to reach the expected accuracy. So with pots... you might end up spending your life seeking for a percentage of digit on your multimeter... in vain.

COntinuing the discussion and answering the question...

About the SPI, I feel like digging into the Datasheet of the AVR and configuring every single bit on my own instead of using the Arduino dedicated functions. Of course they are much more user friendly, but I want to learn more about the HW and be closer as possible to it, so i might do the same, I prefer ton configure it on my own.

About the ADC, I have today very good audio results with my 8 bits DAC presented in the links above. Resistors are basic 5% tolerance, so there is non linearities spread among the way, it can be heared, but for a "lowfi but still accurate" project, it's worth it.

I will eventually use MCP4921's for my final Synth Shield, but only for "cleaning" purpose, I feel perfectly at ease with the current resistor based 8 bit DAC. I have not tried higher resolutions though, because of this table you mention.

I don't understand why you don't just lose the shift register and have the R-2R ladder on 8 Arduino pins (say port D then writing is a single instruction). You'll get to MHz with the sinewave table perhaps?

Good question, simple answer: The lower the pin count, the better it is.

In the audio synth application I'm currently working on, I need the pins 0 & 1 for Midi In/Out purpose, and also need four analog inputs for control Knobs and so on. Add to this three Leds for Synth operation purpose (gate + lfo rate + general purpose), four buttons for operation like preset managment and edition, and make the breakout:

2 + 4 + 3 + 4 = 13 pins, with 9 being discretes.

With this basic setup, I have no room for Port dedicated 8 Bit DAC on a Uno board.

Then, in the future I plan to use a MCP4921 as a DAC. This will lead to better results, so using a homemade SPI DAC in this case is the best way to anticipate design evolutions.

However, as I mentionned on my blog, I started using a rough 6bits DAC on PortC with great success... except for dynamic range of course :slight_smile:

Is it possible to have a three phase sine wave with this generator ?
I would like to generate a 10 kHz to idealy 18 kHz three phase wave.
Does miro-Hertz precision will pertain with this change ?

ten Khz is anyway a problem, the atmega is to slw for that. using a dedicated DDS chip would be a solution
maybe some manufactor has a 3 phase version.

martin

You definitely could with the R2R SPI DAC trick presented above:

Just chain 3 x 74HC595 with their associated DAC, and use the same method as described above, except that the 3 respective phase accumulators should be initialised with 0, (1/3)x2^16, (2/3)x2^16.

This will make 3 outputs !

Thanks for those two replies, the original post about frequency production limit came from an email that I addressed to marnaw about 10 Khz to 18 Khz 3-phase sine wave.
I found this and marnaw is in the pdf file.(I)

I did not be able to contact the author and he claimed of 13 Khz, I think it's about switching pwm, don't you ?
So, first, my question still pertain : does I really need a dedicated dds to perform my signals ?

Second, does marnaw work deal with this, sometimes also called magic sine waves ?(II)
Best regards.
Sril

Edit (09/23/11) :
(I) is a non finish student work about control motor, does not need to be read, sorry.
(II) deal with a method to suppress harmony under a certain level from base frequency and is not the same as described heare, sorry.
I insist to present my apologizes for stupid lost time to read me.

Go-on my work with a 3-phased generating circuit.

Hi

Came across this utility/routine for the Arduino, looks great. I am still digesting the program as I have very basic knowledge of C language and specifically some of the commands used in this routine.

My question is this;
I would like to modify this to be able to generate 2 sine wave outputs, same frequency, but one of the sine wave needs to be shifted 90 degrees from the other. Can it be modified for this? Some help in finding where explanations of all these particular commands could be found would be useful. I imagine that the commands to drive the second sine wave would need to be contained in the interrupt service routine.

I think I should be able to use the same sine value table but shifted by 64 values for an out of phase wave of 90 degrees.
Thanks for any help.

Can't you just maintain two table pointers 90 degrees out of phase, and do the summing in the ISR?
(watch out for unsigned arithmetic summing the samples)
It would limit the highest frequency you could generate.
Or, if the two signals are always the same amount out of phase, simply generate a single lookup at compile-time.

AWOL nailed it.

As mentioned above, just initialise the two phase accumulators with 0 and 16384 (pi/2).

The rest of the DDS is the same...

Thanks for the suggestions.
I got it working just as hoped. I simply initialized the second PWM output then created a second sine table lookup pointer that is shifted by -64 bytes, which generates the same wave but phase shifted by 90 degrees. Awesome. My project can now move ahead.

A question for those who used this code ( And apologies if some of the question might sound silly, but my issue will be more to do with the hardware).
Would i be feasible to transform this code to also modulate the signal, using an input ( from a pot, lets say) to influence the speed of modulation ( a LFO, lets say) ?!?
I notice there is a pot...Is that pot influencing the frequency ?!?
Always found this code interesting, but only more recently im getting to grips with the hardware features and limitations.
My aims are low frequencies, audio based anyway. By the way, what would be the limitations of this, as is ?!( I noticed the ook-up table issues for higher frequencies etc)
*PS-GOT IT

The frequency range reaches form zero to 16 KHz with a resolution of a millionth part of one Hertz!

Thanks in advance and many thanks to the original programmer above all !!

Yes, it would be easy to use a potentiometer. Since the program requires that you specify a frequency value, you can read the pot and use that value to specify the frequency to generate. The original program used a pot for this very purpose. I took this out of the code as I needed specific digital frequency values entered by the user.

Late reply but hey...

The answer to the question is : probably yes, but not sure at all. Let me explain : LFO, modulation and so on, those require multiplication at which Arduino does not excel at. Multiplication take several clocks depending on what you are doing, and this definitely makes the point.

44.1kHz clock means... one sample every 22 micro second.

You roughly have 18us to do the job, so the math of your modulation shall not be too big, indeed.

Hope this helps.

I added a TI 5515 DSP which sped things up a bit ..

hi,
in my project i want to use dds with arduino for generation of desired frequency upon command in the range of 125 hz to 8khz and then also vary there amplitude (increase or decrease) upon command using a variable gain amplifier.I want this selection of frequency and amplitude to be done using computer i.e. generation of desired frequency and amplitude upon a click on computer.
Kindly suggest me a proper board and its cost in India.
Kindly reply as soon as possible.

Kindly suggest me a proper board and its cost in India.
Kindly reply as soon as possible.

Well you just need a standard Arduino Deumilanove or uno etc clones out there remember that the code used is working with registers of an ATmega328 (ATmega168 and 88 will suffice too!) so lookon to have the arduino clone or original arduino which these chips, also you would needsomepassives to create the low-pass filter.

How to make it: The linkis here:

http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/

Hi. I have a question about this DDS sinewave generator. Why is Timer0 is disabled in the setup? I need to use the millis() function and it doesn't work without Timer0.

  // disable interrupts to avoid timing distortion
  cbi (TIMSK0,TOIE0);              // disable Timer0 !!! delay() is now not available
  sbi (TIMSK2,TOIE2);              // enable Timer2 Interrupt

tjk3052:
Hi. I have a question about this DDS sinewave generator. Why is Timer0 is disabled in the setup?

Probably because if you don't disable it, the interrupt service routine for timer 0 that gets executed nearly every millisecond causes the DDS interrupt service routine to be delayed a little, and that spoils the purity of the signal.