pid working code for Anssi's lab

Dependencies:   mbed millis

Committer:
nikitakl
Date:
Sat Jan 02 17:10:29 2021 +0000
Revision:
4:4a3c3188e992
Parent:
3:70e0372dbf2e
newwest

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nikitakl 0:2b302a1ce68a 1 #include "mbed.h"
nikitakl 0:2b302a1ce68a 2 #include "millis.h"
nikitakl 1:36155a9a4422 3
nikitakl 1:36155a9a4422 4 #define threshold 0.009
nikitakl 2:fe18ec619746 5
nikitakl 0:2b302a1ce68a 6 double Input, Output;
nikitakl 3:70e0372dbf2e 7 double Setpoint=0.10303030303 ; //=34/330;
nikitakl 2:fe18ec619746 8 // the setpoint was defined to be 34 degrees, since it was evidenced that the temperature
nikitakl 2:fe18ec619746 9 // can not fall under 33 degrees even when the fan is at full speed
nikitakl 2:fe18ec619746 10 unsigned long lastTime;
nikitakl 0:2b302a1ce68a 11 double errSum, lastErr;
nikitakl 2:fe18ec619746 12 // variables lastTime, errSum and lastErr are used in calculating I and D values
nikitakl 0:2b302a1ce68a 13 double kp, ki, kd;
nikitakl 2:fe18ec619746 14 int SampleTime = 1000; // SampleTime defines how ofter the PID function is called
nikitakl 0:2b302a1ce68a 15
nikitakl 2:fe18ec619746 16 AnalogIn temperature(p20); // pin p20 is used to read analog output from the temperature sensor
nikitakl 2:fe18ec619746 17 PwmOut fanControl(p21); //pin p21 is used to control the fan with PWM output signal
nikitakl 0:2b302a1ce68a 18
nikitakl 0:2b302a1ce68a 19 Ticker temperatureTicker;
nikitakl 0:2b302a1ce68a 20 int readTemperatureFlag=0;
nikitakl 0:2b302a1ce68a 21
nikitakl 0:2b302a1ce68a 22 void tickerFlagOn()
nikitakl 0:2b302a1ce68a 23 {
nikitakl 0:2b302a1ce68a 24 readTemperatureFlag=1;
nikitakl 0:2b302a1ce68a 25 }
nikitakl 0:2b302a1ce68a 26
nikitakl 2:fe18ec619746 27 void Compute()
nikitakl 3:70e0372dbf2e 28 // Compute function calculates new values for lastTime, errSum and lastErr,
nikitakl 2:fe18ec619746 29 // it also initializes new variables, and calculated their values, finally
nikitakl 2:fe18ec619746 30 // resulting in calculation of new Output value
nikitakl 0:2b302a1ce68a 31 {
nikitakl 1:36155a9a4422 32
nikitakl 0:2b302a1ce68a 33 unsigned long now = millis();
nikitakl 0:2b302a1ce68a 34 int timeChange = (now - lastTime);
nikitakl 1:36155a9a4422 35 if (Setpoint<Input) {
nikitakl 0:2b302a1ce68a 36 double error = Setpoint - Input;
nikitakl 0:2b302a1ce68a 37 errSum += error;
nikitakl 0:2b302a1ce68a 38 double dErr = (error - lastErr);
nikitakl 0:2b302a1ce68a 39 Output = kp * error + ki * errSum + kd * dErr;
nikitakl 0:2b302a1ce68a 40 lastErr = error;
nikitakl 0:2b302a1ce68a 41 lastTime = now;
nikitakl 1:36155a9a4422 42 }
nikitakl 1:36155a9a4422 43 else { Output=0; errSum=0; lastErr=0;}
nikitakl 1:36155a9a4422 44
nikitakl 0:2b302a1ce68a 45 }
nikitakl 0:2b302a1ce68a 46
nikitakl 2:fe18ec619746 47 void SetTunings(double Kp, double Ki, double Kd) //function SetTunings is used to set values of P, I, D.
nikitakl 0:2b302a1ce68a 48 {
nikitakl 0:2b302a1ce68a 49 double SampleTimeInSec = ((double)SampleTime)/1000;
nikitakl 0:2b302a1ce68a 50 kp = Kp;
nikitakl 0:2b302a1ce68a 51 ki = Ki * SampleTimeInSec;
nikitakl 0:2b302a1ce68a 52 kd = Kd / SampleTimeInSec;
nikitakl 0:2b302a1ce68a 53 }
nikitakl 0:2b302a1ce68a 54
nikitakl 2:fe18ec619746 55 void SetSampleTime(int NewSampleTime) //function SetSampleTime changes the sampling time
nikitakl 0:2b302a1ce68a 56 {
nikitakl 0:2b302a1ce68a 57 if (NewSampleTime > 0)
nikitakl 0:2b302a1ce68a 58 {
nikitakl 0:2b302a1ce68a 59 double ratio = (double)NewSampleTime
nikitakl 0:2b302a1ce68a 60 / (double)SampleTime;
nikitakl 0:2b302a1ce68a 61 ki *= ratio;
nikitakl 0:2b302a1ce68a 62 kd /= ratio;
nikitakl 0:2b302a1ce68a 63 SampleTime = (unsigned long)NewSampleTime;
nikitakl 0:2b302a1ce68a 64 }
nikitakl 0:2b302a1ce68a 65 }
nikitakl 0:2b302a1ce68a 66 int main()
nikitakl 3:70e0372dbf2e 67 {
nikitakl 4:4a3c3188e992 68 fanControl.period(0.00004f);//PWM frequency is set to 25khz by setting its period to 0.00004
nikitakl 4:4a3c3188e992 69 SetTunings(4, 10, 2); // Values 4, 10 and 2 were proven to be the optimal P, I, D tunings
nikitakl 0:2b302a1ce68a 70
nikitakl 0:2b302a1ce68a 71 float oldTemperature = temperature.read();
nikitakl 0:2b302a1ce68a 72 float newTemperature= oldTemperature;
nikitakl 1:36155a9a4422 73 temperatureTicker.attach(&tickerFlagOn, 0.2);
nikitakl 0:2b302a1ce68a 74
nikitakl 0:2b302a1ce68a 75 while (1)
nikitakl 0:2b302a1ce68a 76 {
nikitakl 0:2b302a1ce68a 77 newTemperature = temperature.read();
nikitakl 3:70e0372dbf2e 78 oldTemperature = newTemperature;
nikitakl 3:70e0372dbf2e 79 printf("Temperature: %.1f\n\r", 3.3*oldTemperature*100);
nikitakl 3:70e0372dbf2e 80 // on lines 71-79 reading of the temperature is executed, as well as updating it to the console
nikitakl 3:70e0372dbf2e 81
nikitakl 2:fe18ec619746 82 Input=oldTemperature; //PID loop input is the temperature of the linear regulator
nikitakl 2:fe18ec619746 83 Compute(); //Compute() activates the function and calculates the new value for Output
nikitakl 3:70e0372dbf2e 84
nikitakl 3:70e0372dbf2e 85 if (-Output>1) Output=-1; //since Output can be unlimited by its value but fan is controlled by values 0-1,
nikitakl 2:fe18ec619746 86 // Output is set between 0 and 1.
nikitakl 3:70e0372dbf2e 87 fanControl.write(-Output); // PWM signal is generated with the duty cycle equaling the value of Output
nikitakl 2:fe18ec619746 88 printf("Fan speed: %f\n\n\r", -Output); //Speed of the fan is printed to the console.
nikitakl 3:70e0372dbf2e 89
nikitakl 2:fe18ec619746 90 wait(3); // for the conveniece, a delay of 3 seconds is added.
nikitakl 3:70e0372dbf2e 91 }
nikitakl 0:2b302a1ce68a 92 }