### Configure ArduPID Controller in setup() Source: https://github.com/powerbroker2/ardupid/blob/main/README.md This snippet shows the essential configuration steps for the ArduPID controller within the Arduino `setup()` function. It includes setting PID gains, output limits, integral limits to prevent wind-up, and output direction. ```cpp void setup() { Serial.begin(115200); // Set PID gains myController.setTunings(kp, ki, kd); // Optional configuration myController.setOutputLimits(0, 255); // Clip output to actuator range myController.setILimits(-100, 100); // Prevent integral wind-up myController.setPLimits(-255, 255); // Optional P term limits myController.setDLimits(-50, 50); // Optional D term limits myController.setDirection(ArduPID::FORWARD); // Set output direction } ``` -------------------------------- ### Arduino PID Temperature Control Example Source: https://context7.com/powerbroker2/ardupid/llms.txt This example demonstrates PID-based temperature control for a heating element using the ArduPID library. It includes safety limits to prevent overheating and uses PWM to control the heater. The code reads temperature from an analog sensor, computes the PID output, and applies it to the heater pin, while also providing serial output for monitoring. ```cpp #include "ArduPID.h" // Pin definitions const int HEATER_PIN = 9; const int TEMP_SENSOR_PIN = A0; const int STATUS_LED_PIN = 13; // PID controller ArduPID tempController; // Temperature constants const float MAX_SAFE_TEMP = 80.0; // Maximum safe temperature const float TARGET_TEMP = 50.0; // Default target temperature void setup() { Serial.begin(115200); pinMode(HEATER_PIN, OUTPUT); pinMode(STATUS_LED_PIN, OUTPUT); // Configure temperature PID controller tempController.setName("TEMP"); tempController.setTunings(10.0, 0.5, 2.0); // Aggressive P for fast heating tempController.setSetpoint(TARGET_TEMP); tempController.setDtS(0.1); // 10 Hz sample rate tempController.setOutputLimits(0, 255); // PWM range for heater tempController.setILimits(-50, 50); // Limit integral buildup tempController.setPLimits(-255, 255); // Full P range tempController.setDMode(ArduPID::D_ON_M); // Smooth derivative tempController.setAntiWindMode(ArduPID::BACK_CALC); tempController.setAntiWindupGain(0.2); Serial.println("Temperature Controller Ready"); Serial.print("Target: "); Serial.print(TARGET_TEMP); Serial.println(" C"); } void loop() { // Read temperature sensor (10mV per degree, 0.5V offset for TMP36) float voltage = analogRead(TEMP_SENSOR_PIN) * (5.0 / 1024.0); float currentTemp = (voltage - 0.5) * 100.0; // Safety check if (currentTemp > MAX_SAFE_TEMP) { analogWrite(HEATER_PIN, 0); // Emergency shutoff digitalWrite(STATUS_LED_PIN, HIGH); Serial.println("OVERHEAT! Heater disabled."); delay(1000); return; } digitalWrite(STATUS_LED_PIN, LOW); // Compute PID output float heaterPWM = tempController.compute(currentTemp); // Apply to heater analogWrite(HEATER_PIN, heaterPWM); // Get signals for monitoring ArduPID::Signals signals = tempController.getSignals(); Serial.print("Temp: "); Serial.print(currentTemp, 1); Serial.print("C, Target: "); Serial.print(TARGET_TEMP, 1); Serial.print("C, Heater: "); Serial.print((heaterPWM / 255.0) * 100.0, 0); Serial.print("%,"); Serial.print(" Error: "); Serial.println(signals.error, 2); delay(50); } ``` -------------------------------- ### Complete Motor Control Example with ArduPID in C++ Source: https://context7.com/powerbroker2/ardupid/llms.txt This comprehensive C++ example demonstrates PID-based motor speed control using the ArduPID library. It incorporates encoder feedback for RPM measurement, anti-windup techniques, and serial communication for monitoring and control adjustments. The code configures the PID controller with specific tuning parameters, sample rates, output limits, and derivative modes. ```cpp #include "ArduPID.h" // Pin definitions const int MOTOR_PWM_PIN = 9; const int MOTOR_DIR_PIN = 8; const int ENCODER_PIN = A0; // PID controller ArduPID speedController; // Control variables float targetRPM = 500; float currentRPM = 0; float motorPWM = 0; void setup() { Serial.begin(115200); pinMode(MOTOR_PWM_PIN, OUTPUT); pinMode(MOTOR_DIR_PIN, OUTPUT); digitalWrite(MOTOR_DIR_PIN, HIGH); // Forward direction // Configure PID controller speedController.setName("MOTOR"); speedController.setTunings(0.5, 0.2, 0.05); speedController.setSetpoint(targetRPM); speedController.setDtMs(10); // 100 Hz sample rate speedController.setOutputLimits(0, 255); // PWM range speedController.setILimits(-100, 100); // Prevent integral windup speedController.setDMode(ArduPID::D_ON_M); // Derivative on measurement speedController.setAntiWindMode(ArduPID::BACK_CALC); speedController.setAntiWindupGain(0.3); Serial.println("Motor Speed Controller Initialized"); Serial.println("Commands: '+' increase speed, '-' decrease speed, 'r' reset"); } void loop() { // Read encoder and convert to RPM currentRPM = analogRead(ENCODER_PIN) * 2.0; // Compute PID output motorPWM = speedController.compute(currentRPM); // Apply PWM to motor analogWrite(MOTOR_PWM_PIN, motorPWM); // Handle serial commands if (Serial.available()) { char cmd = Serial.read(); if (cmd == '+') { targetRPM += 50; speedController.setSetpoint(targetRPM); Serial.print("New target: "); Serial.println(targetRPM); } else if (cmd == '-') { targetRPM -= 50; if (targetRPM < 0) targetRPM = 0; speedController.setSetpoint(targetRPM); Serial.print("New target: "); Serial.println(targetRPM); } else if (cmd == 'r') { speedController.reset(); Serial.println("Controller reset"); } } // Debug output for Serial Plotter speedController.debug(ArduPID::PRINT_SETPOINT | ArduPID::PRINT_INPUT | ArduPID::PRINT_OUTPUT); delay(5); } ``` -------------------------------- ### Setting PID Gains with setTunings (C++) Source: https://context7.com/powerbroker2/ardupid/llms.txt Illustrates how to set the proportional (Kp), integral (Ki), and derivative (Kd) gain coefficients for the ArduPID controller. It provides examples for aggressive and conservative tuning, emphasizing that negative gains are not supported. ```cpp #include "ArduPID.h" ArduPID pid; void setup() { Serial.begin(115200); // Set PID gains: Kp=2.0, Ki=0.5, Kd=0.1 pid.setTunings(2.0, 0.5, 0.1); // For aggressive response (fast but may overshoot) // pid.setTunings(5.0, 2.0, 0.5); // For conservative response (slow but stable) // pid.setTunings(0.5, 0.1, 0.05); pid.setSetpoint(512); pid.setOutputLimits(0, 255); } void loop() { float input = analogRead(A0); float output = pid.compute(input); analogWrite(9, output); delay(10); } ``` -------------------------------- ### Reset PID Controller State (C++) Source: https://context7.com/powerbroker2/ardupid/llms.txt Resets the internal state of the PID controller, including integral and derivative terms, error history, and timestamps. This is useful for re-initializing the controller after significant system changes or when starting a new control loop. The reset is also called automatically when direction or sample time changes. ```cpp #include "ArduPID.h" ArduPID controller; bool systemEnabled = false; void setup() { Serial.begin(115200); controller.setTunings(2.0, 0.5, 0.1); controller.setSetpoint(512); controller.setOutputLimits(0, 255); } void loop() { // Check enable button bool enableButton = digitalRead(2); if (enableButton && !systemEnabled) { // System just enabled - reset controller to clear old state controller.reset(); Serial.println("Controller ENABLED and RESET"); systemEnabled = true; } else if (!enableButton && systemEnabled) { Serial.println("Controller DISABLED"); systemEnabled = false; } if (systemEnabled) { float input = analogRead(A0); float output = controller.compute(input); analogWrite(9, output); controller.debug(ArduPID::PRINT_OUTPUT | ArduPID::PRINT_I); } else { analogWrite(9, 0); // Output off when disabled } delay(10); } ``` -------------------------------- ### ArduPID Constructor and Basic Usage (C++) Source: https://context7.com/powerbroker2/ardupid/llms.txt Demonstrates how to create an ArduPID controller instance with default values and configure it for basic operation. It shows setting gains, setpoint, output limits, and performing a compute cycle. ```cpp #include "ArduPID.h" ArduPID myController; void setup() { Serial.begin(115200); // Controller is created with default values // Now configure it for your application myController.setTunings(2.0, 0.5, 0.1); myController.setSetpoint(100.0); myController.setOutputLimits(0, 255); } void loop() { float sensorValue = analogRead(A0); float output = myController.compute(sensorValue); analogWrite(3, output); } ``` -------------------------------- ### Instantiate ArduPID Controller and Variables Source: https://github.com/powerbroker2/ardupid/blob/main/README.md This snippet demonstrates how to create an instance of the ArduPID controller and declare variables for setpoint, input, output, and PID gains (kp, ki, kd). ```cpp ArduPID myController; float setpoint = 512; float input; float output; float kp = 1.0; float ki = 0.0; float kd = 0.0; ``` -------------------------------- ### Set/Get Full PID Controller Configuration (C++) Source: https://context7.com/powerbroker2/ardupid/llms.txt Allows setting or retrieving the entire PID controller configuration structure at once. This is useful for bulk configuration changes or for saving and restoring the controller's state. The configuration includes tuning parameters, output limits, and control modes. ```cpp #include "ArduPID.h" ArduPID controller; void setup() { Serial.begin(115200); // Create and configure a Config structure ArduPID::Config config; strcpy(config.name, "MOTOR"); config.kp = 2.0; config.ki = 0.5; config.kd = 0.1; config.outMin = 0; config.outMax = 255; config.pMode = ArduPID::P_ON_E; config.dMode = ArduPID::D_ON_M; config.direction = ArduPID::FORWARD; config.dt = 10000; // 10ms in microseconds config.dts = 0.01; // 10ms in seconds // Apply entire configuration at once controller.setConfig(config); controller.setSetpoint(512); } void loop() { float input = analogRead(A0); float output = controller.compute(input); analogWrite(9, output); // Retrieve current configuration ArduPID::Config currentConfig = controller.getConfig(); Serial.print("Kp: "); Serial.print(currentConfig.kp); Serial.print(", Ki: "); Serial.print(currentConfig.ki); Serial.print(", Kd: "); Serial.println(currentConfig.kd); delay(100); } ``` -------------------------------- ### Setting the Target Value with setSetpoint (C++) Source: https://context7.com/powerbroker2/ardupid/llms.txt Shows how to define the desired target value (setpoint) for the ArduPID controller. This function is crucial for applications like temperature regulation, where the controller aims to maintain a specific temperature. ```cpp #include "ArduPID.h" ArduPID temperatureController; const int HEATER_PIN = 9; const int TEMP_SENSOR_PIN = A0; void setup() { Serial.begin(115200); temperatureController.setTunings(2.0, 0.5, 0.1); temperatureController.setOutputLimits(0, 255); // Set target temperature (scaled sensor value) temperatureController.setSetpoint(150.0); // Target: 150 degrees } void loop() { float currentTemp = analogRead(TEMP_SENSOR_PIN) * 0.48828125; // Convert to Celsius float heaterPower = temperatureController.compute(currentTemp); analogWrite(HEATER_PIN, heaterPower); Serial.print("Setpoint: 150, Current: "); Serial.print(currentTemp); Serial.print(", Output: "); Serial.println(heaterPower); delay(100); } ``` -------------------------------- ### Executing PID Control Loop with compute (C++) Source: https://context7.com/powerbroker2/ardupid/llms.txt Demonstrates the core `compute` function of the ArduPID library, which performs a single PID update cycle. It takes the current sensor measurement as input and returns the calculated control output. The function intelligently handles timing to ensure consistent sampling. ```cpp #include "ArduPID.h" ArduPID motorController; const int MOTOR_PWM_PIN = 5; const int ENCODER_PIN = A0; void setup() { Serial.begin(115200); motorController.setTunings(1.5, 0.3, 0.05); motorController.setSetpoint(500); // Target RPM motorController.setOutputLimits(0, 255); // PWM range motorController.setDtMs(10); // 10ms sample time } void loop() { // Read encoder feedback (scaled to RPM) float currentRPM = analogRead(ENCODER_PIN) * 2.0; // Compute PID output float motorPWM = motorController.compute(currentRPM); // Apply to motor analogWrite(MOTOR_PWM_PIN, motorPWM); // Debug output Serial.print("Target: 500 RPM, Current: "); Serial.print(currentRPM); Serial.print(" RPM, PWM: "); Serial.println(motorPWM); delay(5); // Loop runs faster than sample time - compute() handles timing } ``` -------------------------------- ### Retrieve PID Controller Signals with ArduPID in C++ Source: https://context7.com/powerbroker2/ardupid/llms.txt This C++ code snippet demonstrates how to retrieve detailed internal signals from an ArduPID controller. It includes the setpoint, input, error, P, I, D contributions, and output. This is useful for debugging, tuning, and collecting telemetry data. ```cpp #include "ArduPID.h" ArduPID controller; void setup() { Serial.begin(115200); controller.setTunings(2.0, 0.5, 0.1); controller.setSetpoint(512); controller.setOutputLimits(0, 255); } void loop() { float input = analogRead(A0); float output = controller.compute(input); analogWrite(9, output); // Get all internal signals for analysis ArduPID::Signals signals = controller.getSignals(); Serial.print("Setpoint: "); Serial.print(signals.setpoint); Serial.print(", Input: "); Serial.print(signals.input); Serial.print(", Error: "); Serial.print(signals.error); Serial.print(", P: "); Serial.print(signals.p); Serial.print(", I: "); Serial.print(signals.i); Serial.print(", D: "); Serial.print(signals.d); Serial.print(", Output: "); Serial.println(signals.out); delay(50); } ``` -------------------------------- ### Include ArduPID Library Source: https://github.com/powerbroker2/ardupid/blob/main/README.md This snippet shows how to include the ArduPID library in your Arduino sketch. It is a prerequisite for using any of the library's functionalities. ```cpp #include "ArduPID.h" ``` -------------------------------- ### Configure Anti-Windup Strategy (BACK_CALC, CLEGG) in ArduPID Source: https://context7.com/powerbroker2/ardupid/llms.txt Sets the anti-windup strategy for the PID controller's integrator. Options include NONE (disables anti-windup), BACK_CALC (uses back-calculation based on output saturation, an industrial standard), and CLEGG (resets the integrator when the error crosses zero). The BACK_CALC mode requires output limits to be set and utilizes an anti-windup gain. ```cpp #include "ArduPID.h" ArduPID backCalcPID; ArduPID cleggPID; void setup() { Serial.begin(115200); // Back-calculation anti-windup (industrial standard) backCalcPID.setTunings(2.0, 1.0, 0.1); backCalcPID.setSetpoint(800); // High setpoint may cause saturation backCalcPID.setOutputLimits(0, 255); // Output limits required for back-calc backCalcPID.setAntiWindMode(ArduPID::BACK_CALC); backCalcPID.setAntiWindupGain(0.5); // Back-calculation gain // Clegg integrator anti-windup (resets I on zero-crossing) cleggPID.setTunings(2.0, 1.0, 0.1); cleggPID.setSetpoint(800); cleggPID.setOutputLimits(0, 255); cleggPID.setAntiWindMode(ArduPID::CLEGG); } void loop() { float input = analogRead(A0); float backCalcOutput = backCalcPID.compute(input); float cleggOutput = cleggPID.compute(input); ArduPID::Signals backCalcSignals = backCalcPID.getSignals(); ArduPID::Signals cleggSignals = cleggPID.getSignals(); Serial.print("BackCalc I: "); Serial.print(backCalcSignals.i); Serial.print(", Clegg I: "); Serial.println(cleggSignals.i); analogWrite(9, backCalcOutput); delay(10); } ``` -------------------------------- ### Set Proportional Control Percentage (C++) Source: https://context7.com/powerbroker2/ardupid/llms.txt Configures the blend between proportional-on-error (P_ON_E) and proportional-on-measurement (P_ON_M) modes. Accepts values from 0 to 100 percent. This function allows fine-tuning the controller's response to error and measurement changes. ```cpp #include "ArduPID.h" ArduPID blendedPID; void setup() { Serial.begin(115200); blendedPID.setTunings(2.5, 0.5, 0.3); blendedPID.setSetpoint(512); blendedPID.setOutputLimits(0, 255); // 70% proportional-on-error, 30% proportional-on-measurement blendedPID.setPercentPonE(70); // Alternative: specify by measurement percentage // blendedPID.setPercentPonM(30); // Same as setPercentPonE(70) // Full proportional-on-error (default behavior) // blendedPID.setPercentPonE(100); // Full proportional-on-measurement // blendedPID.setPercentPonM(100); } void loop() { float input = analogRead(A0); float output = blendedPID.compute(input); analogWrite(9, output); blendedPID.debug(ArduPID::PRINT_SETPOINT | ArduPID::PRINT_INPUT | ArduPID::PRINT_OUTPUT); delay(10); } ``` -------------------------------- ### Debug PID Controller Signals with ArduPID in C++ Source: https://context7.com/powerbroker2/ardupid/llms.txt This C++ code snippet shows how to use the ArduPID library's debug function to print selected PID signals to a serial stream. It utilizes bitmask flags to choose which values to output, making it compatible with tools like the Arduino Serial Plotter for visualization. ```cpp #include "ArduPID.h" ArduPID controller; void setup() { Serial.begin(115200); controller.setName("PID1"); controller.setTunings(2.0, 0.5, 0.1); controller.setSetpoint(512); controller.setOutputLimits(0, 255); } void loop() { float input = analogRead(A0); float output = controller.compute(input); analogWrite(9, output); // Print setpoint and output (for Serial Plotter) controller.debug(ArduPID::PRINT_SETPOINT | ArduPID::PRINT_OUTPUT); // Output: "PID1_SP PID1_OUT 512.00 127.50 " // Print all PID terms for tuning analysis // controller.debug(ArduPID::PRINT_P | ArduPID::PRINT_I | ArduPID::PRINT_D); // Print input, output, and setpoint // controller.debug(ArduPID::PRINT_INPUT | ArduPID::PRINT_OUTPUT | ArduPID::PRINT_SETPOINT); // Print gains (useful for adaptive tuning) // controller.debug(ArduPID::PRINT_KP | ArduPID::PRINT_KI | ArduPID::PRINT_KD); // Print to different stream (e.g., Serial2) // controller.debug(ArduPID::PRINT_OUTPUT, Serial2); delay(10); } ``` -------------------------------- ### Set Proportional Control Mode (P_ON_E, P_ON_M) with ArduPID Source: https://context7.com/powerbroker2/ardupid/llms.txt Selects the proportional control mode: P_ON_E (proportional on error) or P_ON_M (proportional on measurement). P_ON_E is standard and reacts to the difference between setpoint and measurement, while P_ON_M reacts to measurement changes, which can reduce overshoot when the setpoint is altered. ```cpp #include "ArduPID.h" ArduPID standardPID; ArduPID smoothPID; void setup() { Serial.begin(115200); // Standard proportional-on-error (responsive to setpoint changes) standardPID.setTunings(2.0, 0.5, 0.1); standardPID.setPMode(ArduPID::P_ON_E); standardPID.setSetpoint(512); standardPID.setOutputLimits(0, 255); // Proportional-on-measurement (reduces overshoot) smoothPID.setTunings(2.0, 0.5, 0.1); smoothPID.setPMode(ArduPID::P_ON_M); smoothPID.setSetpoint(512); smoothPID.setOutputLimits(0, 255); } void loop() { float input = analogRead(A0); float standardOutput = standardPID.compute(input); float smoothOutput = smoothPID.compute(input); Serial.print("Standard (P_ON_E): "); Serial.print(standardOutput); Serial.print(", Smooth (P_ON_M): "); Serial.println(smoothOutput); delay(10); } ``` -------------------------------- ### Set Output Limits for ArduPID Controller Source: https://context7.com/powerbroker2/ardupid/llms.txt Sets the minimum and maximum bounds for the controller output. The output is clamped to this range after computing the sum of P, I, and D terms. Essential for protecting actuators from over-driving. This function takes two arguments: the minimum output limit and the maximum output limit. ```cpp #include "ArduPID.h" ArduPID servoController; const int SERVO_PIN = 9; void setup() { Serial.begin(115200); servoController.setTunings(1.0, 0.2, 0.05); servoController.setSetpoint(90); // Target angle: 90 degrees // Limit output to valid servo PWM range (0-180 degrees) servoController.setOutputLimits(0, 180); // For bidirectional motor control (-255 to 255) // servoController.setOutputLimits(-255, 255); // For unidirectional PWM (0 to 255) // servoController.setOutputLimits(0, 255); } void loop() { float currentAngle = analogRead(A0) * (180.0 / 1023.0); float servoCommand = servoController.compute(currentAngle); // Output is guaranteed to be within 0-180 range analogWrite(SERVO_PIN, servoCommand); delay(20); } ``` -------------------------------- ### Assign Name to PID Controller (C++) Source: https://context7.com/powerbroker2/ardupid/llms.txt Assigns a human-readable name to a PID controller instance, which is used for identification in debug output. The name can be up to 31 characters long. This is particularly helpful when managing multiple PID controllers simultaneously. ```cpp #include "ArduPID.h" ArduPID leftMotor; ArduPID rightMotor; void setup() { Serial.begin(115200); // Name controllers for easier debugging leftMotor.setName("LEFT"); leftMotor.setTunings(1.5, 0.3, 0.1); leftMotor.setSetpoint(500); leftMotor.setOutputLimits(0, 255); rightMotor.setName("RIGHT"); rightMotor.setTunings(1.5, 0.3, 0.1); rightMotor.setSetpoint(500); rightMotor.setOutputLimits(0, 255); } void loop() { float leftEncoder = analogRead(A0) * 2.0; float rightEncoder = analogRead(A1) * 2.0; float leftPWM = leftMotor.compute(leftEncoder); float rightPWM = rightMotor.compute(rightEncoder); analogWrite(9, leftPWM); analogWrite(10, rightPWM); // Debug output shows controller names // Output: "LEFT_SP 500 LEFT_OUT 127 " leftMotor.debug(ArduPID::PRINT_SETPOINT | ArduPID::PRINT_OUTPUT); // Output: "RIGHT_SP 500 RIGHT_OUT 130 " rightMotor.debug(ArduPID::PRINT_SETPOINT | ArduPID::PRINT_OUTPUT); delay(10); } ``` -------------------------------- ### Set Proportional (P) Limits for ArduPID Controller Source: https://context7.com/powerbroker2/ardupid/llms.txt Sets limits for the proportional term contribution. Useful for systems where large sudden errors could cause dangerous proportional kicks. This function takes two arguments: the minimum proportional limit and the maximum proportional limit. ```cpp #include "ArduPID.h" ArduPID safetyController; void setup() { Serial.begin(115200); safetyController.setTunings(5.0, 0.5, 0.2); // High Kp for fast response safetyController.setSetpoint(500); safetyController.setOutputLimits(0, 255); // Limit proportional term to prevent aggressive spikes safetyController.setPLimits(-150, 150); // Also limit integral to prevent windup safetyController.setILimits(-100, 100); } void loop() { float input = analogRead(A0); float output = safetyController.compute(input); analogWrite(9, output); ArduPID::Signals signals = safetyController.getSignals(); Serial.print("P: "); Serial.print(signals.p); // Limited to -150 to 150 Serial.print(", I: "); Serial.print(signals.i); Serial.print(", D: "); Serial.println(signals.d); delay(10); } ``` -------------------------------- ### Update ArduPID Controller in loop() Source: https://github.com/powerbroker2/ardupid/blob/main/README.md This snippet illustrates how to continuously update the ArduPID controller within the Arduino `loop()` function. It involves reading sensor input, computing the PID output, optionally debugging, and sending the output to an actuator. ```cpp void loop() { // Read sensor input input = analogRead(A0); // Replace with your sensor reading // Compute PID output output = myController.compute(input); // Debug information (prints selected signals to Serial) myController.debug(ArduPID::PRINT_OUTPUT | ArduPID::PRINT_SETPOINT); // Send output to actuator analogWrite(3, output); // Replace with your actuator control } ``` -------------------------------- ### Set Derivative Mode (D_ON_M vs D_ON_E) in ArduPID Source: https://context7.com/powerbroker2/ardupid/llms.txt Configures the derivative calculation mode for the PID controller. D_ON_M calculates the derivative of the measurement, which is generally preferred to avoid 'derivative kick' on setpoint changes. D_ON_E calculates the derivative of the error, suitable for systems with infrequent setpoint changes. This function requires the ArduPID library. ```cpp #include "ArduPID.h" ArduPID motorPID; void setup() { Serial.begin(115200); motorPID.setTunings(1.5, 0.3, 1.0); // Significant derivative gain motorPID.setSetpoint(500); motorPID.setOutputLimits(0, 255); // Use derivative-on-measurement to avoid kick on setpoint changes motorPID.setDMode(ArduPID::D_ON_M); // Alternative: derivative-on-error for systems where setpoint rarely changes // motorPID.setDMode(ArduPID::D_ON_E); } void loop() { static unsigned long lastSetpointChange = 0; // Change setpoint every 5 seconds if (millis() - lastSetpointChange > 5000) { float newSetpoint = random(400, 600); motorPID.setSetpoint(newSetpoint); Serial.print("New setpoint: "); Serial.println(newSetpoint); lastSetpointChange = millis(); } float rpm = analogRead(A0) * 2.0; float output = motorPID.compute(rpm); analogWrite(9, output); // D_ON_M prevents output spike when setpoint changes motorPID.debug(ArduPID::PRINT_OUTPUT | ArduPID::PRINT_D); delay(10); } ``` -------------------------------- ### Set Back-Calculation Anti-Windup Gain (Kaw) in ArduPID Source: https://context7.com/powerbroker2/ardupid/llms.txt Sets the gain (Kaw) for the back-calculation anti-windup strategy. This parameter is specifically used when the `ArduPID::BACK_CALC` anti-windup mode is enabled. A higher gain results in more aggressive compensation for integrator windup when the controller output saturates. The typical range for this gain is between 0.1 and 2.0. ```cpp #include "ArduPID.h" ArduPID controller; void setup() { Serial.begin(115200); controller.setTunings(3.0, 2.0, 0.5); controller.setSetpoint(900); // High setpoint likely to cause saturation controller.setOutputLimits(0, 255); // Enable back-calculation anti-windup controller.setAntiWindMode(ArduPID::BACK_CALC); // Set anti-windup gain // Higher values = faster integral recovery from saturation // Typical range: 0.1 to 2.0 controller.setAntiWindupGain(1.0); } void loop() { float input = analogRead(A0); float output = controller.compute(input); ArduPID::Signals signals = controller.getSignals(); Serial.print("Error: "); Serial.print(signals.error); Serial.print(", I term: "); Serial.print(signals.i); Serial.print(", Output: "); Serial.println(output); analogWrite(9, output); delay(10); } ``` -------------------------------- ### Set Controller Update Period (ms, us, s) with ArduPID Source: https://context7.com/powerbroker2/ardupid/llms.txt Defines the controller's update interval using milliseconds (setDtMs), microseconds (setDtUs), or seconds (setDtS). The controller only computes when the specified time has passed since the last update, ensuring consistent control loop frequency. Changing the sample time resets the controller state. ```cpp #include "ArduPID.h" ArduPID fastController; ArduPID slowController; void setup() { Serial.begin(115200); // Fast controller: 10ms sample time (100 Hz) fastController.setTunings(1.0, 0.5, 0.1); fastController.setDtMs(10); // 10 milliseconds fastController.setSetpoint(512); fastController.setOutputLimits(0, 255); // Slow controller: 0.5 second sample time (2 Hz) slowController.setTunings(2.0, 0.3, 0.2); slowController.setDtS(0.5); // 0.5 seconds slowController.setSetpoint(512); slowController.setOutputLimits(0, 255); // Alternative: use microseconds for very fast control // ultraFastController.setDtUs(1000); // 1000 microseconds = 1ms } void loop() { float input1 = analogRead(A0); float input2 = analogRead(A1); float output1 = fastController.compute(input1); // Updates at 100 Hz float output2 = slowController.compute(input2); // Updates at 2 Hz analogWrite(9, output1); analogWrite(10, output2); delay(1); // Loop runs at ~1000 Hz, but controllers respect their own timing } ``` -------------------------------- ### Set Integral (I) Limits for ArduPID Controller Source: https://context7.com/powerbroker2/ardupid/llms.txt Sets limits for the integral term to prevent integral windup. When the system cannot reach the setpoint (e.g., actuator saturation), the integral term can grow indefinitely. Setting I limits prevents this accumulation and ensures faster recovery. This function takes two arguments: the minimum integral limit and the maximum integral limit. ```cpp #include "ArduPID.h" ArduPID positionController; void setup() { Serial.begin(115200); positionController.setTunings(2.0, 1.0, 0.3); positionController.setSetpoint(512); positionController.setOutputLimits(0, 255); // Limit integral term to prevent windup // Integral contribution clamped to -100 to 100 positionController.setILimits(-100, 100); // For systems with large steady-state errors // positionController.setILimits(-200, 200); } void loop() { float position = analogRead(A0); float output = positionController.compute(position); analogWrite(3, output); // Monitor integral term behavior ArduPID::Signals signals = positionController.getSignals(); Serial.print("I term: "); Serial.print(signals.i); // Will be within -100 to 100 Serial.print(", Output: "); Serial.println(output); delay(10); } ``` -------------------------------- ### Set Controller Direction with ArduPID Source: https://context7.com/powerbroker2/ardupid/llms.txt Configures the controller's direction (FORWARD or BACKWARD) to adjust how output changes with error. This function resets controller state to prevent transients. It's useful for systems like cooling where increased output should correspond to a positive error (e.g., temperature above setpoint). ```cpp #include "ArduPID.h" ArduPID coolingController; const int COOLING_FAN_PIN = 9; void setup() { Serial.begin(115200); coolingController.setTunings(2.0, 0.5, 0.1); coolingController.setSetpoint(25.0); // Target: 25 degrees Celsius coolingController.setOutputLimits(0, 255); // BACKWARD: When temperature is above setpoint (positive error), // we want to INCREASE cooling (increase fan speed) // Standard heating would use FORWARD coolingController.setDirection(ArduPID::BACKWARD); } void loop() { float temperature = analogRead(A0) * 0.48828125; // Convert to Celsius float fanSpeed = coolingController.compute(temperature); analogWrite(COOLING_FAN_PIN, fanSpeed); Serial.print("Temp: "); Serial.print(temperature); Serial.print("C, Fan PWM: "); Serial.println(fanSpeed); delay(100); } ``` -------------------------------- ### Set Derivative (D) Limits for ArduPID Controller Source: https://context7.com/powerbroker2/ardupid/llms.txt Sets limits for the derivative term contribution. Useful for filtering out noise-induced derivative spikes that could cause erratic output behavior. This function takes two arguments: the minimum derivative limit and the maximum derivative limit. ```cpp #include "ArduPID.h" ArduPID noisySystemController; void setup() { Serial.begin(115200); noisySystemController.setTunings(1.5, 0.3, 2.0); // High Kd for damping noisySystemController.setSetpoint(512); noisySystemController.setOutputLimits(0, 255); // Limit derivative term to filter noise spikes noisySystemController.setDLimits(-50, 50); // Use derivative on measurement to avoid setpoint kick noisySystemController.setDMode(ArduPID::D_ON_M); } void loop() { float noisySensor = analogRead(A0); // Noisy sensor input float output = noisySystemController.compute(noisySensor); analogWrite(5, output); ArduPID::Signals signals = noisySystemController.getSignals(); Serial.print("D term (limited): "); Serial.println(signals.d); // Will be within -50 to 50 delay(10); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.