Creating sine wave using DAC

Thread Starter

emoney123

Joined Jun 4, 2012
32
Hello,

I have a few questions about generating a sine wave using a DAC. First off, I know most people say the easiest way is to setup an array of points of a sine wave and then use a timer to step through it at the desired frequency. What is the array of points derived from? Is there a way to generate the wave "on the fly" by using a sine equation (A*sin(wt))? Is it possible to add multiple frequencies together to form a composite signal?
Thank you for any information.
 

MrChips

Joined Oct 2, 2009
30,794
Is this homework?

It takes too long to calculate sine on the fly.

What one would do is calculate sine from 0 to π/2 or 0 to 2π for a large number of points and put into a look-up table.
To generate the sinewave before sending to the DAC, one would cycle through the look-up table at a given phase interval or frequency in order to generate the signal at a desired frequency.

Yes, one can generate a composite signal on the fly by applying the same technique for various frequencies and summing the values.
 

Thread Starter

emoney123

Joined Jun 4, 2012
32
No this is not homework, just trying to understand how this all works.
For the composite signal, would one generate the two or three waves ahead of time and store each point into an array or something before summing the values? It sounds like this is trivial but I have a hard time visualizing how this algorithm would look.
Thanks for the reply.
 

MrChips

Joined Oct 2, 2009
30,794
No, you do not generate more than one waveform.
You use a single look-up table.
Go to the look-up table at different phase intervals and sum the values you get to output a single point to the DAC.
 

OBW0549

Joined Mar 2, 2015
3,566
I have a few questions about generating a sine wave using a DAC. First off, I know most people say the easiest way is to setup an array of points of a sine wave and then use a timer to step through it at the desired frequency.
Actually that's doing it the hard way, unless you just want to generate a fixed frequency with no intention of ever varying it. A much better technique is what's called "direct digital synthesis" and is pretty much as @MrChips described, and is implemented in a number of DDS synthesizer chips, such as the AD9833 and AD9850. Those datasheets will give all the gory details.

What is the array of points derived from?
It's pre-calculated (via Excel or whatever other means is available) and stored in program memory.

Is there a way to generate the wave "on the fly" by using a sine equation (A*sin(wt))?
Yes, but it's way too slow to be useful for generating any but the lowest frequencies.

Is it possible to add multiple frequencies together to form a composite signal?
Sure; you just execute the DDS algorithm for each frequency individually, and add the results together (scaling them appropriately for the D-to-A converter, of course).

Read the two datasheets I linked to, and you'll get the idea. You just do in software what those chips do in hardware.
 

MrAl

Joined Jun 17, 2014
11,457
Hello,

I have a few questions about generating a sine wave using a DAC. First off, I know most people say the easiest way is to setup an array of points of a sine wave and then use a timer to step through it at the desired frequency. What is the array of points derived from? Is there a way to generate the wave "on the fly" by using a sine equation (A*sin(wt))? Is it possible to add multiple frequencies together to form a composite signal?
Thank you for any information.
Hi there,

This is a very big question because here are so many variations on the idea of how to generate a sine wave. That is just because there are so darn many ways to do this we could probably talk for a week or two just on this subject alone. It might be best to make a list of the various ways and then decide which one you like the best.

To start, the way you are doing it, with a dac, has some limitations in that the dac has to be fast enough to generate the sub cycle values needed in a complete sine wave signal. This means hardware is the main limiting factor as usual. For example to generate a 100kHz sine wave with just 5 points per half cycle, you need a dac that allows you to change points at the rate of 1MHz (10 times the sine wave frequency). If you want to have better resolution like 10 points per half cycle, then you need a dac capable of going at 2MHz (20 points per full cycle, 100kHz sine).

Now we get into the actual generation of the codes that need to be sent to the dac. To start with, you would not really do sin(wt) anyway, you would probably have to do sin(wt)+1 in order to offset the entire wave above zero, unless you happen to have a dual polarity dac on hand. If you use two outputs you can even make a dual polarity sine from two dac's, as long as you dont need a system ground reference for the sine.

The generation of a sine in code can be done in various ways also. The first as you noted was sin(wt) (or the modified sin(wt)+1). Since that is a little slow you would probably create a table dynamically during startup (in RAM) and then use that as the lookup table. That's probably the most straightfoward way. Another way is to use an approximation for a sine. For example, a Taylor's series approximation or even just x^2 as a parabola fitted to a half sine works out to a fairly close approximation. That would mean a small calculation for each point, which would require only one power calculation. There is also the Chebyshev series which has a better distribution of errors across the full wave.

