Due to the high interest I would like to ask some help in translating the PID library written by above mentioned gentlemen. If we find the final solution this could be uploaded to the libstock. (If Ahmed and Daniel agree, of course.)
First, let me show you the basic-C translation. Please help to develop the code together.
I couldn't find the definition of the variable Result in the Basic source, so I defined as global variable. If I made a mistake, please correct it.
Code: Select all
/*******************************************************************************
----------------------------------------------------------
---- PID library with fixed calculation time interval ----
----------------------------------------------------------
Ahmed Lazreg
ahmed.lazreg@pocketmt.com
Translated from original mikroPascal code from D.Rosseel
D. Rosseel
Original: 27-09-2011
Latest update: 27-09-2011
History:
29-09-2011: Translation from Pascal Code to MikroBasic
27-09-2011: Original Version (in mikroPascal).
Documentation: http://en.wikipedia.org/wiki/PID_controller/ and
http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/
*******************************************************************************/
Init_PID(float Kp, float Ki, float Kd, float MinOutput, float MaxOutput);
/* Initialises the PID engine
Kp = the "proportional" error multiplier
Ki = the "integrated value" error multiplier
Kd = the "derivative" error multiplier
MinOutput = the minimal value the output value can have (should be < 0)
MaxOutput = the maximal value the output can have (should be > 0)
*/
Reset_PID();
/* Re-initialises the PID engine without change of settings */
PID_Calculate(float Setpoint, float InputValue);
/* To be called at a regular time interval (e.g. every 100 msec)
Setpoint: the target value for "InputValue" to be reached
InputValue: the actual value measured in the system
Function: PID function of (SetPoint - InputValue),
a positive value means "InputValue" is too low (< SetPoint),
the process should take action to increase it
a negative value means "InputValue" is too high (> SetPoint),
the process should take action to decrease it
*/
float PID_Kp, PID_Ki, PID_Kd;
float PID_Integrated;
float PID_Prev_Input;
float PID_MinOutput, PID_MaxOutput;
float Result;
char PID_First_Time;
void Reset_PID() {
PID_Integrated = 0.0;
PID_Prev_Input = 0.0;
PID_First_Time = 1;
}
void Init_PID(float Kp, float Ki, float Kd, float MinOutput, float MaxOutput) {
PID_Kp = Kp;
PID_Ki = Ki;
PID_Kd = Kd;
PID_MinOutput = MinOutput;
PID_MaxOutput = MaxOutput;
PID_Integrated = 0.0;
PID_Prev_Input = 0.0;
PID_First_Time = 1;
}
void PID_Calculate(float Setpoint, float InputValue) {
float TheErr, ErrValue, DiffValue;
TheErr = SetPoint - InputValue;
// --- calculate proportional value ---
ErrValue = TheErr * PID_Kp;
// --- Calculate integrated value ---
PID_Integrated = PID_Integrated + (TheErr * PID_Ki);
// limit it to output minimum and maximum
if(PID_Integrated < PID_MinOutput then) {PID_Integrated = PID_MinOutput;}
if(PID_Integrated > PID_MaxOutput) {PID_Integrated = PID_MaxOutput;}
// --- calculate derivative value ---
if(PID_First_Time) { // to avoid a huge DiffValue the first time (PID_Prev_Input = 0)
PID_First_Time = 0;
PID_Prev_Input = InputValue;
}
DiffValue = (InputValue - PID_Prev_Input) * PID_Kd;
PID_Prev_Input = InputValue;
// --- calculate total ---
Result = ErrValue + PID_Integrated - DiffValue; // mind the minus sign!!!
// limit it to output minimum and maximum
if(Result < PID_MinOutput) {Result = PID_MinOutput;}
if(Result > PID_MaxOutput) {Result = PID_MaxOutput;}
}