pid working code for Anssi's lab

Dependencies:   mbed millis

PID.cpp

Committer:
nikitakl
Date:
2021-01-02
Revision:
4:4a3c3188e992
Parent:
3:70e0372dbf2e

File content as of revision 4:4a3c3188e992:

#include "mbed.h"
#include "millis.h"

#define threshold 0.009 

double Input, Output;
double Setpoint=0.10303030303 ; //=34/330;
// the setpoint was defined to be 34 degrees, since it was evidenced that the temperature
// can not fall under 33 degrees even when the fan is at full speed
unsigned long lastTime;
double errSum, lastErr;
// variables lastTime, errSum and lastErr are used in calculating I and D values
double kp, ki, kd;
int SampleTime = 1000; // SampleTime defines how ofter the PID function is called

AnalogIn temperature(p20); // pin p20 is used to read analog output from the temperature sensor
PwmOut fanControl(p21); //pin p21 is used to control the fan with PWM output signal

Ticker temperatureTicker;
int readTemperatureFlag=0;

void tickerFlagOn()
{
    readTemperatureFlag=1;
}

void Compute() 
// Compute function calculates new values for lastTime, errSum and lastErr,
// it also initializes new variables, and calculated their values, finally 
// resulting in calculation of new Output value
{   
  
   unsigned long now = millis();
   int timeChange = (now - lastTime);
   if (Setpoint<Input) {
      double error = Setpoint - Input;
      errSum += error;
      double dErr = (error - lastErr);
      Output = kp * error + ki * errSum + kd * dErr;
      lastErr = error;
      lastTime = now;
      }
      else { Output=0; errSum=0; lastErr=0;}
  
}
 
void SetTunings(double Kp, double Ki, double Kd) //function SetTunings is used to set values of P, I, D.
{
  double SampleTimeInSec = ((double)SampleTime)/1000;
   kp = Kp;
   ki = Ki * SampleTimeInSec;
   kd = Kd / SampleTimeInSec;
}
 
void SetSampleTime(int NewSampleTime) //function SetSampleTime changes the sampling time
{
   if (NewSampleTime > 0)
   {
      double ratio  = (double)NewSampleTime
                      / (double)SampleTime;
      ki *= ratio;
      kd /= ratio;
      SampleTime = (unsigned long)NewSampleTime;
   }
}
int main()
{ 
    fanControl.period(0.00004f);//PWM frequency is set to 25khz by setting its period to 0.00004
    SetTunings(4, 10, 2); // Values 4, 10 and 2 were proven to be the optimal P, I, D tunings
    
    float oldTemperature = temperature.read();
    float newTemperature= oldTemperature;
    temperatureTicker.attach(&tickerFlagOn, 0.2); 
    
    while (1)
    {
        newTemperature = temperature.read();
        oldTemperature = newTemperature; 
        printf("Temperature: %.1f\n\r", 3.3*oldTemperature*100);
        // on lines 71-79 reading of the temperature is executed, as well as updating it to the console 
        
        Input=oldTemperature;  //PID loop input is the temperature of the linear regulator
        Compute(); //Compute() activates the function and calculates the new value for Output
        
        if (-Output>1) Output=-1; //since Output can be unlimited by its value but fan is controlled by values 0-1,
                                   // Output is  set between 0 and 1.
        fanControl.write(-Output); // PWM signal is generated with the duty cycle equaling the value of Output
        printf("Fan speed: %f\n\n\r", -Output); //Speed of the fan is printed to the console.
        
        wait(3);  // for the conveniece, a delay of 3 seconds is added.
    }   
}