Introduction: 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:
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
if(OK==0){
OCR0B=0;//make pin 5 0
OCR0A=x;//enable pin 6 to corresponding duty cycle
if(OK==1){
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.