I am trying to simulate a microcontroller controlled boost converter on Simulink. Because Simulink doesn't have a microcontroller, I wrote a MATLAB function that emulates one.
In case you're wondering why I'm doing this instead of using a PID control block (which is native to Simulink), it's because I'm going to make an STM32 controlled DC-DC converter, which is why I am trying to emulate a microcontroller.
Before I explain the problem, let me explain the MCU function. The MCU function has two inputs: ADC0 and ADC1. These inputs read an analog value and convert it into a 12-bit equivalent value (which you will see in a bit). I am feeding the output voltage to ADC0 and the reference voltage to ADC1.
The MUC function has one output: Dcontrol. This outputs a value between 0 and 1, which is fed to a PWM block. The output Dcontrol is calculated using a praportional-integral (PI) algorithm.
function Dcontrol = MCU(ADC0, ADC1)
%Initialising the integral error term to zero
err_I = 0;
%This, as I shall demonstrate, causes a problem.
%Converting inputs into 12-bit equivalent value
Vout = (ADC0/3.3)*4096;
Vref = (ADC1/3.3)*4096;
%Calculating the error, i.e., difference between set-point and
%measured-value
err = Vref - Vout;
%Calculating the proporational error
err_P = err;
%Calculating the integral error
err_I = err_I + err;
%Saturating err_I to prevent integral windup
if(err_I > 800)
err_I = 800;
end
if(err_I < 0)
err_I = 0;
end
%Saturating err_P
if(err_P > 100)
err_P = 100;
end
if(err_P < -100)
err_P = -100;
end
%Calculating PI
PI = err_I + err_P;
%Disallowing a negaive PI value
if(PI < 0)
PI = 0;
end
%The dutycycle control output is PI/1000, which gives a max dutycycle of 0.9
Dcontrol = PI/1000;
end
The equivalent circuit using the native PI control block looks like this:
I'm just showing this for clarity.
Coming back to the microcontroller circuit, I've set the reference voltage to 3V, which should give me 30V at the output. But when I run the simulation, this happens:
My output voltage is around 26V. This is due to the following line in the code
%Initialising the integral error term to zero
err_I = 0;
Every time the MCU function runs, the integral error gets initialised to zero. This results in the error term (and hence Dcontrol) getting improperly calculated. If I change my input voltage, the output voltage also changes. This is due to the integral term getting reinitialised. If is remove that line, I get an error:
Undefined function or variable 'err_I'. The first assignment to a local variable determines its class.
So my question is - is there a way to initialise the integral error term during runtime only, the way it's possible with the native PID block?
In other words, I want to modify the code to have this effect
%Initialising the integral error term to zero
void setup()
{
err_I = 0;
}
void loop()
{
%Converting inputs into 12-bit equivalent value
Vout = (ADC0/3.3)*4096;
Vref = (ADC1/3.3)*4096;
%Calculating the error, i.e., difference between set-point and
%measured-value
err = Vref - Vout;
%Calculating the proporational error
err_P = err;
%Calculating the integral error
err_I = err_I + err;
%Saturating err_I to prevent integral windup
if(err_I > 800)
err_I = 800;
end
if(err_I < 0)
err_I = 0;
end
%Saturating err_P
if(err_P > 100)
err_P = 100;
end
if(err_P < -100)
err_P = -100;
end
%Calculating PI
PI = err_I + err_P;
%Disallowing a negaive PI value
if(PI < 0)
PI = 0;
end
%The dutycycle control output is PI/1000, which gives a max dutycycle of 0.9
Dcontrol = PI/1000;
end
}
err_I
is reset everytime the function is called, so if (if) it's called 100 times, it will be reset 100 times. Maybe it will help to seterr_i
as a global parameter that is initialized to zero before the simulation and then leave the function to do what it wills with it? \$\endgroup\$err_I=0
and useerr_I
as a global parameter, before the simulation starts. IIRC, it works that way, too. But only vague memories. \$\endgroup\$