Contents:
- 2023 Multiple PID Controllers
- 2021 PID Cascade single file version
- 2014 PID Cascade VS structure version
1. Multiple PID controllers run simutaneously (example code 2023)
LiuZe, May 27, 2023
Recently we need realize 7 embedded PID controllers run simultaneously in a project. Then we use the OOP Class written before created a multiple-controller example. In the example the number of controller and object are 30. This piece of code is as following.
#include <stdio.h>
class ConObject {
public:
double alpha; // Object parameter
double *Ui, Uo, Uo1;
public:
ConObject() {
alpha = 0.1;
Uo = 0; // Zewen found this important
Uo1 = 0;
}
void Run() {
Uo = alpha * (*Ui) + (1 - alpha) * Uo1; //Object Simu
Uo1 = Uo;
}
};
class PID_controller {
public:
double *sp;
double *pv, cv;
double kp, ki, kd;
double Err, Err1;
double sum;
public:
PID_controller() {
kp = 6;
ki = 1;
kd = 0.5;
Err1 = 0;
sum = 0;
cv = 0;
}
void Run() {
Err = (*sp) - (*pv);
sum += Err; //sum = sum + Err;
cv = kp * Err + ki * sum + kd * (Err - Err1); //PID
Err1 = Err;
}
};
int main()
{
const int N_total_controller = 30;
int i, j;
double sp[N_total_controller];
ConObject Obj[N_total_controller]; // Objects
PID_controller Con[N_total_controller]; // Controllers
FILE* fp; fp = fopen("Control_output.csv", "w+");
// Print data
fprintf(fp, "i,");
for (i = 0; i < N_total_controller; i++) {
fprintf(fp, "pv%d,",i+1);
}
fprintf(fp, "\n");
for (i = 0; i < N_total_controller+1; i++) {
fprintf(fp, "0,");
}
fprintf(fp, "\n");
// Sp setting
for (i = 0; i < N_total_controller; i++) {
sp[i] = 4 + 0.2 * i;
}
// Parameter set in group or specific
for (i = 0; i < N_total_controller; i++) {
Con[i].kp = 6.2;
}
Con[2].kp = 4;
Con[4].ki = 1.2;
Obj[5].alpha = 0.12;
// Control loop connections
for (i = 0; i < N_total_controller; i++) {
Con[i].sp = &sp[i];
Con[i].pv = &(Obj[i].Uo);
Obj[i].Ui = &(Con[i].cv);
}
// System running
for (i = 0; i < 100; i++) {
fprintf(fp, "%d,", i + 1);
for (j = 0; j < N_total_controller; j++) {
Con[j].Run();
Obj[j].Run();
fprintf(fp, "%f,", Obj[j].Uo);
}
fprintf(fp, "\n");
}
//=====================
fclose(fp);
return 0;
}
The running result is recorded in the excel file of the project. The PV graph drawing according to the excel file is as following.

Fig.1 PV value of 30 simulated objects controlled by 30 PID controllers
2. Simulation of PID OOP Cascade System with Visual C++ (2021)
LiuZe, April 10, 2021

2021 We rewrite the cascade PID control program in one single CPP file as following:
#include <stdio.h>
class ConObject{
public:
double alpha; // Object parameter
double *Ui, Uo, Uo1;
public:
ConObject(){
alpha=0.1;
Uo=0; // Zewen found this important
Uo1=0;
}
void Run(){
Uo= alpha * (*Ui) + (1-alpha) * Uo1; //Object Simu
Uo1=Uo;
}
};
class PID_controller{
public:
double *sp;
double *pv,cv;
double kp,ki,kd;
double Err, Err1;
double sum;
public:
PID_controller(){
kp=6;
ki=1;
kd=0.5;
Err1=0;
sum=0;
}
void Run(){
Err=(*sp)-(*pv);
sum+=Err; //sum = sum + Err;
cv=kp*Err + ki*sum + kd * (Err-Err1); //PID
Err1=Err;
}
};
int main()
{
double sp=5.0;
ConObject Obj1,Obj2; // Objects
PID_controller Con1,Con2; // Controllers
FILE * fp;fp = fopen ("Control_output.csv", "w+");
fprintf(fp, "i, pv\n"); fprintf(fp, "0, 0\n");
Con1.sp=&sp; //No.1 Connection
Con1.pv=&(Obj2.Uo); //No.2
Con2.sp=&(Con1.cv); //3
Con2.pv=&(Obj1.Uo); //4
Obj1.Ui=&(Con2.cv); //5
Obj2.Ui=&(Obj1.Uo); //6
for(int i=0;i<100;i++){
Con1.Run();
Con2.Run();
Obj1.Run();
Obj2.Run();
fprintf(fp, "%d, %f\n",i+1,Obj2.Uo);
}
//=====================
fclose(fp);
return 0;
}
3 Simulation of PID OOP Cascade System with Visual C++ (2014)
LiuZe, April 1st, 2014
Full Program Download (2014 version):
PID control source code (Visual C++ 6 Version)
PID control source code (Visual Studio Version)
Design Introduction: PPT instruction download
Part of programs is as follows:
// PID_OOP.cpp : PID control program MAIN.
// Designed by Students and Teacher
// in the class of Intelligent Instrument Design
// Date: 2014-03-28
// MagtomoLab: http://emt.bjtu.edu.cn
// BJTU: http://www.bjtu.edu.cn
// -----------------------------------------------
#include "stdafx.h"
#include "PID_Controller.h"
#include "RC_Object.h"
int main(int argc, char* argv[])
{
FILE *fp;
double sp=2.5;
PID_Controller con1,con2;
RC_Object obj1,obj2;
// Initialize
con1.Initialization();
obj1.Initialization();
con2.Initialization();
obj2.Initialization();
// Customized Setting
con1.kp=2.0;
con1.ki=1;
con2.ki=1.2;
// Connection
con2.pointer_sp=&sp;
con1.pointer_sp=&con2.cv;
obj1.pointer_cv=&con1.cv;
obj2.pointer_cv=&obj1.pv;
con2.pointer_pv=&obj2.pv;
con1.pointer_pv=&obj1.pv;
// Run
fp=fopen("Record.csv","wt");
fprintf(fp, "pv\n");
for (int k=0;k<100;k++)
{ //Print result
fprintf(fp, "%f\n", obj2.pv);
con2.Calculate();
con1.Calculate();
obj1.Calculate();
obj2.Calculate();
}
fclose(fp);
printf("Finished!\n");
return 0;
}