4

I recently started developing a digital regulator for a DCM boost (Digital regulator for DCM Boost - How does it relate to duty cycle?) And I've implemented the difference the following controller in C:

$$ G_{Z} = \frac{1.39 z^{-1} - 1.332z^{-2} }{2 - 2.002{z^{-1}} + 0.002031z^{-2}} $$

in terms of a difference equation:

$$ y[n] = 1.001\cdot y[n-1] - 0.0010155 \cdot y[n-2] + 0.695\cdot x[n-1] - 0.666 \cdot x[n-2] $$

My code is as follows:

// Digi Reg Coeffs
const float a1 = 1.001;
const float a2 = -0.0010155;

const float b0 = 0.0;   
const float b1 = 0.6975;   
const float b2 = -0.666;

typedef struct 
{

    float y0;   // new reg value
    float y1;   // last reg value
    float y2;   // last^2 reg value

    float x0;   // latest sample
    float x1;   // last sample
    float x2;   // last^2 sample

} voltage_control;

uint16_t DigitalRegulator(float error) {

    float duty = 0;

    voltage_control.x2 = voltage_control.x1;
    voltage_control.x1 = voltage_control.x0;     
    voltage_control.x0 = error;   /// this is the new sample

    voltage_control.y2 = voltage_control.y1;
    voltage_control.y1 = voltage_control.y0;

    //calc new y0
    voltage_control.y0 = (a1 * voltage_control.y1) + (a2 * voltage_control.y2) + (b0 * voltage_control.x0) + (b1 * voltage_control.x1) + (b2 * voltage_control.x2);


    // new value for PWM
    duty = (voltage_control.y0 / PWM_GAIN) * PERIOD_VALUE;

    return duty;

}

Is this the correct way to implement a difference equation? I'm asking because the resulting controller seems unstable, and I'd like to know if it's my implementation or something else.

pipe
  • 13,748
  • 5
  • 42
  • 72
  • Have you tried doing a linear model (in a sim) to make sure it doesn't go unstable - boost converters can be awfully tricky to get the control algorithm correct. – Andy aka May 07 '20 at 17:19
  • I'm not sure what you mean by a linear model, do you mean in a circuit simulator like LTspice? If so, not yet, but its a great idea, I can implement the Laplace and see if it's stable – JustAnEngineer May 07 '20 at 17:54
  • Yes, that’s what I mean. – Andy aka May 07 '20 at 18:16
  • Your coeffs in the G_C formula vary by 5-6 orders of magnitude, but your multipliers in your difference equation do not. ALSO, not sure how you can write a difference equation based on a formula using _s_ instead of _z_, where 1/_z_ represents a 1-unit delay. *BUT* ignoring both of those, 1.905-0.9048 is greater than 1, so according to your diff equation, with ZERO input, your y's WILL go to infinity (each new y is "approximately" 1.0002 times the average-ish of the previous two, which grows without bound). – Atomique May 07 '20 at 19:31
  • Hi Atomique, I jumped a step as I didn't think it was important, but you're quite right I should have it there. You're also right that this Laplace equation is not the correct one for the difference equation I wrote (face palm). However, it is the difference equation I implemented in C so what you have written may be my solution. Does this mean the S domain equation I had is not realisable? PS I've edited the question to reflect the correct Z transfer function – JustAnEngineer May 07 '20 at 19:48
  • you might post questions like this to the [DSP Stack Exchange](https://dsp.stackexchange.com/). that's where it belongs. – robert bristow-johnson May 08 '20 at 02:29
  • 1
    your transfer function for \$G_Z\$ does not match your difference equation for \$y[n]\$. you have to multiply both numerator and denominator by \$\frac12\$ and then the coefficients should match except for a sign change regarding the denominator coefficients. – robert bristow-johnson May 08 '20 at 02:33
  • I updated the question again, I updated this late alst night and did it wrong. I still think my issue might be related to what @Atomique - is there a way to know if the equation is realisable ? – JustAnEngineer May 08 '20 at 06:53
  • The floating point constants should be `1.001f` and so on. Don't sloppily mix `float` and `double`, keep one precision and stick to it. – Lundin May 08 '20 at 06:58
  • no @JustAnEngineer, your coefficients in the difference equation are wrong. take your difference equation, apply the Z transform to every term on both sides and solve for \$Y(z)\$ in terms of \$X(z)\$. (i think you got the numerator and denominator swapped.) – robert bristow-johnson May 08 '20 at 16:05
  • @robertbristow-johnson you're quite right - I had them swapped in the question, but in the C code they are correct. I did notice that in my C code the b2 coefficient was negative, and my difference equation in C was already subtracting this and causing a double negative - so perhaps this was the reason for the instability. I'm currently doing what Andy-aka mentioned which was take the laplace form and model the boost in LTSpice, and see if it's okay – JustAnEngineer May 08 '20 at 16:53

0 Answers0