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.cpp
- Committer:
- electromotivated
- Date:
- 2015-11-24
- Revision:
- 1:c307cd559154
- Parent:
- 0:9a6f7aafe531
- Child:
- 3:6c2c985408df
File content as of revision 1:c307cd559154:
#include "PID.h" /* Bryce Williams 11/19/2015 See PID.h for references as well as method descriptions */ PID::PID(float* setpoint, float* feedback, float* output, float output_lower, float output_upper, float kp, float ki, float kd, float Ts){ _Ts = Ts; // Init params _kp = kp; _ki = ki*Ts; // Roll sample time into gain _kd = kd / Ts; // Roll sample time into gain _setpoint = setpoint; _feedback = feedback; _output = output; _output_lower = output_lower; _output_upper = output_upper; } void PID::start(){ // Start up such we avoid bumps... (see "Initialization" section in // the reference link found in the header file). last_feedback = *_feedback; // Eliminate derivative kick at start/restart i_accumulator = clip(*_output, _output_lower, _output_upper); // P and D terms are zero, thus // i term is used to keep output unchanged sample_timer.attach(this, &PID::sample, _Ts); } void PID::stop(){ sample_timer.detach(); } float PID::getError(){ return error; } void PID::set_parameters(float kp, float ki, float kd, float Ts){ stop(); // Disable Sample Interrupt... stop() _Ts = Ts; // Set New Sample Time _kp = kp; // Seet New Kp _ki = ki*Ts; // Roll sample time into gain _kd = kd / Ts; // Roll sample time into gain start(); // Enable Sample Interrupt... start() } float PID::getKp(){ return _kp; } float PID::getKi(){ return _ki; } float PID::getKd(){ return _kd; } float PID::getTs(){ return _Ts; } void PID::sample(){ error = *_setpoint - *_feedback; // Accumulate Integral Term such ki is applied to current error // before adding to pool; avoids bumps if ki gain value is changed. i_accumulator += _ki * error; // Avoid "Windup" by clamping intergral term to output limits; // essentially we stop integrating when we reach an upper or // lower bound. i_accumulator = clip(i_accumulator, _output_lower, _output_upper); // Run it! *_output = _kp*error + i_accumulator - _kd*(*_feedback - last_feedback); last_feedback = *_feedback; // Clamp Output *_output = clip(*_output, _output_lower, _output_upper); } float PID::clip(float value, float lower, float upper){ return std::max(lower, std::min(value, upper)); }