ESPHome  2022.8.0
pid_controller.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "esphome/core/hal.h"
4 
5 namespace esphome {
6 namespace pid {
7 
8 struct PIDController {
9  float update(float setpoint, float process_value) {
10  // e(t) ... error at timestamp t
11  // r(t) ... setpoint
12  // y(t) ... process value (sensor reading)
13  // u(t) ... output value
14 
15  float dt = calculate_relative_time_();
16 
17  // e(t) := r(t) - y(t)
18  error = setpoint - process_value;
19 
20  // p(t) := K_p * e(t)
22 
23  // i(t) := K_i * \int_{0}^{t} e(t) dt
24  accumulated_integral_ += error * dt * ki;
25  // constrain accumulated integral value
26  if (!std::isnan(min_integral) && accumulated_integral_ < min_integral)
28  if (!std::isnan(max_integral) && accumulated_integral_ > max_integral)
31 
32  // d(t) := K_d * de(t)/dt
33  float derivative = 0.0f;
34  if (dt != 0.0f)
35  derivative = (error - previous_error_) / dt;
37  derivative_term = kd * derivative;
38 
39  // u(t) := p(t) + i(t) + d(t)
41  }
42 
44 
46  float kp = 0;
48  float ki = 0;
50  float kd = 0;
51 
52  float min_integral = NAN;
53  float max_integral = NAN;
54 
55  // Store computed values in struct so that values can be monitored through sensors
56  float error;
60 
61  protected:
63  uint32_t now = millis();
64  uint32_t dt = now - this->last_time_;
65  if (last_time_ == 0) {
66  last_time_ = now;
67  return 0.0f;
68  }
69  last_time_ = now;
70  return dt / 1000.0f;
71  }
72 
74  float previous_error_ = 0;
77  uint32_t last_time_ = 0;
78 };
79 
80 } // namespace pid
81 } // namespace esphome
float accumulated_integral_
Accumulated integral value.
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:26
float ki
Integral gain K_i.
float kp
Proportional gain K_p.
float update(float setpoint, float process_value)
Definition: pid_controller.h:9
float kd
Differential gain K_d.
Definition: a4988.cpp:4
float previous_error_
Error from previous update used for derivative term.