Skip to content

PID Control C++ Programming

Background Music

Contents:

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

Structure of 2021 version

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

Control_Structure_640
2014 version structure

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;
}