You are on page 1of 11

Speed and Position Control of a

Brushed
DC Motor

By
Mr.Shoaib Naseem

Report Prepared By:


Ihtisham Ali

FACULTY OF MECHANICAL ENGINEERING


GHULAM ISHAQ KHAN INSTITUTE
OFENGINEERING SCIENCES & TECHNLOGY

Table of Contents

Abstract......................................................................................................................................ii
Objective....................................................................................................................................1
Introduction................................................................................................................................1
Componenet List........................................................................................................................2
Appendix A................................................................................................................................3
Program Code...........................................................................................3

ABSTRACT
This report provides a technical review for position and speed control of a
Brushed DC motor drive, including the background analysis using sensors and
its limitation. The goal is to improve the overall efficiency of system by
individually tackling the accuracy and repeatibility of system.The speed of the
DC motor is varied using the pwm pins of arduino in a open loop system.The
close loop control acquires a feed back from the rotary optical encoder which in
turn is fed to PID controller to achieve a steady accurate output value.

OBJECTIVE
The objective of this experimentation is to achieve optimal control over
the speed and position of of DC motor with highly effiecient performance.

INTRODUCTION
The speed control of a motor is frequently required in industrial
applications, robotics, home appliances, etc. The idea of a speed control system
is to maintain the speed of the motor at the desired value under various
condition. In this report, we have implemented a DC motor speed control system.
The speed of dc motor is directly proportional to the supply voltage.If the
supply voltage is varied ,the speed of motor varies as well.The variability in input
voltage is achieved though pulse width modulation (pwm) pins of an arduino.The
pwm signal is provided to L298 Dual H-bridge IC which inturns provides the
motor with a proportional voltage to the dutycyle from the Supply Voltage.
In the closed loop system ,the speed of motor is controlled through PID
controller. In practice, the DC motor is a nonlinear device and its speed varies
because of change in load demand, disturbances,etc. We have implemented the
PID controller algorithm which is a popular controller in industries. The motor
speed is sensed and calculated through by an optical rotary encode and
converted to feedback voltage. It is compared with the reference signal (i.e.
desired speed) by the error detector. The PID controller acts on the error signal
and generates appropriate control voltage. The PWM generator block than varies
the duty cycle of the voltage supplied to the motor to control its speed.Figure 1
shows the the overall schematic of the system.

Figure1. Schematic of a close loop DC motor control system

COMPONENT LIST
Table 1.
S.No

List of required cmponent

Components

Quantity

Brushed DC Motor

01

Arduin UNO

01

L298 Dual H-Bridge .

01

Voltage Regulator

01

Optical Rotary Encoder (Quadrature)

01

Connecting Wires (Male to Male, Male to Female)

DCPower Source (24V , 5V )

01

APPENDIX A
PROGRAM CODE
/*
IBT-2 1 Motor Control Board driven by Arduino with no motor reverse function.

Speed controlled by user input via serial monitor.


PID Variables set initially in code but can be modified by user via serial monitor
during program run.

Connection to the IBT-2 controller:


IBT-2 pin 1 (RPWM) to Arduino pin 6(PWM)
IBT-2 pins 3 (R_EN), 7 (VCC) to Arduino 5V pin
IBT-2 pin 8 (GND) to Arduino GND
IBT-2 pins 2 (LPWM), 4 (L_EN), 5 (R_IS) and 6 (L_IS) not connected

Optical encoder board is FC-02 v2.0 twin encoder version and is connected to
Ardiuno pin 2 as only one encoder required
RPM read from optical encoder and use as feedback for PID calculation routine.
3

*/

int MotorPWM = 6; // ENABLE to digital pin 6


//int MotorIN_1 = 8;
//int MotorIN_2 = 12;
int encoder0PinA = 2; // Optical encoder attached to this pin

// temp working variables


volatile unsigned long lastTime;
volatile unsigned long duration, CapTime, LastCapTime;
volatile double errSum, lastErr, lastErr_2;
volatile double lastOutput;
volatile double dT;
volatile int count = 0;
double PV, Output;
double kp, ki, kd;
double ref;

//The setup function

void setup (){


pinMode(encoder0PinA, INPUT); // Optical encoder input
//pinMode(MotorIN_1, OUTPUT);
//pinMode(MotorIN_2, OUTPUT);
pinMode(MotorPWM, OUTPUT); // PWM value to motor
attachInterrupt(0, doEncoder, FALLING);
4

CapTime = 0;
LastCapTime = 0;

//Controller Parameter
kp = 1.00; ki = 0.00; kd = 0.00; // Only using process part of PID routine at
present
Output = 0;
Serial.begin (9600);
}
//Interrupt subroutine function

void doEncoder(){
LastCapTime = CapTime;
CapTime = millis();
}

void loop (){


unsigned long now;
double Freq;
now = millis();
dT = (double)(now - lastTime) / 1000; //Our Sampling time
if(dT>=0.01){ //Do control loop every 10ms
duration = CapTime - LastCapTime; //Get the period in ms
LastCapTime = CapTime;
if(duration==0){
Freq = 0;
}
5

else{
Freq = 1000/(double)duration; //in Hz unit
}
PV = Freq*60/8; // Rpm unit '8' used in formula as there are 4 interupts per
revolution on encoder disk
compute(ref, PV); // Find controller output
sendCommand(Output); // Send command to DC motor
lastTime = now;
}
//Receive Command
byte val;
if(Serial.available()){
val = Serial.read();
switch (val) {
case 'A': ref = 0; break;
case 'W': ref += 50; break;
case 'S': ref -= 50; break;
case 'O': kp+=0.01;
Serial.println(kp); break;
case 'L': kp-=0.01;
Serial.println(kp); break;
case 'I': ki+=0.01;
Serial.println(ki); break;
case 'K': ki-=0.01;
Serial.println(ki); break;
case 'U': kd+=0.001;
Serial.println(kd); break;
6

case 'J': kd-=0.001;


Serial.println(kd);
break;
}
}
// display setpoint and measured value
if(count>5000){
Serial.print(ref);
Serial.print(", ");
Serial.print(Freq);
Serial.print(", ");
Serial.print(dT);
Serial.print(", ");
Serial.print(duration);
Serial.print(", ");
Serial.print(PV);
Serial.print(", ");
Serial.print(Output);
Serial.println(", ");
Serial.print(now);
Serial.println(", ");
Serial.print(lastTime);
Serial.println(", ");

count = 0;
}
7

else{
count++;
}
}
//The "sendCommand" function
void sendCommand(int cmd){
if(cmd>0) {
analogWrite(MotorPWM, cmd);
//digitalWrite(MotorIN_1,LOW);
//digitalWrite(MotorIN_2,HIGH);
}
else if(cmd<0){
analogWrite(MotorPWM, -cmd);
//digitalWrite(MotorIN_1,HIGH);
//digitalWrite(MotorIN_2,LOW);
}
else{
analogWrite(MotorPWM, 0);
//digitalWrite(MotorIN_1,LOW);
//digitalWrite(MotorIN_2,LOW);
}
}

//The PID controller algorithm (velocity PID algorithm)


void compute(double Setpoint, double Measured)
{
8

double error = Setpoint - Measured;


/*Compute PID Output*/
Output = kp*(error - lastErr) + ki*error*dT + ( kd*(error - 2*lastErr + lastErr_2) /
dT )
+ lastOutput;
/*Max 255, Min -255*/
if(Output>255){
Output = 255;
}
else if(Output <-255){
Output = -255;
}
else{
}
/*Remember some variables for next time*/
lastOutput = Output;
lastErr_2 = lastErr;
lastErr = error;
}

You might also like