How to Implement PID Controller in Arduino: Simple Guide
To implement a
PID controller in Arduino, you need to calculate the proportional, integral, and derivative terms based on the error between your target and current value, then adjust the output accordingly. Use the PID library or write your own code to update these terms in the Arduino loop for real-time control.Syntax
A PID controller in Arduino typically uses three main parts: proportional (P), integral (I), and derivative (D) calculations. The general formula is:
- Proportional (P): Reacts to current error.
- Integral (I): Reacts to accumulated past errors.
- Derivative (D): Reacts to the rate of error change.
In code, you calculate each term and sum them to get the control output.
arduino
double error = setpoint - input; double integral = integral + error * dt; double derivative = (error - previous_error) / dt; double output = Kp * error + Ki * integral + Kd * derivative; previous_error = error;
Example
This example shows a simple PID controller that tries to reach a target value by adjusting an output. It uses fixed PID constants and updates every 100 milliseconds.
arduino
#include <Arduino.h> // PID constants const double Kp = 2.0; const double Ki = 0.5; const double Kd = 1.0; // Variables double setpoint = 100.0; // Target value double input = 0.0; // Current value double output = 0.0; // Control output // PID terms double integral = 0.0; double previous_error = 0.0; unsigned long lastTime = 0; const unsigned long sampleTime = 100; // milliseconds void setup() { Serial.begin(9600); lastTime = millis(); } void loop() { unsigned long now = millis(); if (now - lastTime >= sampleTime) { double dt = (now - lastTime) / 1000.0; // convert to seconds lastTime = now; double error = setpoint - input; integral += error * dt; double derivative = (error - previous_error) / dt; output = Kp * error + Ki * integral + Kd * derivative; // Simulate system response (for demo): input changes by output * dt input += output * dt; previous_error = error; Serial.print("Input: "); Serial.print(input); Serial.print(" Output: "); Serial.println(output); } }
Output
Input: 0 Output: 200
Input: 0.02 Output: 197.9
Input: 0.03958 Output: 195.8
... (values approach 100 over time)
Common Pitfalls
Common mistakes when implementing PID controllers in Arduino include:
- Not tuning PID constants (Kp, Ki, Kd) properly, causing oscillations or slow response.
- Ignoring the time difference
dtbetween updates, which leads to incorrect integral and derivative calculations. - Integral windup: integral term grows too large if error persists, causing overshoot.
- Not initializing variables like
previous_errorandintegralto zero.
Always test with small values and adjust constants step-by-step.
arduino
/* Wrong way: ignoring dt and integral windup */ double error = setpoint - input; integral += error; // no dt multiplication double derivative = error - previous_error; // no dt division output = Kp * error + Ki * integral + Kd * derivative; previous_error = error; /* Right way: include dt and limit integral */ double dt = (now - lastTime) / 1000.0; integral += error * dt; if (integral > 100) integral = 100; // limit integral windup if (integral < -100) integral = -100; double derivative = (error - previous_error) / dt; output = Kp * error + Ki * integral + Kd * derivative; previous_error = error;
Quick Reference
Tips for smooth PID implementation:
- Start with Kp only, then add Ki and Kd gradually.
- Use consistent time intervals and calculate
dtprecisely. - Limit the integral term to prevent windup.
- Test your controller with simple simulated inputs before hardware.
- Consider using the Arduino
PIDlibrary for easier setup.
Key Takeaways
Calculate proportional, integral, and derivative terms using error and time difference for accurate control.
Tune PID constants carefully to avoid oscillations or slow response.
Prevent integral windup by limiting the integral term.
Use consistent timing (dt) in your calculations for stable behavior.
Test your PID code with simple simulations before applying to real hardware.