Arduino Sinewave for Inverters

In this project i've generated a SPWM(sine wave pulse wide modulated) signal from two arduino pwm digital outputs.

Because to make such a program i have to talk about many others functions and properties of the arduino the full project including oscilloscope images and for different frequencies please visit my website:


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: Generating the Pwm Signal for 50Hz

To generate a 50Hz signal at higher frequency it is neccesary to make some calculations. Frequencies from arduino can be at 8MHz, but we want a signal with variable duty cycle.

To understand the types of variable duty cycles of arduino you can read this 3 parts of the same post 1,2 and 3.

Let’s assume our frequency is 50Hz that mean the time period is 20ms. So 10ms is half cycle period. In those 10ms we need to have many pulses with different duty cycles starting with small duty cycles, in the middle of the signal we have maximum duty cycles and finish also with small duty cycles.
To generate a sine wave we will use two pins one for positive half cycle and one for negative half cycle. In our post for this we use pins 5 and 6 that means Timer 0.

For a smooth signal we choose phase correct pwm at a frequency 31372 Hz-see previous post.
One of the biggest problem is that how we calculate the necessary duty cycle for each pulse. So, because our frequency is f=31372Hz the period for each pulse is T=1/31372=31.8 us, so number of pulses for a half cycle is N=10ms/31.8us=314 pulses. Now to calculate the duty cycle for each pulse we have y=sinx, but in this equation we need degrees so half cycle has 180deg for 314 pulses. For each pulse we have 180/314=0.57deg/pulse. That means for every pulse we move forward with 0.57deg.

y is the duty cycle and x the value of the position in half duty cycle. at first x is 0, afetr that x=0.57, x=1.14 and so on until x= 180.

if we calculate all of the 314 values we obtain an array 314 elements(type "int" to be calculated easier by arduino).

Such array is:

int sinPWM[]={1,2,5,7,10,12,15,17,19,22,24,27,30,32,34,37,39,42,
44,47,49,52,54,57,59,61,64,66,69,71,73,76,78,80,83,85,88,90,92,94,97,99, 101,103,106,108,110,113,115,117,119,121,124,126,128,130,132,134,136,138,140,142,144,146, 148,150,152,154,156,158,160,162,164,166,168,169,171,173,175,177,178,180,182,184,185,187,188,190,192,193, 195,196,198,199,201,202,204,205,207,208,209,211,212,213,215,216,217,219,220,221,222,223,224,225,226,227, 228,229,230,231,232,233,234,235,236,237,237,238,239,240,240,241,242,242,243,243,244,244,245,245,246,246, 247,247,247,248,248,248,248,249,249,249,249,249,250,250,250,250,249,249,249,249,249,248, 248,248,248,247,247,247,246,246,245,245,244,244,243,243,242,242,241,240,240,239,238,237,237,236,235,234, 233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,217,216,215,213,212,211,209,208,207,205,204, 202,201,199,198,196,195,193,192,190,188,187,185,184,182,180,178,177,175,173,171,169,168,166,164,162,160, 158,156,154,152,150,148,146,144,142,140,138,136,134,132,130,128,126,124,121,119,117,115,113,110,108,106, 103,101,99,97,94,92,90,88,85,83,80,78,76,73,71,69,66,64,61,59,57,54,52,49,47,44,42,39,37,34,32,30, 27,24,22,19,17,15,12,10,7,5,2,1};

You can see that like a sine wave the duty cycle is lowest at first and last element and highest in the middle.

Step 2: Arduino Program for Variable Duty Cycle

In the image above we have variable duty cycles signals with values from the array.

But how to make such signal??

the part of the program below use interrupts to change the values of duty cycles

sei();// enable interrupts


ISR(TIMER1_COMPA_vect){// interrupt when timer 1 match with OCR1A value

if(i>313 && OK==0){// final value from vector for pin 6

i=0;// go to first value of vector(array)

OK=1;//enable pin 5


x=sinPWM[i];// x take the value from vector corresponding to position i(i is zero indexed)-value of duty cycle

i=i+1;// go to the next position


Step 3: Alternating at 50Hz Arduino Pins

Beacause each pin generate only a half duty cycle to make a full sine wave we use two pins which alternate one after another after exact 10mseconds(for 50Hz). This change of pins is made at the end of the array- after let's say pin 5 has generated 314 pulses this pin is powered off and enabled pin 6 which makes the same thing but for the negative duty cycle.

Because arduino can generate only positive signals negative duty cycle is made in h bridge- you can read here about it

The program for changing pins:

sei();// enable interrupts


ISR(TIMER1_COMPA_vect){// interrupt when timer 1 match with OCR1A value

if(i>313 && OK==0){// final value from vector for pin 6

i=0;// go to first value of vector

OK=1;//enable pin 5


if(i>313 && OK==1){// final value from vector for pin 5

i=0;//go to first value of vector

OK=0;//enable pin 6


x=sinPWM[i];// x take the value from vector corresponding to position i(i is zero indexed)

i=i+1;// go to the next position


OCR0B=0;//make pin 5 0

OCR0A=x;//enable pin 6 to corresponding duty cycle


OCR0A=0;//make pin 6 0

OCR0B=x;//enable pin 5 to corresponding duty cycle



Step 4: Driving a H Bridge and Filtering the Pwm Signal

The signals obtain from arduino are the control part for inverter aplications because both are positive. To make a full sine wave and a practical inverter we have to use a h bridge and to clear the pwm a low pass filter.

The H-bridge is presented here.

The low-pass filter tested with small Ac motors-here.

Be the First to Share


    • Made with Math Contest

      Made with Math Contest
    • Multi-Discipline Contest

      Multi-Discipline Contest
    • Robotics Contest

      Robotics Contest

    4 Discussions


    9 months ago

    How would I mod this for 120v / 60 hz? Not understanding the relationship between ms and hz.


    Reply 1 year ago

    i hope there is no problem because i put some links to my webpage but without the pwm types and interrupts it can't be done(at least how i've done)