QuickPID

repository·master·Indexed 42 days ago

https://github.com/dlloydev/quickpid

An enhanced implementation of the Arduino PID library featuring multiple proportional/derivative modes and sophisticated integral anti-windup strategies. It supports ESP32 via ESP-IDF and provides fine-grained control over PID terms through modes like pOnError, dOnMeas, and iAwCondition. The library uses pointers to link directly to Input, Output, and Setpoint variables for automatic updates during the Compute() cycle.

Tokens
2.4K
Snippets
5
Records
13
Agent score
4%

What's inside QuickPID

  1. Configure PID modes and anti-windup

    master

    QuickPID allows fine-grained control over how the proportional, derivative, and integral terms are calculated.

    Proportional Mode (pMode)

    Determines if the proportional term is based on error, measurement, or a combination:

    • pOnError: Based on error (default).
    • pOnMeas: Based on measurement.
    • pOnErrorMeas: A mix (0.5 error + 0.5 measurement).

    Derivative Mode (dMode)

    Determines if the derivative term is based on error or measurement:

    • dOnError: Based on error.
    • dOnMeas: Based on measurement (default).

    Anti-Windup Mode (iAwMode)

    Controls how the integral term handles saturation:

    • iAwCondition: Uses PI terms to provide integral correction, prevent deep saturation, and reduce overshoot (default).
    • iAwClamp: Clamps the summation of the pTerm and iTerm.
    • iAwOff: Disables all anti-windup.
    // Example of setting modes after construction
    pid.SetProportionalMode(pMode::pOnMeas);
    pid.SetDerivativeMode(dMode::dOnError);
    pid.SetAntiWindupMode(iAwMode::iAwClamp);
  2. Initialize QuickPID for ESP32 using ESP-IDF

    master

    To use QuickPID in an ESP-IDF environment for programming an ESP32, clone the repository into your components folder, then perform a clean build and rebuild your project.

    # Example workflow
    # 1. Clone repo into your project's components folder
    # 2. Clean and rebuild
    idf.py fullclean
    idf.py build
  3. Configure Proportional, Derivative, and Anti-Windup modes

    master

    You can fine-tune how the PID terms are calculated using the following modes:

    Proportional Mode (pMode)

    • pOnError: Compute based on error (default).
    • pOnMeas: Compute based on measurement.
    • pOnErrorMeas: Compute based on the average of both.

    Derivative Mode (dMode)

    • dOnError: Compute based on error.
    • dOnMeas: Compute based on measurement (default).

    Integral Anti-Windup Mode (iAwMode)

    Prevents integral saturation:

    • iAwCondition: Provides integral correction, prevents deep saturation, and reduces overshoot (default).
    • iAwClamp: Clamps the output after adding integral and proportional (on measurement) terms.
    • iAwOff: Disables anti-windup altogether.
  4. Configure QuickPID control modes and actions

    master

    QuickPID provides several enums to control the behavior of the controller:

    Control Modes (Control)

    Determines how the controller operates:

    • manual: Manual mode.
    • automatic: Automatic PID control.
    • timer: Timer-based mode.
    • toggle: Toggles between manual and automatic.

    Controller Action (Action)

    Determines the relationship between error and output:

    • direct: Output increases when error is positive.
    • reverse: Output decreases when error is positive.
  5. Initialize and use the QuickPID controller

    master

    QuickPID is a PID controller that uses pointers to link directly to your Input, Output, and Setpoint variables. This allows the controller to update your variables automatically during the Compute() cycle.

    To use QuickPID:

    1. Define your float variables for input, output, and setpoint.
    2. Instantiate QuickPID using one of the constructors.
    3. Call Compute() inside your main loop at a consistent frequency.

    Note: You must call Compute() regularly. The calculation frequency is controlled by SetSampleTimeUs() (default is 100,000 µs).

    float input, output, setpoint;
    // Initialize with pointers to your variables
    QuickPID pid(&input, &output, &setpoint, 2.0, 0.5, 0.1, 
                 QuickPID::pMode::pOnError, 
                 QuickPID::dMode::dOnMeas, 
                 QuickPID::iAwMode::iAwCondition, 
                 QuickPID::Action::direct);
    
    void loop() {
        // Compute performs the PID calculation and updates the 'output' variable
        pid.Compute();
    }
  6. Construct a QuickPID instance

    master

    QuickPID provides several constructors to initialize the controller. You must provide pointers to the Input, Output, and Setpoint variables so the library can update them directly.

    Full Constructor

    Use this to define all PID parameters, including modes and action type at initialization.

    Simplified Constructor

    Allows you to define Kp, Ki, and Kd while keeping default modes. You can later use setter functions to configure specific modes.

    Minimal Constructor

    Initializes the controller with zeroed gains. You must call SetTunings later to provide valid PID values.

    // Full configuration
    QuickPID pid(&input, &output, &setpoint, Kp, Ki, Kd, pMode::pOnError, dMode::dOnMeas, iAwMode::iAwCondition, Action::direct);
    
    // Simplified (defaults to pOnError and dOnMeas)
    QuickPID pid(&input, &output, &setpoint, Kp, Ki, Kd, Action::direct);
    
    // Minimal (requires SetTunings later)
    QuickPID pid(&input, &output, &setpoint);
  7. Run the PID control loop with Compute()

    master

    The Compute() function executes the PID algorithm. It should be called inside your main loop (e.g., loop() in Arduino).

    Behavior:

    • Most calls return false and do nothing.
    • When the internal sample time (set via SetSampleTimeUs) has elapsed, it calculates a new Output and returns true.
    • Use the return value to trigger logic that should only run when a new calculation is performed.
    void loop() {
      if (pid.Compute()) {
        // This block runs only when a new PID calculation is completed
        Serial.print("New Output: ");
        Serial.println(output);
      }
    }
  8. Manage PID state and limits

    master

    Use these functions to control the operational state and constraints of the PID controller:

    • Initialize(): Ensures a bump-less transfer when moving from manual to automatic mode.
    • Reset(): Clears all internal terms (pTerm, iTerm, dTerm, outputSum).
    • SetOutputLimits(float Min, float Max): Sets the range for the controller output. Defaults to 0-255.
    • SetControllerDirection(Action Action): Sets the response direction:
      • direct: Input moves in the same direction as output (e.g., heating).
      • reverse: Input moves in the opposite direction as output (e.g., cooling).
    • SetSampleTimeUs(uint32_t NewSampleTimeUs): Sets the calculation frequency in microseconds (default is 100000 µs).
  9. Query PID internal state

    master

    You can inspect the current state of the PID controller using these getter functions:

    FunctionDescription
    GetKp()Proportional gain
    GetKi()Integral gain
    GetKd()Derivative gain
    GetPterm()Proportional component of output
    GetIterm()Integral component of output
    GetDterm()Derivative component of output
    GetMode()Manual (0), Automatic (1), or Timer (2)
    GetDirection()Direct (0) or Reverse (1)
    GetPmode()pOnError (0), pOnMeas (1), pOnErrorMeas (2)
    GetDmode()dOnError (0), dOnMeas (1)
    GetAwMode()iAwCondition (0), iAwClamp (1), iAwOff (2)
  10. Configure output limits and sample time

    master

    Use these methods to constrain the output range and define the calculation frequency.

    • SetOutputLimits(float Min, float Max): Sets and clamps the output to a specific range. The default range is 0 to 255.
    • SetSampleTimeUs(uint32_t NewSampleTimeUs): Sets the sample time in microseconds. The default is 100,000 µs.
  11. Reset and Initialize the PID controller

    master

    Use these methods to manage the controller's internal state:

    • Initialize(): Ensures a bumpless transfer when switching from manual to automatic mode.
    • Reset(): Clears all internal terms (pTerm, iTerm, dTerm) and the outputSum value.
  12. Query PID state and components

    master

    Use these methods to inspect the current state of the controller and its individual terms:

    MethodDescription
    GetKp()Proportional gain
    GetKi()Integral gain
    GetKd()Derivative gain
    GetPterm()Proportional component of output
    GetIterm()Integral component of output
    GetDterm()Derivative component of output
    GetOutputSum()Summation of all PID term components
    GetMode()Current Control mode
    GetDirection()Current Action (direct/reverse)
    GetPmode()Current pMode
    GetDmode()Current dMode
    GetAwMode()Current iAwMode