Introduction: Grid Tie Inverter V2
This version takes a big step towards being transformerless (see version 1.0). It successfully injected 50 watts continuously into the grid with a THD <5% and efficiency >90%. The microcontroller is completely isolated from the DC bus and grid.
GTIs are fascinating and becoming more commonplace with the growth of renewable microgeneration. I haven't seen any "amateur projects" on this topic and I believe a well documented DIY circuit provides an insight one doesn't get elsewhere.
The big changes in this version 2 are:
- An isolated H-Bridge capable of working with voltages up to 450 volts and incorporating an isolated current sensor inline with the PWM output.
- An isolated voltage sensing module that measures the DC Bus and AC line voltage.
Step 1: Let's Discuss Our Strategy for Building This GTI:
- We use an H-Bridge and LC filter working together to act as a voltage source. The output can vary anywhere between +/- of the DC bus voltage and is proportional to the PWM duty cycle.
- We sample the grid voltage (at 10 ksps) and set our PWM duty to generate a voltage equal to the measured grid voltage. This results in a replica of the grid waveform. If we connect this to the grid, no current will flow as there is no voltage differential at any point. Accurate grid and bus voltage sensing is important so this “feedforward” controller works well.
- In order to push current into the grid we need a slight overvoltage.
- A sensor is used to measure the current exiting the H-Bridge. A PI controller varies the voltage about the feedforward value to achieve a current output setpoint. The PI control loop (which iterates at 10 kHz) should therefore add a slight overvoltage beyond the feedforward control necessary to drive the correct current into the grid at any one instant.
- We want to output a sinusoidal current in phase with the grid voltage.
- We simulate a 50 Hz sinusoidal local oscillator (LO) and use a PLL to synchronise the phase of this to the grid. This LO is used to continuously update the current output setpoint for the PI controller. As a result we ask for a sinusoidal current to be outputted in phase with the grid voltage.
- That’s it. We also add some safety mechanisms so if the grid frequency or voltage goes out of whack or our DC bus voltage goes too low or high etc we disconnect.
Step 2: Designing the H-Bridge
H-Bridge circuits are fairly standard but I wanted a few additional features:
- Isolation between the microcontroller side and high voltage side
- Accurate and isolated current sensing
- 450v capability
I found an awesome looking gate driver chip, the UCC21520. It offers isolation and stupendous switching specifications along with layout recommendations and component selection advice.
I also found an incredible current sensing chip, the AMC1306. It also offers isolation and layout examples. It’s called an isolated shunt modulator as it outputs a digital stream of 1s & 0s that have to be digitally filtered by a microcontroller. Set up correctly it can accurately obtain 16 bit ADC current readings at 20ksps!
I found some fancy 600v MOSFETs too. They had an Rds_on = 60mOhms and a Qg total of 67nC which isn’t bad for 600v spec. I liked the idea of separate gate driver pins. For comparison the 60v MOSFETs used in the DRV8301 dev board had an Rds_on = 4.7mOhms and a Qg total of 29nC.
The circuit is nothing more than an H-Bridge with an in-line current shunt sensor on the output. I popped all these components onto a PCB using Eagle. I tried very hard to minimise the inductance of the gate drive paths by keeping them tight and short. I also tried to minimise the inductance between the DC bus capacitance and MOSFETs. I was very satisfied by the design.
I ordered from PCBway. Bloody hell they’re fast! I think I got the boards back in less than a week! I was impressed by the quality. It wasn’t difficult to solder the components onto the board.
Step 3: Testing the H-Bridge
I used a 75 V DC bus for initial testing. PWM was provided by an STM32F407 to the gate drivers. I used a 3S LiPo to provide an isolated 12V power supply for the gate switching.
Initially it seemed to work as expected. I was getting PWM on the outputs of the half-bridges. I noticed a small DC bus current (20-30mA) was being drawn despite no load. I took no notice, connected 450V DC and promptly smelt smoke!
Luckily it seemed to just be the MOSFETs. A few weeks later I replaced them and was back where I started.
It was as though there was a capacitance in the region of 25nF grounding the output of each Half bridge. Increasing the PWM frequency and DC bus voltage both increased the pathological current. At 75v and 42KHz the current was resulting in 2 watts of heat dissipation and the MOSFETs were getting to 50℃. I needed these babies to handle 450v. What the hell was going on?
I tried everything I could think of from:
- Increasing the deadtime in software and hardware
- Changing the gate drive resistors from 4.7R to 10R to 22R
- Increasing the gate drive voltage
It was only the MOSFETS that were dissipating heat, all other components were behaving properly. Using my oscilloscope I could confirm there was no cross conduction going on or nasty ringing.
I even turned to Stackexchange for help. Someone suggested trying another MOSFET / IGBT.
I swapped out a pair of the fancy MOSFETS and tried some 100v MOSFETs. It then all worked perfectly! I can’t explain why that fixed the issue but it did. I ordered some standard 600V MOSFETS from Farnell (STF35N60DM2) , swapped them in as best I could (it’s not pretty) and eventually had myself an H-Bridge with my required specs. What an ordeal!
Step 4: Filter Design and Inductor Ripple
The job of the filter is to block the 40 kHz PWM carrier frequency but pass our 50 Hz signal. The illustration here shows our filter network in a simulated test setup:
- My inductor setup uses combinations of 1410524C 1mH inductors to create the above filter. These units have a 60% saturation at 2.4 A.
- The first parameter to look at is the resonant frequency. This works out to be 4.3 kHz which is away from any frequencies we’re injecting into the network. Good.
- We need an idea of the ripple current through the inductors. In the simulation I found a 6 mA ripple using what’s essentially a 2 V DC bus. Since it’s a linear circuit all numbers scale. Therefore we can expect a ripple of 150 mA with a 50 V DC bus or 300 mA with 100 volts. The capacitance and load resistances don't affect the ripple, just the PWM voltage swing and inductance.
- When we want to get rid of the transformer and directly produce 240 V AC we’ll need a DC bus voltage of 400 V. If we reconfigure our inductors to be in series this should quadruple our total inductance to 4mH and maintain a ripple of ~300mA. Such a series configuration would have a 2.4 A 60% saturation current so we’d have to keep peak currents below 2 A at most.
- Ferrite cores appear to work well at our frequencies.
Understanding the filter network has been the crux for me on this project. I know LCL filters are used in commercial inverters. But choosing the component values seems to involve black magic that I can’t get my head around yet.
It’s also fairly difficult to find massive inductors such as are used in commercial inverters. Where the hell do they come from? Stringing together a load of smaller inductors was the only solution I could decide upon.
Step 5: Filter Inductor Core Material and Saturation
I’ve had to learn about inductors during this project. They’re not as ideal as capacitors. Some core materials have unacceptable losses at high frequencies. Our PWM may be at 41 kHz but the fourier series of this is composed of harmonic frequencies much higher. Likely beyond 500 kHz.
Therefore the filter is subjected to very high frequencies and some inductors I tried dissipated a lot of heat. Presumably from hysteresis core losses. I think iron powder cores have this problem and I believe ferrite behaves better at higher frequencies.
Another area to be cautious about is saturation current. This is analogous to a capacitor’s max voltage rating. Again, core materials behave differently.
Some inductor data sheets quote a saturation current for when the inductor has lost 60% of its inductance. Well I don’t want the filter network deviating from its nominal by that much!
Step 6: Measuring Current
The AMC1306 Isolated shunt modulator used in this design outputs 1 & 0s at a rate of between 5-21MHz. The STM32F407 needs to receive these, process them and arrive at a 16 bit value at a rate of 20 kSPS. I must admit that even after I had designed and assembled this PCB I was in the dark as to how to do this processing.
The shunt resistor sits in-line with phase B and is 100mR. I chose the AMC1306M25 meaning that full scale output occurs at +/-250mv. This means we can measure +/-2.5Amps.
I’ve read that the optimal way to decode the data stream from the AMC1306 is to use a sinc3 filter. This TI article was key to my understanding of how these filters work and how to implement one. A block diagram of a sinc3 filter pictured.
I searched to find an already existing implementation of this but couldn’t find one. I then realised the software is actually pretty simple! We can configure the SPI of the STM32F407 to read at 5.25Mbits/s and transfer bytes into a circular buffer using the DMA. I went for a 256 downsampling ratio resulting in a 20.5KSP output rate. This works brilliantly because there are notches in the frequency response at multiples of the decimated sampling frequency. In our case this puts a notch at our PWM carrier frequency of 41KHz which is superb. The 3dB point of our filter is at 5.4KHz.
I used a double buffer method so the previous 256 bits are processed whilst the next 256 bits are collected. With bits coming in at 5.25Mbits/s the algorithm must be efficient. I estimated that as long as each bit is processed using less than 25 clocks on average there should be adequate CPU power.
The code to process a batch of 256 bits is in the images. PDM_Raw_Data is a 32 byte buffer that is filled with 1s and 0s from the current shunt modulator via SPI. From oldest to newest the bits are read and inserted into a cascade of 3 serial accumulators. The output of the 1st accumulator (aka. integrator) is put into the input of the second etc. You can see this clearly in the code.
Following the sequential insertion of 256 bits we do a single 3rd order differatiention on the output. This gives us a 24 bit reading which I scale and offset to get a 16 bit signed current measurement. So swanky!
What we’re essentially doing is integrating the input three times over each time a new bit comes in. Then once we’ve done this 256 times, we do a single third order differentiation (ie. differentiate 3 times in a row). We then repeat the cycle. I won’t delve into the specifics but this process gives us a 24 bit number every 256 clocks which is much more useful than a bunch of 1s and 0s.
Step 7: Testing the Current Sensing
These images show what we saw on the oscilloscope when generating 50 Hz sine and square waves. The red traces show the differential voltage (x50) across a load resistor (ie. proportional to the current). The blue traces are the STM32F407’s DAC outputting the measured current. This is amazing, they are exact replicas of each other. And there is no PWM carrier noise at 41KHz so the filter is clearly working well. I was very chuffed by this.
You may have noticed on the square wave a slight slope. The cause of that puzzles me… oh well.
Step 8: Measurement Delay of Current Sensing
You might notice a slight delay in the measured current relative to the actual current. This is expected and is because of the digital filtering we’re doing. To look at this more closely I took this snap shot.
I deduced a 180 us delay. On a 20 ms periodic signal this equates to a 𝚹 = 3.3 degree phase lag. The reason for the slow upslope of the actual current is due to our filter effectively suppressing high frequencies. All in all I think the control system will have adequate response times to work with.
Step 9: Isolated Voltage Sensing
I learnt in this second iteration of the GTI the importance of reliable and accurate voltage sensing. You need to know the DC Bus voltage together with the phase voltage. These are both critical in order to implement a decent feedforward filter.
I stumbled across the ISO224 Isolated voltage amplifier. We can use 2 to measure each of these voltages. Here is the schematic and board layouts. It’s fairly straightforward.
The ISO224 outputs a differential voltage. But it’s easy to make this single ended in software by subtracting the 2 ADC readings.
Step 10: Synchronising to the Grid and the PLL
The PLL runs in a periodic function. It automatically runs every 13125 clock ticks which on a 186 MHz processor equates to 12800/second which is 256 x 50 Hz. We store a 256 sample lookup table of sine values and by incrementing our lookup index at this rate we obtain samples for a 50 Hz sine wave. This makes up our local oscillator (LO).
The job of the PLL is to make slight adjustments to our LO frequency so it stays in phase with the grid voltage. We need to do this because our LO is used to set the output current setpoint. Let's talk through the code imaged:
The 1st line phase shifts our lookup index by 90 degrees (64/256) so that we have a cosine LO.
The 2nd line multiplies our LO cosine value by the sampled line voltage (which should be sine wave). We store this value as Signal_Multiple.
In the 3rd line we refresh our integral of the previous 256 Signal_Multiple values. The result of this is the integral of our cosine LO x sinusoidal Line_Voltage waveforms over the past 1 period. This equates to:
integral [Cos(wt) * Sin(wt + phi)] -> The result is cos(phi)
phi represents any phase shift between these 2 waveforms. The whole point of the PLL is to measure phi so we can adjust our LO frequency using it. Adjusting our LO frequency is easily done by incrementing our lookup table index at 13125 clocks +/- a small amount. By adjusting the LO frequency slightly we can bring phi to zero. Once phi is zero we can keep our LO frequency at a value that makes phi stay at 0. We employ a PI control loop here with the setpoint equal to zero. For example, if we are lagging in phase from the grid, our PLL will give phi = -100 say. We’ll then ensure we increment through our LO lookup index at 13025 clocks (instead of 13125). This increases our LO frequency which will mean the phase catches up with the grid’s.
To summarize, we want to adjust our LO frequency to make this integral result 0. We do this by using a PI control algorithm to vary the 13125 tick amount slightly. This locks our LO to be in phase with the line phase. It's a phase locked loop. It's actually pretty simple when you get your head around it. But you need to understand that the integral of Cos(x) x Sin(x) over 0 - 2pi is 0 etc.
Step 11: The PI Control Loop
The PI controller is responsible for adjusting the output voltage based on the measured output current. It has to respond quickly and therefore the control loop is run at 10 kHz. The desired output current at any one time (aka the setpoint) is varied sinusoidally in phase with the grid voltage by our local oscillator.
There are 2 tuning parameters for the PI control loop:
- Proportional constant (P)
- Integral constant (I)
I started with values of zero and gradually increased them until the control loop began to oscillate. Then reduced them down somewhat for stability. I have realised 2 things affect the tuning values:
- The load resistance. Larger load resistances will need a bigger “overvoltage” to achieve a given current output.
- DC Bus voltage. A given change in PWM duty will lead to a larger change in overvoltage at higher bus voltages.
With better tuned PI parameters we get tighter control. This results in:
- Outputting closer to our requested output current
- Less phase lag between the output current and the grid voltage.
I just found some values that seem to work but in future it would be good to look into normalising the tuning parameters so we compensate for such changes. I would like to try to measure the grid impedance by seeing what “overvoltage” results in what current flow etc.
Step 12: Connecting and Disconnecting From the Grid
We remain disconnected from the grid whilst our H-Bridge MOSFETs are all off. When this occurs, our AMC1306 current sensor shuts down since it relies on a bootstrapped power supply created via the PWM switching.
When disconnected we are still measuring the grid voltage and our PLL is keeping our LO synchronised. When we enable our H-Bridge we immediately start producing a voltage (proportional to our PWM duty). It is very important that this voltage is equal to the grid voltage otherwise a potentially damaging current will flow into or out of the H-Bridge.
To join the grid we wait for the zero crossing point (by waiting for our LO index to rollover to zero). We then enable the H-Bridge with a PWM duty of zero and we start our feedforward controller to track the voltage from there. This works great as shown in the picture.
After about 2 ms the AMC1306 current sensor is powered up and back in action. The software then enables PI control alongside the feedforward control.
Step 13: Anti-islanding
Similar to our last GTI we continually measure:
- The grid voltage
- The grid frequency
- The DC bus voltage
- The output current
- The error between our requested output current and the actual output current
If any of these parameters go out of whack and leave a given threshold we disconnect from the grid. This protects the circuit in the event of an error and supposedly those electricians working on a line during a power cut. See the image showing the blue output switching off after the red grid voltage disappears.
Step 14: Summary
I measured 51 Watts of output power and nothing was getting particularly warm even. There was definitely less than 5 Watts of heat being generated so I crudely concluded >90% efficiency.
The waveform here shows the transformer scaled grid voltage in blue. The red waveform shows the AMC1306 measured current flow into the grid. The is a slight phase lag and a small amount of ripple but it’s less than 5% THD.
Step 15: What's Next?
I’m very close to trying higher DC bus voltages but thought I’d post this update 1st. Things to do next:
- Try to measure grid impedance.
- Try to normalise our PI tuning parameters to be independent on impedance and bus voltage
- Try 100 W output power.
I hope this update was interesting or informative. I expect there are loads of unexplained concepts but GTIs are actually a rather massive topic to cover! Do comment in the comments section or email me.
Participated in the
Explore Science Challenge