PID based on http://brettbeauregard.com/blog/2011/04/improving-the-beginner%e2%80%99s-pid-sample-time/
Dependencies: mbed PID Ticker_HelloWorld millis
PID.cpp@1:b71be4a00291, 2020-12-14 (annotated)
- 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?
User | Revision | Line number | New 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 | } |