0
0
AutocadHow-ToBeginner · 4 min read

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 dt between 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_error and integral to 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 dt precisely.
  • Limit the integral term to prevent windup.
  • Test your controller with simple simulated inputs before hardware.
  • Consider using the Arduino PID library 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.