# generate sin wave with PWM

• posted

hi all,

How do I generate a sin wave using PWM? The way I have thought is just to create a triangular wave with equal steps of the PWM duty cycle (depending on freq) and then filter out the harmonics with a hw filter. But what if I want to generate a sin wave instead of a triangular wave, how do I calculate the steps for the duty cycle of the PWM? These steps are not equal, so I will need to store them in a table. Any ideas?

thanks Ivan

• posted

Well, the steps are not equal, so you will need to store them in a table :)

Using sine tables is common for generating sine waves, since calculating sines is a very expensive operation.

You could use something like the following snippet:

#include

int main(int argc, char **argv) { int x = 0, y = 64;

while(1) { x += y/8; y -= x/8;

printf("%d %d\n", x, y); } return 0; }

```--
:wq
^X^Cy^K^X^C^C^C^C```
• posted

Write a program on your favorite computer in your favorite language that emits a bunch of .pword assembler directives with the sine values.

Note that the table only needs to cover 1/4 cycle. At run time you use symmetry to get the values for other parts of the sine wave. All 4 combinations of indexing into the table forwards and backwards, and negating the result or not yield the full sine wave.

ivan wrote:

• posted

steps

harmonics

how

not

Or calculate them on the fly. Neither method seems challenging. After all if the PWM is clocking at the CPU frequency you've got lots of cycles to the next PWM update unless you got no resolution from the PWM. Now, is the sin wave you want at a fixed frequency or fixed amplitude?

As to calculating you might want to apply you mind to the trig formula:

sin(A+B) = sin(A)*cos(B) + cos(A)*sin(B)

Peter

• posted

You can output widths that are samples of a sine. they can be generated directly as you need them or taken from a table. The derivative of a sine is a cosine. The difference between the widths of successive pulses that simulate a sine follow a cosine. A pair of DDAs, like a pair of op-amps, connected back to back can generate sine and cosine waves simultaneously. (DDA stands for "digital differential analyzer". Nobody builds them any more, but they are easily created in software.) Software DDAs are often used for circle generation, and they can supply pulse widths for uni- or bipolar PWM.

The software version is related to Bresenham?s algorithm. Look it up.

Jerry

```--
"The rights of the best of men are secured only as the
rights of the vilest and most abhorrent are protected."```
• posted

Not necessarily. You could, for example, run a square wave into a wave digital LP filter. If you use Chebychev or elliptic it won't consume much in terms of MIPS. One can play with the coefficients a bit to reduce the number of shift-adds as long as the stop band attenuation remains sufficient. And use CSD.

```--
Regards, Joerg

http://www.analogconsultants.com```
• posted

:)

Thats hugely more work than you need to do. We're talking a few multiplies (by constants) and adds at the most.

Peter

• posted

Hello Peter,

Depends on the hardware the OP is planning to employ. If it's a uC or DSP with a HW multiplier it is easy. If it has to be a low end garden variety without HW multiplier that is a different story. You can run a steep Chebychev WDF in about 500 cycles per sample. Probably similar with other shift-add schemes.

```--
Regards, Joerg

http://www.analogconsultants.com```
• posted

Here are some ideas:

• posted

Others will tell you of all sorts of formulae and about look-up tables but one technique that many forget is called a "Digital Differential Analyser". With some very simple maths and some logic these can be implemented and produce sine and cosine streams of data which could be used more-or-less directly by the PWM generation logic.

Put the term "Digital Differential Analyser" and Sizer into Google's search string and you will get a number of references that may prove useful (especially if you register for the IEEE and CiteSeer sites.

```--
********************************************************************
Paul E. Bennett ....................```
• posted

That's what I said, very expensive

:)

```--
:wq
^X^Cy^K^X^C^C^C^C```
• posted

Don Lancaster got carried away with this awhile ago:

• posted

Hello Ico,

You can do that for a buck fifty with an MSP :-)

```--
Regards, Joerg

http://www.analogconsultants.com```
• posted

The first task is to define the PWM:sine freq ratios, and also decide if you need to scale the Sine voltage, or Frequency, via the PWM. Then you'll know what quantize errors you are forced to live with, and from there, you can choose a coding scheme : you may find in small systems, that the quantize issues matter most. One system we did, was fixed Freq and Amplitude, so used this approach :

We took care to match the slopes of the steepest sine portions, to a sensible step rate. Then chose a width for the flat top/bottoms, and finally chose widths for 'chamfers' to what is thus far a flattened triangle. This is effectively a slope-fit method, with carefully selected time-breaks. It does need maths to choose the corners, but needs no maths on the uC running the PWM.

-jg

• posted

You don't. For that you need a moral height destabilizer, not a pulse width modulator. A PWM just ain't evil enough to trigger a wave of sin.

SCNR ;->

```--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.```
• posted

Hello Hans-Bernhard,

But if it were connected to the FET gate of a switcher and the compare register ain't updated before the inductor current reaches kaboom level it is able to re-create Sodom and Gomorrha...

```--
SCNR either, Joerg

http://www.analogconsultants.com```
• posted

... snip ...

Precisely. Set B = dA (the angular increment) and you have:

sin(A + dA) = k1 * sin(A) + k2 * cos(A)

which, for small dA, has k1 close to 1 and k2 close to 0. You can use cos(A) = sin(90-A) so that you don't need elaborate calculations for cos.

```--
• posted

Paul,

I have long felt that we shared a common way of seeing things. Did you see my response?

Jerry

```--
"The rights of the best of men are secured only as the
rights of the vilest and most abhorrent are protected."```
• posted

"ivan" ha scritto nel messaggio news:egg63k\$ekg\$ snipped-for-privacy@news.flashnet.it...

steps

harmonics

how

not

ok.. this is the way I have done it and it seems to work althought there is some discontinuity between the last and first element of the table (however this can be solved calculating increments of the PWM values instead of the values itself). Well the value of the PWM dutycycle is directly proportional to the value of the output voltage, so for 24bits and a isr that updates the PWM value at about 60KHz I have:

x = (int)(0x7fffff * sin(2*pi*n/N))

where

N = 60KHz / TargetFreq;

hence I generate my table with:

for(n = 0; n < N; n++) { x = (int)((16777216.0/2)*(sin(2*PI*n/N) + 1)); printf("%d,\\\n",x); }

thanks again ivan

• posted

Only after I had posted and on my subsequent trawl through the newsgroups.

```--
********************************************************************
Paul E. Bennett ....................```

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.