Basic but robust PID library
Dependents: ESP8266_pid_mtrPos_webserver_SDcard_v2 ESP8266_pid_mtrSpeed_Webserver_SDcard ESP8266_pid_spd_and_pos_webserver_SDcard ESP8266_pid_redbot_webserver ... more
PID.h@5:0cf2f6d13c71, 2015-12-29 (annotated)
- Committer:
- electromotivated
- Date:
- Tue Dec 29 02:31:32 2015 +0000
- Revision:
- 5:0cf2f6d13c71
- Parent:
- 2:07397aa513c6
Added Comments
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
electromotivated | 0:9a6f7aafe531 | 1 | #ifndef PID_H |
electromotivated | 0:9a6f7aafe531 | 2 | #define PID_H |
electromotivated | 0:9a6f7aafe531 | 3 | #include "mbed.h" |
electromotivated | 0:9a6f7aafe531 | 4 | #include <algorithm> |
electromotivated | 0:9a6f7aafe531 | 5 | |
electromotivated | 0:9a6f7aafe531 | 6 | /* |
electromotivated | 0:9a6f7aafe531 | 7 | Bryce Williams 11/19/2015 |
electromotivated | 0:9a6f7aafe531 | 8 | |
electromotivated | 0:9a6f7aafe531 | 9 | PID Controller Class based on Brett Beauregard's Arduino PID Library |
electromotivated | 0:9a6f7aafe531 | 10 | and PID blog post. |
electromotivated | 0:9a6f7aafe531 | 11 | |
electromotivated | 0:9a6f7aafe531 | 12 | Brett Beauregard's blog post explains the PID code implementation very well |
electromotivated | 0:9a6f7aafe531 | 13 | and discusses why the actual equation is a bit different than the classical |
electromotivated | 0:9a6f7aafe531 | 14 | equation, i.e. he explains and implements how to overcome windup, dervative |
electromotivated | 0:9a6f7aafe531 | 15 | kick, etc. This class uses the same implementation, but adds interrupt |
electromotivated | 0:9a6f7aafe531 | 16 | driven computation. |
electromotivated | 0:9a6f7aafe531 | 17 | |
electromotivated | 0:9a6f7aafe531 | 18 | Reference Links: |
electromotivated | 0:9a6f7aafe531 | 19 | 1. Arduion Library: |
electromotivated | 0:9a6f7aafe531 | 20 | (http://playground.arduino.cc/Code/PIDLibrary) |
electromotivated | 0:9a6f7aafe531 | 21 | 2. Brett Beauregard's PID Blog: |
electromotivated | 0:9a6f7aafe531 | 22 | (http://brettbeauregard.com/blog/2011/04/improving-the-beginners- |
electromotivated | 0:9a6f7aafe531 | 23 | pid-introduction/) |
electromotivated | 0:9a6f7aafe531 | 24 | */ |
electromotivated | 0:9a6f7aafe531 | 25 | |
electromotivated | 0:9a6f7aafe531 | 26 | class PID{ |
electromotivated | 0:9a6f7aafe531 | 27 | public: |
electromotivated | 0:9a6f7aafe531 | 28 | /* |
electromotivated | 0:9a6f7aafe531 | 29 | Constructor for PID objects. |
electromotivated | 0:9a6f7aafe531 | 30 | |
electromotivated | 0:9a6f7aafe531 | 31 | Note: PID objects use given pointers, ie setpoint, |
electromotivated | 0:9a6f7aafe531 | 32 | feedback, output inside interrupts. When reading/ modifying |
electromotivated | 0:9a6f7aafe531 | 33 | these vars make sure we don't have possible read/write |
electromotivated | 0:9a6f7aafe531 | 34 | conflicts if the interrupt fires. Either ensure reads/writes |
electromotivated | 0:9a6f7aafe531 | 35 | are atomic operations, or call the stop() method perform the |
electromotivated | 0:9a6f7aafe531 | 36 | read/write and then call the start() method. |
electromotivated | 5:0cf2f6d13c71 | 37 | |
electromotivated | 5:0cf2f6d13c71 | 38 | @param setpoint The setpoint |
electromotivated | 5:0cf2f6d13c71 | 39 | @param feedback Pointer to feedback/sensor data var |
electromotivated | 5:0cf2f6d13c71 | 40 | @param output Pointer to the output var |
electromotivated | 5:0cf2f6d13c71 | 41 | @param output_lower The lower bound of the output value |
electromotivated | 5:0cf2f6d13c71 | 42 | @param output_upper The upper bount of the output value |
electromotivated | 5:0cf2f6d13c71 | 43 | @param kp The Proportional Gain value |
electromotivated | 5:0cf2f6d13c71 | 44 | @param ki The Integral Gain value |
electromotivated | 5:0cf2f6d13c71 | 45 | @param kd The Derivative Gain value |
electromotivated | 5:0cf2f6d13c71 | 46 | @param Ts The sample period at which the PID algorithm will |
electromotivated | 5:0cf2f6d13c71 | 47 | generate an interrupt and run. |
electromotivated | 0:9a6f7aafe531 | 48 | */ |
electromotivated | 0:9a6f7aafe531 | 49 | PID(float* setpoint, float* feedback, float* output, |
electromotivated | 0:9a6f7aafe531 | 50 | float output_lower, float output_upper, |
electromotivated | 0:9a6f7aafe531 | 51 | float kp, float ki, float kd, float Ts); |
electromotivated | 0:9a6f7aafe531 | 52 | /* |
electromotivated | 0:9a6f7aafe531 | 53 | Starts PID Controller; Attaches sample() as callback to Ticker |
electromotivated | 0:9a6f7aafe531 | 54 | sample_timer and starts the interrupt |
electromotivated | 0:9a6f7aafe531 | 55 | */ |
electromotivated | 0:9a6f7aafe531 | 56 | void start(); |
electromotivated | 0:9a6f7aafe531 | 57 | /* |
electromotivated | 0:9a6f7aafe531 | 58 | Stops PID Contoller; detaches callback from Ticker sample_timer. |
electromotivated | 5:0cf2f6d13c71 | 59 | Allows manual setting of output and read/write of shared vars, |
electromotivated | 5:0cf2f6d13c71 | 60 | DON'T FORGET TO CALL stop() before read/write of shared vars! |
electromotivated | 5:0cf2f6d13c71 | 61 | Then after call start()!!! |
electromotivated | 0:9a6f7aafe531 | 62 | */ |
electromotivated | 0:9a6f7aafe531 | 63 | void stop(); |
electromotivated | 0:9a6f7aafe531 | 64 | /* |
electromotivated | 0:9a6f7aafe531 | 65 | Increments/ decrements Gain values and Sample time |
electromotivated | 0:9a6f7aafe531 | 66 | by the given value. Gives a simple method to |
electromotivated | 0:9a6f7aafe531 | 67 | programatically step through different values; just put in a |
electromotivated | 0:9a6f7aafe531 | 68 | loop and go |
electromotivated | 0:9a6f7aafe531 | 69 | @param delta_"name" The value that will be added to its currently set value |
electromotivated | 0:9a6f7aafe531 | 70 | */ |
electromotivated | 0:9a6f7aafe531 | 71 | // void adjust_parameters(float delta_kp, float delta_ki, float delta_kd, float delta Ts); |
electromotivated | 0:9a6f7aafe531 | 72 | /* |
electromotivated | 0:9a6f7aafe531 | 73 | Overwrite Gain and Sample Time parameters with new |
electromotivated | 0:9a6f7aafe531 | 74 | values |
electromotivated | 0:9a6f7aafe531 | 75 | Note: sample_timer interrupt is disabled during update |
electromotivated | 0:9a6f7aafe531 | 76 | to avoid synch issues. |
electromotivated | 0:9a6f7aafe531 | 77 | |
electromotivated | 0:9a6f7aafe531 | 78 | */ |
electromotivated | 0:9a6f7aafe531 | 79 | void set_parameters(float kp, float ki, float kd, float Ts); |
electromotivated | 0:9a6f7aafe531 | 80 | |
electromotivated | 2:07397aa513c6 | 81 | float getKp(); |
electromotivated | 2:07397aa513c6 | 82 | float getKi(); |
electromotivated | 2:07397aa513c6 | 83 | float getKd(); |
electromotivated | 2:07397aa513c6 | 84 | float getTs(); |
electromotivated | 2:07397aa513c6 | 85 | |
electromotivated | 0:9a6f7aafe531 | 86 | /* |
electromotivated | 0:9a6f7aafe531 | 87 | returns current error |
electromotivated | 0:9a6f7aafe531 | 88 | */ |
electromotivated | 0:9a6f7aafe531 | 89 | float getError(); |
electromotivated | 0:9a6f7aafe531 | 90 | |
electromotivated | 0:9a6f7aafe531 | 91 | private: |
electromotivated | 0:9a6f7aafe531 | 92 | float _kp, _ki, _kd; // PID Gain values |
electromotivated | 0:9a6f7aafe531 | 93 | float _Ts; // Sample time is seconds |
electromotivated | 0:9a6f7aafe531 | 94 | float* _setpoint; // Pointer to setpoint value |
electromotivated | 0:9a6f7aafe531 | 95 | float* _feedback; // Pointer to sensor feedback value (sensor input) |
electromotivated | 0:9a6f7aafe531 | 96 | float* _output; // Pointer to control output value |
electromotivated | 0:9a6f7aafe531 | 97 | float _output_lower; // Ouput Lower Limit |
electromotivated | 0:9a6f7aafe531 | 98 | float _output_upper; // Output Upper Limit |
electromotivated | 0:9a6f7aafe531 | 99 | |
electromotivated | 0:9a6f7aafe531 | 100 | float i_accumulator; // Integral Term accumulator |
electromotivated | 0:9a6f7aafe531 | 101 | float last_feedback; // Previous feedback value |
electromotivated | 0:9a6f7aafe531 | 102 | float error; // Feedback error term |
electromotivated | 0:9a6f7aafe531 | 103 | Ticker sample_timer; // Generates the sample time interrupt and calls sample() |
electromotivated | 0:9a6f7aafe531 | 104 | /* |
electromotivated | 0:9a6f7aafe531 | 105 | sample() performs next sample calculationand updates command value |
electromotivated | 0:9a6f7aafe531 | 106 | */ |
electromotivated | 0:9a6f7aafe531 | 107 | void sample(); |
electromotivated | 0:9a6f7aafe531 | 108 | /* |
electromotivated | 0:9a6f7aafe531 | 109 | Clips value to lower/ uppper |
electromotivated | 0:9a6f7aafe531 | 110 | @param value The value to clip |
electromotivated | 0:9a6f7aafe531 | 111 | @param lower The mininum allowable value |
electromotivated | 0:9a6f7aafe531 | 112 | @param upper The maximum allowable value |
electromotivated | 0:9a6f7aafe531 | 113 | @return The resulting clipped value |
electromotivated | 0:9a6f7aafe531 | 114 | */ |
electromotivated | 0:9a6f7aafe531 | 115 | float clip(float value, float lower, float upper); |
electromotivated | 0:9a6f7aafe531 | 116 | }; |
electromotivated | 0:9a6f7aafe531 | 117 | |
electromotivated | 0:9a6f7aafe531 | 118 | #endif |