Various aspects of home brew inverters

Author Message


Joined: 02/02/2017
Location: Australia
Posts: 1364
Posted: 03:54pm 08 Mar 2017      

It's my firm view that mosfets feel no pain.

It was mentioned in another forum (,1228.msg13370.html#msg13370) that maybe syncronising to mains might be a good idea to look at since the EG8010 has no capability to do so.

Part 2: Mains sync

I have a few Arduino boards, mainly using the ATMega 328P (Uno boards, and similar)
and also a couple of Due boards using Atmel SAM3 chips running at 84MHz which is much faster than the Uno at 16MHz. The SAM3 chips have a 32bit ALU compared with the 16bit Uno.

I have my inverter test code runnning on a Due and wanted to get it to sync to an external input. For testing, the input will be a square wave, to gently introduce me to the ugly concepts of phase and frequency feedback loops. The Due is about 4-10x faster in most things and it has a huge data + program memory.

After a few hours I have a PLL working quite nicely, and you can see it in the below video

What to look for is the frequency of the input, shown at top right.
The yellow trace is input, the blue is low pass filtered 20KHz PWM output of the inverter program.
Note how it can track and lock onto the small changes I make to the input signal.

This was scary easy to hack up a quick feasibility test.

I found a document looking at AUS electric network frequency standard and it seems network connected mains will be 49.9 to 50.1Hz when running normally, and 49.75 to 50.25Hz during an unplanned outage. Island or separated systems (Hello Oztules!) have a standard of 49-51Hz for normal running. So the PLL does not need to lock on to and follow freq/phase changes of large proportions just +/- 0.5Hz or so.
How rapid will these excursions occur? Any information I can read online?

So at first glance I think I can do this. There then appear very significant issues such as:
- should we ever do this?
- when not in sync, the inverter will blow it's self to bits. How to protect against this?
- maybe OK for advanced DIY systems on electrical islands (hello Oztules! again)
- maybe OK in un(der) regulated jurisdictions
- I would probably be hung by the neck if I do this here in OZ

But it's fun to have a look at how and why...

The PLL work has another application and that is syncronising to another inverter.
This will let us design multiple units to run under a single regime.

rough program:
1/ during each 50Hz output, locate rising edge of external sync and record when it happens.
2/ at the end of the 50Hz wave, update both the 50Hz PWM period counter and the 20KHz SPWM so as to have the future output closer to the external sync phase and freq.

code snippets:

// all 16 bit integer math so it runs fast. This code runs about 300KHz so it's called
// very often so as to get best estimate of rising edge.
u = ADC->ADC_CDR[6]; // fast read of ADC channel 2 on Due
if(psc < 300) // only look for the edge in first 3/4 of 50Hz output
{ // u1, u0 get set to -1 at start of each 50Hz cycle elsewhere
if (u > 1500) // threshold for HI/LOW test of ext sync
u1 = 1;
u1 = 0;
if (u1 == 1 && u0 == 0) // we have the transition from low to high now
uedge = REG_PWM_CCNT1; // so record PWM clock source counter
u0 = u1;
if(psc == 200) // at end of 1/2 50Hz cycle, check ext sync
{ // to determine leading or lagging phase
if (u > 1500)
usign = 1;
usign = -1;


// this runs once at the beginning of each 50Hz output cycle.
if(burstcount > 3) // only alter the 50Hz period counter once each 4 times
{ // most importantly, the change in the period counter
burstcount=0; // for phase differences is not cumulative
pburst = (uedge - 26250)/4; // PWM period change value, if uedge = 26250 then
} // ext sync is exactly in phase
pburst = 0;
u = abs(uedge - 26250);
u2 = u2 - usign*(1+u/256); // need a trim factor for frequency which is cumulative
REG_PWM_CPRDUPD1 = 52500 + u2 + pburst; // update 50Hz PWM period register
REG_PWM_CDTYUPD1 = (52500 + u2 + pburst)/2;
// and maintain 50% duty cycle with new period
REG_PWM_CPRDUPD0 = PPWM + u2/10; // also change 20kHz period reg to suit shorter or longer
// "50Hz" output

Edited by poida 2017-03-10
wronger than a phone book full of wrong phone numbers