Example Code for Arduino-PID Speed Control

This tutorial demonstrates how to drive a DC motor using the L298P DC motor driver board, with a PID control algorithm applied to regulate the motor speed.

Hardware Preparation

Software Preparation

Wiring Diagram

Motor PID Wiring (correspond to example2)
Just connect the positive and the negative to M1 and remain other parts as the same, and download example2.

FIT0520, FIT0521, FIT0522 Metal DC Geared Motor w/Encoder Connection Diagram

Other Preparation Work

In this tutorial, D2 and D3 are selected, D2 is the interrupt pin and D3 is the signal input pin.
In practice, we just need to ensure one interrupt pin, and the other pin can be self-defined (see master of the interrupt pin in the figure below)

Notcie: attachInterrupt()

FIT0520, FIT0521, FIT0522 Metal DC Geared Motor w/Encoder Connection Diagram

For example, if you want to use interrupt pin 0 (interrupt 0) on UNO, you can connect the number 2 digital pin (D2); With Interrupt Pin 1 (Interrupt 1), you can connect number 3 digital pin (D3).

Download and install the Arduino PID Library.

Sample Code

/*!
 * @file  FIT052X.ino
 * @brief Metal DC Motor Encoder - 6V
 * @n Drive the DC motor via the L298P DC motor drive board.
 * @n The PID algorithm controls the speed of the motor.
 * @copyright  Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @license  The MIT License (MIT)
 * @author  DFRobot
 * @version  V1.0
 * @date  2023-08-03
 */

 //The sample code for driving one way motor encoder
#include <PID_v1.h>
const byte encoder0pinA = 2;//A pin -> The interrupt pin 0
const byte encoder0pinB = 3;//B pin -> The digital pin 3
int E_left = 5; //Connect the enabling port of the L298P DC motor drive shield to digital port 5
int M_left = 4; //Connect the turning port of the L298P DC motor drive shield to digital port 4
byte encoder0PinALast;
double duration, abs_duration;//The number of the pulses
boolean Direction;//The rotation direction 
boolean result;

double val_output;//Provide the PWM output value to motor
double Setpoint;
double Kp = 0.6, Ki = 5, Kd = 0;
PID myPID(&abs_duration, &val_output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
{
  Serial.begin(9600);//Initialize the serial port
  pinMode(M_left, OUTPUT);   //Set the control port of the L298P DC motor drive shield to output mode 
  pinMode(E_left, OUTPUT);
  Setpoint = 80;  //Set PID output value
  myPID.SetMode(AUTOMATIC);//Set PID to automatic mode
  myPID.SetSampleTime(100);//Set the PID sampling frequency to 100ms
  EncoderInit();//Initialize the module
}

void loop()
{
  advance();//Motor rotates clockwise
  abs_duration = abs(duration);
  result = myPID.Compute();//The return value is 1 after PID conversion
  if (result) {
    Serial.print("Pluse: ");
    Serial.println(duration);
    duration = 0; //Clear count value and waits for the next count
  }


}

void EncoderInit()
{
  Direction = true;//default -> Forward  
  pinMode(encoder0pinB, INPUT);
  attachInterrupt(0, wheelSpeed, CHANGE);
}

void wheelSpeed()
{
  int Lstate = digitalRead(encoder0pinA);
  if ((encoder0PinALast == LOW) && Lstate == HIGH) {
    int val = digitalRead(encoder0pinB);
    if (val == LOW && Direction) {
      Direction = false; //Reverse
    } else if (val == HIGH && !Direction) {
      Direction = true;  //Forward
    }
  }
  encoder0PinALast = Lstate;

  if (!Direction)  duration++;
  else  duration--;

}
void advance()//Motor rotates clockwise
{
  digitalWrite(M_left, LOW);
  analogWrite(E_left, val_output);
}
void back()//Motor rotates counterclockwise
{
  digitalWrite(M_left, HIGH);
  analogWrite(E_left, val_output);
}

void Stop()//Motor stops
{
  digitalWrite(E_left, LOW);
}

Result

Because the program sets a PID value of 80, the stable speed of the motor is around 80.
When external forces (such as the driving voltage change of the motor, the resistance of the motor increased, etc.) force the speed to change, the program adjust the speed to about 80 through the PWM.
For example, increase the motor drive voltage, the motor speed will briefly rise to 80. Reduce the motor drive voltage, the motor speed will temporarily drop, then rise to 80.

Was this article helpful?

TOP