Another very roundabout method would be to generate a triangle with one dac, feed an external non linear waveshaper circuit, then read the output values with an ADC, then use those values to generate the sine. The advantage here would be the waveshaper circuit would always output the same amplitude and then you could scale that in code for your actual sine output.

If you move to PWM instead there are various ways to calculate the pulse widths also. That method does not use a dac though just a bang bang output with some passive filtering on the output.

I have to say that i had a bit of fun talking about this with various people from various walks of life over the years starting from maybe around 1980 or so. Back around that time i worked in an industry where we HAD to be able to do this because the products were those that had to produce sine waves with great power output capabilities up to around 30 kilowatts.
 
Last edited:
Thank you for your detailed response here! I am currently using a DAC to generate a sine wave, and was finding it hard to find good information about how to do it, but I found your points extremely helpful :)


Hi there,

This is a very big question because here are so many variations on the idea of how to generate a sine wave. That is just because there are so darn many ways to do this we could probably talk for a week or two just on this subject alone. It might be best to make a list of the various ways and then decide which one you like the best.

To start, the way you are doing it, with a dac, has some limitations in that the dac has to be fast enough to generate the sub cycle values needed in a complete sine wave signal. This means hardware is the main limiting factor as usual. For example to generate a 100kHz sine wave with just 5 points per half cycle, you need a dac that allows you to change points at the rate of 1MHz (10 times the sine wave frequency). If you want to have better resolution like 10 points per half cycle, then you need a dac capable of going at 2MHz (20 points per full cycle, 100kHz sine).

Now we get into the actual generation of the codes that need to be sent to the dac. To start with, you would not really do sin(wt) anyway, you would probably have to do sin(wt)+1 in order to offset the entire wave above zero, unless you happen to have a dual polarity dac on hand. If you use two outputs you can even make a dual polarity sine from two dac's, as long as you dont need a system ground reference for the sine.

The generation of a sine in code can be done in various ways also. The first as you noted was sin(wt) (or the modified sin(wt)+1). Since that is a little slow you would probably create a table dynamically during startup (in RAM) and then use that as the lookup table. That's probably the most straightfoward way. Another way is to use an approximation for a sine. For example, a Taylor's series approximation or even just x^2 as a parabola fitted to a half sine works out to a fairly close approximation. That would mean a small calculation for each point, which would require only one power calculation. There is also the Chebyshev series which has a better distribution of errors across the full wave.

Another very roundabout method would be to generate a triangle with one dac, feed an external non linear waveshaper circuit, then read the output values with an ADC, then use those values to generate the sine. The advantage here would be the waveshaper circuit would always output the same amplitude and then you could scale that in code for your actual sine output.

If you move to PWM instead there are various ways to calculate the pulse widths also. That method does not use a dac though just a bang bang output with some passive filtering on the output.

I have to say that i had a bit of fun talking about this with various people from various walks of life over the years starting from maybe around 1980 or so. Back around that time i worked in an industry where we HAD to be able to do this because the products were those that had to produce sine waves with great power output capabilities up to around 30 kilowatts.
 

MrAl

Joined Jun 17, 2014
11,457
Thank you for your detailed response here! I am currently using a DAC to generate a sine wave, and was finding it hard to find good information about how to do it, but I found your points extremely helpful :)
Hi,

I did not see your reply until now for some reason. You are welcome.
I also forgot to mention that some of the people i worked with on these kinds of projects were from quite different places in the world such as from Purdue University, Mit, and Sandia Labs for example.
 

Janis59

Joined Aug 21, 2017
1,846
RE:""Is it possible to add multiple frequencies together to form a composite signal""
Yes, it is, take 0% 2nd, 1/3=33,33% 3rd; 0% 4-th, 1/5=20% of 5th, .... 1/7 of 7th, 1/9 of 9th etc etc.
BUT You never shall be capable to beat over the factory ready-made product what are in free market by China price-set. They eat only a rice spoon in a day, in contrast to You, thus You arent concurrent with them.
AD9950 is slowest but cheap, and AD9851 is faster up to 70 MHz, 9854 is up to 200 MHz and there are many more IC~s.
For example (note the different IC names into):
http://www.ebay.com/itm/DDS-AD9850-...201019&hash=item3f6f88c1ae:g:Uo4AAOSwux5YLuX5

