I posted this originally in the electronics stack exchange, as it's for an electronic purpose (digitally controlled boost) but it was pointed out to me that this would be the more appropriate place - so here goes!
As mentioned, I recently started developing a digital regulator for a DCM boost and I've implemented the following discrete transfer function in C:
$$ G_{Z} = \frac{1.39 z^{-1} - 1.332z^{-2} }{2 - 2.002{z^{-1}} + 0.002031z^{-2}} $$
and, in terms of a difference equation:
$$ y[n] = 0.695\cdot y[n-1] - 0.666 \cdot y[n-2] + 1.001\cdot x[n-1] - 0.0010155 \cdot x[n-2] $$
My code is as follows:
// Digi Reg Coeffs
const float a1 = 1.001;
const float a2 = 0.0010155;
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) +
(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.