# Is my IIR implementation (in C) correct for this difference equation?

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.

• 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. May 7, 2020 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 May 7, 2020 at 17:54
• Yes, that’s what I mean. May 7, 2020 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). May 7, 2020 at 19:31
• 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. May 8, 2020 at 2:33