http://www.ebay.com/itm/AD9910-DDS-...021269?hash=item4d425f4395:g:ft4AAOSwJQdXB5XF

http://www.ebay.com/itm/AD9851-DDS-...205021?hash=item487cc92f9d:g:vF8AAOSwmLlX9eVR

http://www.ebay.com/itm/AD9834-DDS-...876678?hash=item3d39367a86:g:sg4AAOSwSypY~0-f

http://www.ebay.com/itm/AD9854-120M...514899?hash=item281f0b2113:g:R7oAAOSwawpXwBru

http://www.ebay.com/itm/AD9958-200M...422837?hash=item3f626fa235:g:ligAAOSwmLlX4lAc

http://www.ebay.com/itm/4-Channel-A...296169?hash=item280c3203a9:g:zoEAAOSw4UtWTPyL
 
Hi,

I did not see your reply until now for some reason. You are welcome.
I also forgot to mention that some of the people i worked with on these kinds of projects were from quite different places in the world such as from Purdue University, Mit, and Sandia Labs for example.
That's great to hear. After reading your advice (and others on various forums) I succeeded in generating AC using the DAC to generate a positive half-sine wave, then a switch to reverse polarity each time the voltage crossed the x-axis. Lookup table was rather straight forward to create and store upon startup, but the most difficult part was setting up the timer and ISP to cycle through it!

In your opinion, what's the best way to generate a sin wave? I've only used a DAC because it was there - but we are redesigning our circuits and might the option to move to a dual-DAC or PWM option
 

panic mode

Joined Oct 10, 2011
2,736
the best way would be to come up with some specs and constraints before asking way too broad question and reading/considering already offered advises (ie use DDS instead of DAC, DAC is just one part of the system).

keep in mind - what is best for you is not nearly good for someone else and the other way around

so what frequency range you are interested in?

https://ipnpr.jpl.nasa.gov/progress_report/42-75/75G.PDF
 
the best way would be to come up with some specs and constraints before asking way too broad question and reading/considering already offered advises (ie use DDS instead of DAC, DAC is just one part of the system).

keep in mind - what is best for you is not nearly good for someone else and the other way around

so what frequency range you are interested in?

https://ipnpr.jpl.nasa.gov/progress_report/42-75/75G.PDF
Thanks for the response - and fair point. I'm looking at generating low frequencies roughly between 3-20Hz. Current output spec is low as well at a maximum of 3mA, but with a voltage range up to 50.
 

cmasenas

Joined Sep 11, 2017
2
That's great to hear. After reading your advice (and others on various forums) I succeeded in generating AC using the DAC to generate a positive half-sine wave, then a switch to reverse polarity each time the voltage crossed the x-axis. Lookup table was rather straight forward to create and store upon startup, but the most difficult part was setting up the timer and ISP to cycle through it!

In your opinion, what's the best way to generate a sin wave? I've only used a DAC because it was there - but we are redesigning our circuits and might the option to move to a dual-DAC or PWM option
The DAC does not generate a sine wave. The DAC or PWM only converts the numerical sine to an output voltage. The challenge is producing the numerical discrete time output that can be used as input to a DAC or PWM. The options for producing a numerical discrete time sine seem to be DDS or an unstable filter.
 

Janis59

Joined Aug 21, 2017
1,846
RE:""frequencies roughly between 3-20Hz""
It means You have nothing so well suited as DDS principle.
Summing You shall get the may be, if lucky, 1% nonlinearity.
With DDS You shall get at least 0,01%.
And Voltage You shall scale up with just booster cascade.
 
The DAC does not generate a sine wave. The DAC or PWM only converts the numerical sine to an output voltage. The challenge is producing the numerical discrete time output that can be used as input to a DAC or PWM. The options for producing a numerical discrete time sine seem to be DDS or an unstable filter.
Hey mate, as I mentioned in my previous comment, the discrete time output is what I found challenging about sine wave generation too. I used a lookup table and a hardware timer to cycle through it for my solution, but was wondering if there was a better solution for generating low f waves. Thanks, Ill check out DDS and the unstable filter.
 
Top