Nikita Klimchuk
/
PID_new_temp
pid working code for Anssi's lab
PID.cpp@4:4a3c3188e992, 2021-01-02 (annotated)
- Committer:
- nikitakl
- Date:
- Sat Jan 02 17:10:29 2021 +0000
- Revision:
- 4:4a3c3188e992
- Parent:
- 3:70e0372dbf2e
newwest
Who changed what in which revision?
User | Revision | Line number | New 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 | } |