-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
auto PID::setTunings(
const double Kp,
const double Ki,
const double Kd) -> voidSets the proportional, integral, and derivative gains.
The proportional term reacts to the current control error:
Example:
Setpoint = 100
Actual = 90
Error = 10
Kp = 5
P = 50
A larger Kp produces a stronger response to the current deviation from the setpoint.
The integral term reacts to an error that persists over time:
Its main purpose is to eliminate steady-state error.
The derivative term reacts to the rate of change of the measured process value.
The implementation uses derivative-on-measurement instead of derivative-on-error. This avoids derivative kick when the setpoint changes and allows the controller to reduce the output while the process value is still approaching the setpoint.
Negative PID gains are clamped to 0.0.
Controller direction should be configured using setDirection().
auto PID::reset() -> voidResets the internal dynamic state of the controller.
The configured PID gains and other settings are not changed.
The following internal states are reset:
mIntegral = 0.0;
mPrevActual = 0.0;
mDerivativeFiltered = 0.0;
mInitialized = false;The internal timing reference is also restarted:
mLastComputeMs = millis();The current output is preserved but clamped to the configured output limits:
mOut = clamp(mOut, mMin, mMax);This avoids an unnecessary output jump simply because the controller state was reset.
Typical use cases include:
- system startup
- switching operating modes
- restarting the control process
- invalidating the previous derivative state
- clearing the integral state
auto PID::setLimits(
const double min,
const double max) -> voidDefines the valid output range of the controller.
Example:
pid.setLimits(0.0, 100.0);This can represent:
0 ... 100 %
Another example:
pid.setLimits(0.0, 1023.0);can be used for a 10-bit internal control range.
If the calculated PID output exceeds the configured range, it is limited before being returned.
Invalid ranges are ignored:
if (max <= min)
return;If the current output is already outside the newly configured range, it is immediately clamped.
auto PID::setSampletime(
const uint32_t sampleTimeMs) -> voidDefines how often the PID controller is recalculated.
Example:
pid.setSampletime(100);This corresponds to approximately:
10 calculations per second
Calling calc() more frequently is allowed. If the configured sample time has not elapsed, calc() simply returns the previous output.
A stable and known sample interval is important because both the integral and derivative calculations depend on elapsed time.
A value of 0 is rejected.
auto PID::setDirection(
const Direction direction) -> voidDefines the direction of controller action.
Use DIRECT when the output must increase if the actual value is below the setpoint.
Typical example:
Heating system
Actual temperature below setpoint
->
Increase heater output
Example:
pid.setDirection(PID::Direction::DIRECT);Use REVERSE when the output must increase if the actual value is above the setpoint.
Typical example:
Cooling system
Actual temperature above setpoint
->
Increase cooling output
Example:
pid.setDirection(PID::Direction::REVERSE);Internally, direction is represented by a multiplier:
const double direction =
(mDirection == Direction::DIRECT)
? 1.0
: -1.0;This keeps the remaining PID equations consistent.
auto PID::setTolerance(
const uint8_t percentage) -> voidDefines a percentage-based tolerance band around the setpoint.
Inside this band, the integral term is frozen.
The proportional and derivative terms remain active.
Example:
pid.setTolerance(2);With:
Setpoint = 100
the tolerance band is:
98 ... 102
The controller does not stop controlling inside this band.
Only the integral accumulation is paused.
This prevents the integral term from continuously reacting to very small errors near the setpoint.
auto PID::setIntegralActivationRange(
const double range) -> voidDefines how close the process value must be to the setpoint before the integral term is allowed to operate.
Example:
pid.setIntegralActivationRange(10.0);With:
Setpoint = 100
the integral term may operate only while the actual value is inside:
90 ... 110
This is particularly useful for slow or thermal systems.
Without this restriction, a large error over a long period can build a very large integral term.
Example:
Setpoint = 100
Actual = 20
If integration is active during the entire approach to the setpoint, the integral term may become very large before the actual value reaches the target.
When the setpoint is finally reached, the proportional term may already be near zero while the integral term still commands a high output.
This is a common cause of overshoot.
Setting the activation range to 0.0 disables this restriction.
auto PID::setDerivativeFilter(
const double tauSeconds) -> voidConfigures the low-pass filter applied to the derivative term.
Derivative action is sensitive to measurement noise because even small fluctuations in the measured value can produce large changes in the calculated derivative.
The controller therefore uses a first-order low-pass filter:
and
Example:
pid.setDerivativeFilter(0.5);This configures a filter time constant of approximately:
500 ms
Typical qualitative behavior:
0.2 s -> light filtering
0.5 s -> moderate filtering
1.0 s -> strong filtering
2.0 s -> very strong / slow filtering
Setting the filter time constant to 0.0 disables derivative filtering.
auto PID::setOutputSlewRate(
const double unitsPerSecond) -> voidLimits how quickly the controller output may change.
Example:
pid.setOutputSlewRate(100.0);This means:
Maximum output change = 100 units per second
With a sample time of:
100 ms
the maximum change per PID update becomes:
100 * 0.1 = 10 units
If the previous output is:
200
and the PID calculation suddenly requests:
700
the output will not immediately jump to 700.
Instead, it will increase gradually:
200
210
220
230
...
This reduces aggressive actuator behavior and makes the control output smoother.
Set the slew rate to 0.0 to disable the limiter.
auto getOutput() const -> doubleReturns the most recently calculated controller output.
Example:
double currentOutput = pid.getOutput();This function does not trigger a new PID calculation.
The const qualifier guarantees that the function does not modify the PID object.
static auto clamp(
double value,
double min,
double max) -> doubleInternal helper function used to restrict a value to a defined range.
Examples:
clamp(120.0, 0.0, 100.0); // 100
clamp(-20.0, 0.0, 100.0); // 0
clamp(53.0, 0.0, 100.0); // 53It is declared static because it does not require access to any PID object state.
auto PID::calc(
const double setpoint,
const double actual) -> doublePerforms the actual PID calculation.
Parameters:
| Parameter | Description |
|---|---|
setpoint |
Desired process value |
actual |
Current measured process value |
Return value:
Current controller output
The function contains the complete control algorithm.