Abstract
In this paper, we explore the design and implementation of a Proportional-Integral-
Derivative (PID) controller for precise control of DC motors using an Arduino
microcontroller. PID controllers are extensively used in industrial and robotics
applications due to their simplicity, robustness, and efficiency. This study focuses
on tuning the PID parameters to achieve accurate speed control, minimal steady-
state error, and faster response times. Experimental results demonstrate the effect
of various tuning methods on motor performance, and practical insights are
provided for real-world applications.
1. Introduction
The need for precise motor control is vital in various applications, from robotics
and automation systems to automotive and aerospace industries. Motors must
respond accurately to control inputs to maintain the desired behavior of the system.
In such cases, a PID controller is often used due to its effectiveness in balancing
responsiveness, stability, and accuracy.
This paper presents a detailed explanation of PID control applied to DC motors
using Arduino. We will cover the mathematical formulation of the PID algorithm,
hardware requirements, and software implementation. The final objective is to
design a system that allows a user to control motor speed with minimal overshoot
and steady-state error.
2. Theory of PID Control
A PID controller uses feedback to minimize the difference between a desired
setpoint and the actual system output. It consists of three terms:
1. Proportional (P): This term produces an output value proportional to the
current error. Increasing the proportional gain (KpK_pKp) improves the
response but can lead to instability if set too high.
2. Integral (I): This term sums the past errors to eliminate steady-state offset.
It improves long-term accuracy but can also introduce oscillations if not
tuned properly.
3. Derivative (D): This term predicts future error based on its rate of change. It
provides damping and reduces overshoot.
The general PID control equation is given by:
u(t)=Kpe(t)+Ki∫0te(τ)dτ+Kdde(t)dtu(t) = K_p e(t) + K_i \int_0^t e(\tau) d\tau +
K_d \frac{de(t)}{dt}u(t)=Kpe(t)+Ki∫0te(τ)dτ+Kddtde(t)
Where:
u(t)u(t)u(t) is the control output (e.g., PWM signal for motor speed),
e(t)e(t)e(t) is the current error e(t)=Setpoint−Measured Valuee(t) = \
text{Setpoint} - \text{Measured Value}e(t)=Setpoint−Measured Value,
KpK_pKp, KiK_iKi, and KdK_dKd are the proportional, integral, and
derivative gains, respectively.
3. Hardware Components
The following hardware components are used for implementing the PID controller:
Arduino Uno: The microcontroller that runs the control algorithm and
interfaces with sensors and actuators.
DC Motor: The actuator that responds to the control signals.
L298N Motor Driver: Converts low-power signals from Arduino to higher-
power signals suitable for motor control.
Incremental Encoder: Provides feedback on motor speed and position.
Power Supply: Provides sufficient voltage and current to the motor and
controller.
Circuit Diagram:
A detailed schematic showing the connection between the Arduino, L298N motor
driver, and encoder.
4. Arduino Implementation
The control algorithm is programmed on Arduino using the built-in PWM (Pulse
Width Modulation) functionalities. Below is a simplified version of the code:
cpp
CopyEdit
// PID constants
float Kp = 2.0;
float Ki = 0.5;
float Kd = 1.0;
int setpoint = 100; // Desired speed in RPM
int motorPin = 9;
int encoderPin = 2;
volatile int encoderTicks = 0;
unsigned long lastTime;
float integral = 0;
float previousError = 0;
void setup() {
pinMode(motorPin, OUTPUT);
attachInterrupt(digitalPinToInterrupt(encoderPin), countTicks,
RISING);
Serial.begin(9600);
}
void loop() {
unsigned long now = millis();
float dt = (now - lastTime) / 1000.0; // Time difference in seconds
lastTime = now;
float speed = encoderTicks / dt; // RPM calculation
encoderTicks = 0;
float error = setpoint - speed;
integral += error * dt;
float derivative = (error - previousError) / dt;
float output = (Kp * error) + (Ki * integral) + (Kd * derivative);
output = constrain(output, 0, 255); // Limit output to valid PWM
range
analogWrite(motorPin, output);
previousError = error;
Serial.println(speed); // Monitor speed
delay(100);
}
void countTicks() {
encoderTicks++;
}
5. Tuning Methods
Tuning PID parameters (Kp,Ki,KdK_p, K_i, K_dKp,Ki,Kd) is crucial for
achieving stable control. Two popular methods are:
Ziegler-Nichols Method:
o Increase KpK_pKp until the system reaches the ultimate gain
KuK_uKu (causing oscillations).
o Record the oscillation period TuT_uTu.
o Set:
Kp=0.6KuK_p = 0.6K_uKp=0.6Ku
Ki=2Kp/TuK_i = 2K_p/T_uKi=2Kp/Tu
Kd=KpTu/8K_d = K_p T_u/8Kd=KpTu/8
Manual Tuning:
o Increase KpK_pKp until oscillations begin.
o Adjust KiK_iKi to reduce steady-state error.
o Fine-tune KdK_dKd to dampen overshoot.
6. Results and Analysis
We measured system performance using the following metrics:
Rise Time: Time taken to reach the desired speed.
Overshoot: Extent to which the system exceeds the desired value.
Settling Time: Time taken to stabilize within a specific error margin.
Steady-State Error: Final error between the desired and actual speed.
Graphical Analysis:
Speed vs. Time graphs for various tuning configurations.
Findings:
Proper tuning of KdK_dKd significantly reduced overshoot.
Higher KiK_iKi values minimized steady-state error but introduced
oscillations.
7. Applications
PID controllers are used in various real-world applications:
Robotic arms: Smooth and accurate joint movements.
Automated conveyor systems: Maintaining consistent speeds.
Self-balancing robots: Stabilization using feedback loops.
8. Conclusion
A well-tuned PID controller ensures accurate and stable motor control. Our
Arduino-based implementation effectively demonstrates real-world applicability in
robotics and automation systems. Future work could explore adaptive PID control
techniques or integration with machine learning algorithms for dynamic tuning.