Panel Cookies
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.


Arduino SPWM SINE inverter tutorial





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(){
  
  freq = map(analogRead(A0),0,1024,1000,3000);
  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;
      }
    }
     
}


Arduino SPWM SINE inverter tutorial frequency control





Help me by sharing this post












yt_link
insta_link
fb_link
twitter_link

Variable inverter
page 1/1



Affiliate Disclosure

ADVERTISERS



PCBWAY PCB service





Curso Arduino Online nivel bajo