Simple PID Controller with Integral Windup Supports creating a diagnostics message to send to a GUI

Fork of PidController by James Batchelar

Files at this revision

API Documentation at this revision

Comitter:
batchee7
Date:
Tue Oct 31 03:46:43 2017 +0000
Parent:
4:b590bd8fec6f
Commit message:
Final updates;

Changed in this revision

PidController.cpp Show annotated file Show diff for this revision Revisions of this file
PidController.h Show annotated file Show diff for this revision Revisions of this file
diff -r b590bd8fec6f -r 1206105e20bd PidController.cpp
--- a/PidController.cpp	Wed Oct 04 01:13:49 2017 +0000
+++ b/PidController.cpp	Tue Oct 31 03:46:43 2017 +0000
@@ -1,13 +1,13 @@
 #include "mbed.h"
 #include "PidController.h"
 
-PidController::PidController(bool sqrt){
+PidController::PidController(char c){
     elapsedTime =0;
     mode = MANUAL;
-    squareRootOuptut = sqrt;
+    diagChar = c;
     }
     
-int PidController::Calculate(float SP, float PV, float ManualMV) 
+float PidController::Calculate(float SP, float PV, float ManualMV) 
     {
         float CV;                   //(mm/s) Control Variable
         float IntegralAction;       // Integral Contribution to Output
@@ -17,35 +17,37 @@
         {   
             CV = ManualMV;      //Write Manual Manipulated Variable
             accumError = 0;
+            prevError = 0;
         }
         else 
         {   
             //Calc error
             error = SP - PV;  
             IntegralAction = K_i*(accumError + error);
-            DerivativeAction = K_d*(PV - lastInput);
+            //DerivativeAction = K_d*(PV - lastInput);
+            DerivativeAction = K_d*(error - prevError);
             
             //-- PID Calculation
-            if (SP) { 
-                CV =  K_p*error + IntegralAction - DerivativeAction;
-                if ((CV > 0) &&  squareRootOuptut)CV = sqrt(CV);
-                }
+            if (SP)
+            { 
+                CV =  bias + K_p*error + IntegralAction + DerivativeAction;
+                if (CV>0) {CV = sqrt(CV);}
+            }
             else 
+            {
+                CV= 0;
+                accumError = 0;
+            }
             
-            CV= 0;
-            
-                
             //-- Only allow the Controller to integrate if the output isnt saturated
             if ((CV < maxLimit) || (CV > minLimit))
             {
                 accumError += error;
                 }
-            
-            //-- Told to stop!
-            if (!SP) accumError = 0;
 
             //-- Save Current Input for Next Loop
-            lastInput = PV;  
+            //lastInput = PV;  
+            prevError = error;
             
             //Check to See Output is Within Limits
             if (CV > maxLimit){CV= maxLimit;}
@@ -56,38 +58,41 @@
         //-- Make message to send to GUI
         if (collectDiagnostics){BuildDiagMessage(SP,PV, CV, K_p*error, IntegralAction, DerivativeAction);}
         
-        return (int)(CV);
+        return CV;
     }
 
-void PidController::UpdateSettings(float Bias, float PropGain, float IntGain, float DiffGain, float OutputMin, float OutputMax, float OutputScale){
+void PidController::UpdateSettings(float Bias, float PropGain, float IntGain, float DiffGain, float OutputMin, float OutputMax){
     bias = Bias;
     K_p = PropGain;
     K_i = IntGain;
     K_d = DiffGain;
     minLimit = OutputMin;
     maxLimit = OutputMax;
-    scalar = OutputScale;
+    return;
     }
 
 void PidController::UpdateSettings(float OutputMin, float OutputMax){
     minLimit = OutputMin;
     maxLimit = OutputMax;
+    return;
     }
 
 
 void PidController::StartDiag(void){
     elapsedTime =0;
     collectDiagnostics = true;
+    return;
     }
 
 void PidController::EndDiag(void){
     collectDiagnostics = false;
-
+    return;
     }
 
 void PidController::BuildDiagMessage(float SetPoint, float ProcessVar, float PWM, float PropAction, float IntAction, float DifAction){
-    sprintf(diagMsg, "P %d %0.4f %0.4f %0.1f %0.4f %0.4f %0.4f\n", elapsedTime, SetPoint, ProcessVar, PWM, PropAction, IntAction, DifAction);
+    //sprintf(diagMsg, "%c %d %0.4f %0.4f %0.1f %0.4f %0.4f %0.4f\n", diagChar, elapsedTime, SetPoint, ProcessVar, PWM, PropAction, IntAction, DifAction);
+    sprintf(diagMsg, "%c %d %0.4f %0.4f %0.1f 0.0 0.0 0.0\n", diagChar, elapsedTime, SetPoint, ProcessVar, PWM); 
     elapsedTime += RATE;
-    if (elapsedTime > 32000){sprintf(diagMsg, "R");}
+    return;
     }
 
diff -r b590bd8fec6f -r 1206105e20bd PidController.h
--- a/PidController.h	Wed Oct 04 01:13:49 2017 +0000
+++ b/PidController.h	Tue Oct 31 03:46:43 2017 +0000
@@ -41,10 +41,9 @@
 #ifndef PidController_H
 #define PidController_H
 #include "mbed.h"
-#include "math.h"
 
 //-- Constants used in system
-const int RATE = 100;       //--(ms) Time that Calculate mehtod is being called       
+const int RATE = 20;       //--(ms) Time that Calculate mehtod is being called       
 const int AUTOMATIC = 0;    //-- In automatic then PID Controls Output
 const int MANUAL = 1;       //-- In Manual then User Controls Output directly
 
@@ -57,14 +56,14 @@
         /** Constructor
         *
         */
-        PidController(bool);
+        PidController(char);
         
         /** Performs the PID Calculation
         * @param SP - Setpoint (target value) units depends on what PID is controlling
         * @param PV - Process Variable (feedback/ measure value) units depends on what PID is controlling
         * @return Returns If Controller is in Automatic then returns PID controlled signal. In manual returns the user SP multipled by scalar.
         */
-        int Calculate(float SP, float PV, float ManualMV);
+        float Calculate(float SP, float PV, float ManualMV);
         
         /** Update Internal Settings
         * @param Bias - Added to the PID Calculation
@@ -75,7 +74,7 @@
         * @param OutputMax - Maximum Limit for the Output (units are same as setpoint)
         * @param OutputScale - Multiplier at End of PID loop to convert from engineering units to signal (eg PWM duty cycle)   
         */    
-        void UpdateSettings(float Bias, float PropGain, float IntGain, float DiffGain, float OutputMin, float OutputMax, float OutputScale);
+        void UpdateSettings(float Bias, float PropGain, float IntGain, float DiffGain, float OutputMin, float OutputMax);
         
         /** Update Internal Settings
         * @param OutputMin - Minimum Limit for the Output (units are same as setpoint)
@@ -126,13 +125,14 @@
         int elapsedTime;
         
         //-- For PID Calculations
-        bool squareRootOuptut;
-        float bias, scalar;
+        char diagChar;
+        float bias;
         float error;
         float lastInput;
         float accumError;
         float minLimit, maxLimit;
         float K_p,K_i,K_d;
+        float prevError;
     };
     
 #endif