Variable Frequency Inverter

Help me by sharing this post

PREVIOUS TUTORIAL       NEXT TUTORIAL

Please see the past Inverter tutorial for all the details. Here we will just add freqeucny cahnge to the code. We all know PWM signal or pulse width modulation. That means we modulate the width of a square signal and by that we could control power. But, this width in case of normal PWM is alweys the same. In case of SPWM or sinusoidal pulse width modulation, the width of the signal is increasing and decreaseing and my that simulating the curve of the sine wave. With small width pulse, the output will incrase a little bit and that represents the zone after the 0 cross of the sine wave. Then with bigger widths, the output is getting bigger and bigger and then it starts to get lower, just as a sine wave. Uisng two mosfets, we could get both the positive and negative sides of the sine wave.

PART 1 - Schematic (no feedback)

We look over this basic inverter schematic that has no feedback. That means the load can change the output and we won't be able to tell. Any way, we have a driver connected to the MOSFET bridge. The signal will be applied by an Arduino that will create an SPWM signal a variable frequency. Take a look over the schematic and let's talk about SPWM signal as well.

PART 2 - Code

S0, how can we create this SPWM signal? Well, with the Arduino, in the code, we make two pins to be PWM pins by setting some registers, TCCR1B and TCCR1A. Now e have to change the width of this signal by changing the value of the OCR1A. But what values we need to use. Well, these are not random values, they musy follow a sine shape curve. So, by knowing the range of the min and max of the PWM signal and using an Excel sheet, we could create values of a sine curve from 0 to 180 degrees. We store those values in a vector as you can see below in the example bit of code.

``````#include <avr/io.h>
#include

//sum is 51,720
// Look up tables with 200 entries each, normalised to have max value of 1600 which is the period of the PWM loaded into register ICR1.
float lookUp1[] = {
50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,
542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,
981 ,1020 ,1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,
1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,
1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 ,1597 ,1599 ,1600 ,
1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,
1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,
1264 ,1233 ,1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,
899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,
446 ,398 ,349 ,300 ,250 ,201 ,151 ,100 ,50 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0};

float lookUp2[] = {
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,
542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,
981 ,1020 ,1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,
1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,
1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 ,1597 ,1599 ,1600 ,
1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,
1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,
1264 ,1233 ,1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,
899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,
446 ,398 ,349 ,300 ,250 ,201 ,151 ,100 ,50 ,0};

int freq = 1600;
float ratio = 1;
bool D9 =  true;

void setup(){
// Register initilisation, see datasheet for more detail.
TCCR1A = 0b10100010;
/*10 clear on match, set at BOTTOM for compA.
10 clear on match, set at BOTTOM for compB.
00
10 WGM1 1:0 for waveform 15.
*/
TCCR1B = 0b00011001;
/*000
11 WGM1 3:2 for waveform 15.
001 no prescale on the counter.
*/
TIMSK1 = 0b00000001;
/*0000000
1 TOV1 Flag interrupt enable.
*/
ICR1   = 1600;     // Period for 16MHz crystal, for a switching frequency of 100KHz for 200 subdevisions per 50Hz sin wave cycle.
sei();             // Enable global interrupts.
DDRB = 0b00001111; // Set PB1 and PB2 as outputs.
pinMode(13,OUTPUT);
}

void loop(){

ICR1 = freq;
ratio = 1600/freq;

}

ISR(TIMER1_OVF_vect){
static int num;
// change duty-cycle every period.
OCR1A = lookUp1[num] * ratio;         //D9
OCR1B = lookUp2[num] * ratio;         //D10

if(++num >= 100)
{ // Pre-increment num then check it's below 200.
if(D9)
{

D9 = false;
}
}

if(++num >= 200)
{ // Pre-increment num then check it's below 200.
num = 0;       // Reset num.
if(!D9)
{
PORTB |= B00000001;             //D8 HIGH
PORTB &= B11110111;             //D11 LOW
D9 = true;
}
}

}
``````

Help me by sharing this post

Variable inverter page 1/1

Alfawise U30 2.8 inch Touch Screen DIY Desktop 3D Printer - U30 EU Plug Black only \$\$162.89

AFFILATE

Creality3D CR - 10S 3D Printer - EU Plug Upgrade Version Coffee and Black only \$\$352.94

Creality 3D Ender-3 V-slot Prusa I3 DIY 3D Printer Kit 220 x 220 x 250mm Printing Size - EU Plug Black only \$\$153.84

Alfawise U20 Large Scale 2.8 inch Touch Screen DIY 3D Printer - EU - U20 EU Plug Black only \$\$253.39