Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Help:O/P Voltage Feedback correction

abicash

Member
Hello

I am correcting the o/p voltage of a PWM sine inverter.
PWM Freq = 8KHz (PWM updates every 125us)
Duty correction loop : 1KHz (duty updates every 1ms)

i have a feedback from the o/p as below
Inverter o/p-->step down transformer-->rectifier-->filter-->ADC

With a DC value received for the o/p AC voltage , i implemented an ON/OFF control loop to control the duty of the PWM as such

Code:
if(OpVoltage < SetV)
{
   Duty++;
if(Duty>DutyMax)Duty=DutyMax;
}else
{
  Duty--;
if(Duty<DutyMin)Duty=DutyMin;
}

I observe that the o/p voltage is not stable and varies within 2Vac

How should i correct this behaviour?

All help appreciated..

Best Regards
 
With your code you only allow for two possibilities, >setV and not>setV. Because of this your duty cycle will all ways be oscillating. The frequency and amplitude of this oscillation will depend on how many times you run the above code in one update period.

I suggest adding some hysteresis to you code. So >SetVMax or <SetVMin, for anything else do nothing.
 
Hi and Thanks Misterbenn for replying

Yes i have already tried what you say

Code:
if(InvVoltage<SetVoltage+offset)
         {
            DutyStep++;
            if (DutyStep > 99) DutyStep = 99;
        
         } else if(InvVoltage>SetVoltage-offset)
            {
              if (DutyStep > 0)
                DutyStep--;
             
             }

But without any great change in behaviour.
Tried values of "offset" up to 10. Since InvVoltage & SetVoltage are 10-bit values
 
No that wont work. The voltage will increase and then as soon as it is greater than SetVoltage+offset it will start decreasing the duty cycle until it is less than SetVoltage+offset and then it will increase again. i.e. its not stable and will just oscillate.

Try this,
Code:
if(InvVoltage>SetVoltage+offset)
          {
               if (DutyStep > 0)
                 DutyStep--;
       
          } else if(InvVoltage<SetVoltage-offset)
             {
             DutyStep++;
             if (DutyStep > 99) DutyStep = 99;
            
              }

Not sure what you're InvVoltage resolution is but I'd set it to maybe 5LSB depending on how much noise you have in the system
 
Hi Misterbenn

Thanks again.

I tried that too (the moment i posted it i realised it was wrong and corrected and tested it)

My o/p voltage varies around a value with this.
My InvVoltage too is a 10-bit value although it is just a filtered replica of the o/p voltage and has some ripple.

How is this normally done in practice?
 
I'm not sure what DutyStep is controlling? presumably the peak duty cycle for you sin wave?

For the feedback you have to be carful with the frequency:
-It has to be less than the fundamental frequency of the sine wave you are trying to create and you will need to average the o/p voltage over that period.
-It also has to be a derivative of the fundamental frequency of the sine wave.
this is due to the beat effect, basically if the frequency's aren't well matched then you might be measuring a peak voltage and working out the duty cycle based on that.
so if you are making a 100Hz sine wave you'll need a 50Hz refresh rate, 100Hz might work but is likely to be more unstable.

Good filtering will help but you'll always get some ripple.

Usually space vector modulation is used and the feedback would have a PI controller to ensure a good response. At the moment you only have a P controller which will always have an offset.
 
Thank you Misterbenn
Much appreaciated.

DutyStep controls peak duty cycle for you sine wave as you correctly speculated.

My sine freq is 50Hz and my refresh rate is 1KHz.

Can you throw some light on your last sentences
"Usually space vector modulation is used and the feedback would have a PI controller to ensure a good response. At the moment you only have a P controller which will always have an offset."
 
Your refresh rate is to high.

You'll have 100Hz ripple on your output due to the rectified sine, even with the best filtering. So at one point you'll measure the peak and thus reduce Dutystep and at another point you'll measure the trough and thus increase Dutystep. This will cause oscillation.

You'll want to collect measurements over at least one sine period and average these measurements. From the calculated average you'll then update your dutystep at a frequency of 50Hz
 
Last edited:
Hello Misterbenn

Tried this.
Oscillations have stopped completely.
Although recovery on loaded conditions is poor.

I have a 625 us timer loop.On each interrupt ,i collect a sample of the feedback voltage.I add 32 samples(20ms) and average.
On this value, i update the duty.
Is this right? or am i missing something?
 
That's right, well done great to hear you've got rid of oscillation.

Now lets improve that transient response.
Currently you change your Dutystep by a fixed value of 1 LSB every 20ms. So if you suddenly load your output and Dutystep needs to increase by 10LSB that's going to take 200ms to do ... which is a slow recovery. At a guess I'd say we could get this down to 60ms, any faster and we'd need to use significantly more complex code.

