11 dt_ = calculate_relative_time_();
14 error_ = setpoint - process_value;
16 calculate_proportional_term_();
17 calculate_integral_term_();
18 calculate_derivative_term_(setpoint);
21 float output = proportional_term_ + integral_term_ + derivative_term_;
24 int samples =
in_deadband() ? deadband_output_samples_ : output_samples_;
25 return ring_buffer_average_(output_window_, output, samples);
31 return (threshold_low_ < err && err < threshold_high_);
34void PIDController::calculate_proportional_term_() {
36 proportional_term_ = kp_ * error_;
41 proportional_term_ *= kp_multiplier_;
45 float threshold = (error_ < 0) ? threshold_high_ : threshold_low_;
46 float pdm_offset = (threshold - (kp_multiplier_ * threshold)) * kp_;
47 proportional_term_ += pdm_offset;
51void PIDController::calculate_integral_term_() {
53 float new_integral = error_ * dt_ * ki_;
57 accumulated_integral_ += new_integral * ki_multiplier_;
59 accumulated_integral_ += new_integral;
63 if (!std::isnan(min_integral_) && accumulated_integral_ < min_integral_)
64 accumulated_integral_ = min_integral_;
65 if (!std::isnan(max_integral_) && accumulated_integral_ > max_integral_)
66 accumulated_integral_ = max_integral_;
68 integral_term_ = accumulated_integral_;
71void PIDController::calculate_derivative_term_(
float setpoint) {
74 float derivative = 0.0f;
77 if (!std::isnan(previous_setpoint_) && previous_setpoint_ != setpoint)
78 previous_error_ -= previous_setpoint_ - setpoint;
79 derivative = (error_ - previous_error_) / dt_;
81 previous_error_ = error_;
82 previous_setpoint_ = setpoint;
85 derivative = ring_buffer_average_(derivative_window_, derivative, derivative_samples_);
87 derivative_term_ = kd_ * derivative;
91 derivative_term_ *= kd_multiplier_;
95float PIDController::ring_buffer_average_(FixedRingBuffer<float> &buf,
float new_value,
int max_samples) {
97 if (max_samples <= 1) {
104 while (buf.size() >=
static_cast<size_t>(max_samples))
111 return sum / buf.size();
114float PIDController::calculate_relative_time_() {
116 uint32_t dt = now - this->last_time_;
117 if (last_time_ == 0) {
uint32_t IRAM_ATTR HOT millis()
float update(float setpoint, float process_value)