PID based on http://brettbeauregard.com/blog/2011/04/improving-the-beginner%e2%80%99s-pid-sample-time/

Dependencies:   mbed PID Ticker_HelloWorld millis

Committer:
nikitakl
Date:
Mon Dec 14 14:25:39 2020 +0000
Revision:
1:b71be4a00291
PID based on ; http://brettbeauregard.com/blog/2011/04/improving-the-beginner%e2%80%99s-pid-sample-time/

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nikitakl 1:b71be4a00291 1 #include "mbed.h"
nikitakl 1:b71be4a00291 2 #include "millis.h"
nikitakl 1:b71be4a00291 3 //#include "SoftwarePWM.h"
nikitakl 1:b71be4a00291 4 //#include "USBDevice.h"
nikitakl 1:b71be4a00291 5 #define threshold 0.003 // 1/330
nikitakl 1:b71be4a00291 6 unsigned long lastTime;
nikitakl 1:b71be4a00291 7 double Input, Output;
nikitakl 1:b71be4a00291 8 double Setpoint=0.0757575757575758;
nikitakl 1:b71be4a00291 9 double errSum, lastErr;
nikitakl 1:b71be4a00291 10 double kp, ki, kd;
nikitakl 1:b71be4a00291 11 int SampleTime = 1000; //1 sec
nikitakl 1:b71be4a00291 12
nikitakl 1:b71be4a00291 13
nikitakl 1:b71be4a00291 14 AnalogIn temperature(p20);
nikitakl 1:b71be4a00291 15 PwmOut fanControl(p21);
nikitakl 1:b71be4a00291 16 //static BufferedSerial pc(USBTX, USBRX);
nikitakl 1:b71be4a00291 17
nikitakl 1:b71be4a00291 18 Ticker temperatureTicker;
nikitakl 1:b71be4a00291 19
nikitakl 1:b71be4a00291 20 int readTemperatureFlag=0;
nikitakl 1:b71be4a00291 21
nikitakl 1:b71be4a00291 22 void tickerFlagOn()
nikitakl 1:b71be4a00291 23 {
nikitakl 1:b71be4a00291 24 //led2 = !led2;
nikitakl 1:b71be4a00291 25 readTemperatureFlag=1;
nikitakl 1:b71be4a00291 26 }
nikitakl 1:b71be4a00291 27
nikitakl 1:b71be4a00291 28 void Compute()
nikitakl 1:b71be4a00291 29 {
nikitakl 1:b71be4a00291 30 printf("PID is functioning\n\r");
nikitakl 1:b71be4a00291 31 unsigned long now = millis();
nikitakl 1:b71be4a00291 32 int timeChange = (now - lastTime);
nikitakl 1:b71be4a00291 33 if(timeChange>=SampleTime)
nikitakl 1:b71be4a00291 34 {
nikitakl 1:b71be4a00291 35 /*Compute all the working error variables*/
nikitakl 1:b71be4a00291 36 double error = Setpoint - Input;
nikitakl 1:b71be4a00291 37 errSum += error;
nikitakl 1:b71be4a00291 38 double dErr = (error - lastErr);
nikitakl 1:b71be4a00291 39
nikitakl 1:b71be4a00291 40 /*Compute PID Output*/
nikitakl 1:b71be4a00291 41 Output = kp * error + ki * errSum + kd * dErr;
nikitakl 1:b71be4a00291 42
nikitakl 1:b71be4a00291 43 /*Remember some variables for next time*/
nikitakl 1:b71be4a00291 44 lastErr = error;
nikitakl 1:b71be4a00291 45 lastTime = now;
nikitakl 1:b71be4a00291 46 }
nikitakl 1:b71be4a00291 47 printf("PID loop has ended\n\r");
nikitakl 1:b71be4a00291 48 }
nikitakl 1:b71be4a00291 49
nikitakl 1:b71be4a00291 50 void SetTunings(double Kp, double Ki, double Kd)
nikitakl 1:b71be4a00291 51 {
nikitakl 1:b71be4a00291 52 double SampleTimeInSec = ((double)SampleTime)/1000;
nikitakl 1:b71be4a00291 53 kp = Kp;
nikitakl 1:b71be4a00291 54 ki = Ki * SampleTimeInSec;
nikitakl 1:b71be4a00291 55 kd = Kd / SampleTimeInSec;
nikitakl 1:b71be4a00291 56 }
nikitakl 1:b71be4a00291 57
nikitakl 1:b71be4a00291 58 void SetSampleTime(int NewSampleTime)
nikitakl 1:b71be4a00291 59 {
nikitakl 1:b71be4a00291 60 if (NewSampleTime > 0)
nikitakl 1:b71be4a00291 61 {
nikitakl 1:b71be4a00291 62 double ratio = (double)NewSampleTime
nikitakl 1:b71be4a00291 63 / (double)SampleTime;
nikitakl 1:b71be4a00291 64 ki *= ratio;
nikitakl 1:b71be4a00291 65 kd /= ratio;
nikitakl 1:b71be4a00291 66 SampleTime = (unsigned long)NewSampleTime;
nikitakl 1:b71be4a00291 67 }
nikitakl 1:b71be4a00291 68 }
nikitakl 1:b71be4a00291 69 int main()
nikitakl 1:b71be4a00291 70 {
nikitakl 1:b71be4a00291 71
nikitakl 1:b71be4a00291 72 float oldTemperature = temperature.read();
nikitakl 1:b71be4a00291 73 float newTemperature= oldTemperature;
nikitakl 1:b71be4a00291 74 temperatureTicker.attach(&tickerFlagOn, 0.2); // the address of the function to be attached (tickerFlagOn) and the interval (0.2 seconds)
nikitakl 1:b71be4a00291 75
nikitakl 1:b71be4a00291 76 while (1)
nikitakl 1:b71be4a00291 77 {
nikitakl 1:b71be4a00291 78 if (readTemperatureFlag)
nikitakl 1:b71be4a00291 79 {
nikitakl 1:b71be4a00291 80 readTemperatureFlag=0;
nikitakl 1:b71be4a00291 81 newTemperature = temperature.read();
nikitakl 1:b71be4a00291 82 if ((newTemperature < (oldTemperature-threshold)) || (newTemperature > (oldTemperature+threshold)))
nikitakl 1:b71be4a00291 83 {
nikitakl 1:b71be4a00291 84 oldTemperature = newTemperature; // These are for the threshold
nikitakl 1:b71be4a00291 85 printf("Temperature= %.1f degrees\n\r", 3.3*oldTemperature*100);
nikitakl 1:b71be4a00291 86 }
nikitakl 1:b71be4a00291 87 }
nikitakl 1:b71be4a00291 88 //Setpoint=0.0757575757575758;
nikitakl 1:b71be4a00291 89 //Setpoint=25/330;
nikitakl 1:b71be4a00291 90 Input=oldTemperature;
nikitakl 1:b71be4a00291 91 SetTunings(1, 1, 1);
nikitakl 1:b71be4a00291 92 Compute();
nikitakl 1:b71be4a00291 93 fanControl.write(Output);
nikitakl 1:b71be4a00291 94 printf("fanSpeed=%f \n \r", Output);
nikitakl 1:b71be4a00291 95 wait(1);
nikitakl 1:b71be4a00291 96 }
nikitakl 1:b71be4a00291 97
nikitakl 1:b71be4a00291 98 }