The first step is to implement proportional control, google it and you'll find some good websites.
The basic idea is that the amplitude of your correction factor is proportional to the difference between desired and measured output.
So for example you'll want to have something like the following for increasing Dutystep
Code:
measuredValue - desiredValue =errorValue
Dutystep = Dutystep + (errorValue * Gain)
if (DutyStep > 99) DutyStep = 99;

Start off with a low gain and gradually increase it until you start to see slight oscillation during transient step response (sudden application of a load). Be aware that you may well need a gain of less than 1, you'll need to know the basics of bit multiplication.
 
Hello again
I included a PID control library for my project.

Somehow i am not able to tune it properly.
These are few parameters

Code:
#include "ECLIB_ControllerPI16.h"
signed int Error,DutyStep;
static ECLIB_sPIparams pPIparams; /* pointer to output phases */
void main(void)
{
pPIparams.propGain = 200;
pPIparams.propGainShift = -3;
pPIparams.intGain = 120;
pPIparams.intGainShift = -5;
pPIparams.upperLimit = 99;
pPIparams.lowerLimit = 0;
pPIparams.integralPortionK_1 = 0;
Error = SetVoltage - InvVoltage;
DutyStep = ECLIB_ControllerPI16(Error, &pPIparams);
}

The parameters are defined such
Code:
pPIparams.propGain : unsigned char 0...100%
pPIparams.propGainShift: signed char positive value - shift left
                                           negative value - shift right
pPIparams.intGain : unsigned char 0...100%
pPIparams.intGainShift : signed char positive value - shift left
                                           negative value - shift right
pPIparams.upperLimit : signed int upper limitation value
pPIparams.lowerLimit : signed int lower limitation value
pPIparams.integralPortionK_1:  signed int integral portion sum

With my settings
1)I get oscillations free o/p at 230Vac
2)Once a Load is added at o/p, recovery is not possible, voltage stays at 223Vac

Changing the parameters have some undesired response like oscillations are introduced, but recovery is good.

Can you please guide me with this?

The library is from Freescale
 
How did you get to these values?

Looking at your code you've set the propgain to 200, and intgain to 120, the limits are 0-99
"
pPIparams.upperLimit = 99;
pPIparams.lowerLimit = 0;"

I may have misunderstood the code, I haven't looked closely, but your values look rubbish to me. Not sure what gainshift does.

I'd advise setting int gain to zero and just using propgain for now, start at 1 and increase until it starts going unstable.
 
Hi Misterbenn

gain values are scaled as 0-255 = 0-100%

When i set intgain = 0, the o/p voltage never rises above 70-80VAC at the o/p
in my earlier post i have placed a link to the pdf file of the library ..if you are kind enough to take a look ...
gainshift will provide the step increase or decrease to the gain values (as i understood)
 
Hello again.

Few observations and a mistake i was committing.

My Battery voltage had dropped to a hazardous low. Due to which what i was measuring was totally wrong.
I installed new batteries and took few readings which i would like to share.

I started with
-> Prop gain at max 100% and integral gain at 0.
= O/P voltage doesn't rise above 20Vac

->Prop gain at max 100% and integral gain at 10%
= O/p voltage increases a bit but no major difference.

->Gradually decreased Prop gain and increased integral gain
= At no load on o/p, voltage is 230VAC and if it is loaded by a 100w load, voltage shoots to 256Vac and stays there
with load removed, the voltage goes back to 230Vac

It seems i am totally lost now :arghh:
 
Revisiting after a long time...
Was hooked up with other things so could not invest time in this project.

After everything failing in my feedback correction algorithm.I have done this.
I generate a sinewave and get a full rectified feedback (as in attached PDF document)
At exact peak i measure the voltage- INV_VOLT
I have a variable voltage SET_V through a pot (0-5v)

I have 100 rows of 32 sine weighted variables each (1-100% duty)

At every ZCD event , i compare the SET_V and INV_VOLT and increase or decrease the row index.

This has a good effect a better stable sine wave, but not very stable , some oscillations are present within 1v.
another effect is on loading, the voltage drops by 4-5 volts (NO LOAD = 230VAC)

Can anyone throw some light?Misterbenn??

Please remember , i correct o/p every 10ms.
 

Attachments

You seem to be making changes in a somewhat random fashion. I suggest you sit back and think about how the control loop is really working. You may want to try a type of control which basically uses a series of If-Then-Else loops, with typically no multiplication/division required, and is fairly intuitive to tune for optimum response.
 
Did you look at the tutorial Fuzzy Logic page I posted?

The simplest way is to do IF-Then-Else statements of the form:
If the error is large Then the correction change is large Else
If
the error is medium Then the correction change is medium Else
If
the error is small Then the correction change is small Else
If
the error is zero Then the correction change is zero Else
Etc.

You use as many If-Then-Else statements as needed while tweaking the "error" and "change" parameter value ranges to get the desired response. This can generally be most easily determined by trial and error.
 
Last edited:

Latest threads

Back
Top