Lab Manual for Position control of motor V2
Lab Manual for Position control of motor V2
Introduction
This document explains the experimental set up of DC motor position control and the execution
method. Fig.1 shows the block diagram of DC motor position control system.
L298 Motor
OUT 1 Motor +
OUT 2 Motor -
Fig2. L298 module
Pin Name Description
Motor DriverModule:
Motor driver is used to control motion of a motor and its direction by feeding current
accordingly. Output of a motor driver is in digital form so it uses PWM (Pulse Width
Modulation) to control speed of a motor. Motor Driver is basically current amplifiers followed
by input signals.
The L298N is a dual H-Bridge motor driver which allows speed and direction control of
two DC motors at the same time. The module can drive DC motors that have voltages between 5
and 35V, with a peak current up to 2A.
The L298N Motor Driver module consists of an L298 Motor Driver IC, 78M05 Voltage
Regulator, resistors, capacitor, Power LED, 5V jumper in an integrated circuit.
PID Controller
A closed-loop system like a PID controller includes a feedback control system. This system
evaluates the feedback variable using a fixed point to generate an error signal. Based on that,
it alters the system output. This procedure will continue till the error reaches Zero otherwise
the value of the feedback variable becomes equivalent to a fixed point.
Proportional tuning involves correcting a target proportional to the difference. Thus, the
target value is never achieved because as the difference approaches zero, so too does the
applied correction. Proportional or P- controller gives an output that is proportional to current
error e (t). It compares the desired or set point with the actual value or feedback process
value. The resulting error is multiplied with a proportional constant to get the output. If the
error value is zero, then this controller output is zero.
This controller requires biasing or manual reset when used alone. This is because it never
reaches the steady-state condition. It provides stable operation but always maintains the
steady-state error. The speed of the response is increased when the proportional constant Kc
increases.
Due to the limitation of p-controller where there always exists an offset between the
process variable and setpoint, I-controller is needed, which provides necessary action to
eliminate the steady-state error. It integrates the error over a period of time until the error
value reaches zero. It holds the value to the final control device at which error becomes zero.
PI controller
Integral control decreases its output when a negative error takes place. It limits the speed of
response and affects the stability of the system. The speed of the response is increased by
decreasing integral gain, Ki.
Fig.PI Controller Response
In the above figure, as the gain of the I-controller decreases, the steady-state error also goes
on decreasing. For most of the cases, the PI controller is used particularly where the high-
speed response is not required.
While using the PI controller, I-controller output is limited to somewhat range to overcome
the integral wind up conditions where the integral output goes on increasing even at zero
error state, due to nonlinearities in the plant.
D-Controller
I-controller doesn’t have the capability to predict the future behavior of error. So it reacts
normally once the setpoint is changed. D-controller overcomes this problem by anticipating
the future behavior of the error. Its output depends on the rate of change of error with respect
to time, multiplied by derivative constant. It gives the kick start for the output thereby
increasing system response.
Fig.PID controller
In the above figure response of D, the controller is more, compared to the PI controller, and
also settling time of output is decreased. It improves the stability of the system by
compensating for phase lag caused by I-controller. Increasing the derivative gain increases
the speed of response.
So finally we observed that by combining these three controllers, we can get the desired
response for the system. Different manufacturers design different PID algorithms.
Integral tuning attempts to remedy this by effectively cumulating the error result from the "P"
action to increase the correction factor. For example, if the oven remained below
temperature, “I” would act to increase the head delivered. However, rather than stop heating
when the target is reached, "I" attempts to drive the cumulative error to zero, resulting in an
overshoot.
Derivative tuning attempts to minimize this overshoot by slowing the correction factor
applied as the target is approached.
void setup() {
Serial.begin(9600);
pinMode (IN1, OUTPUT); //Configuring the Arduino pins as output
pinMode (IN2, OUTPUT);
pinMode (ENA, OUTPUT);
pinMode(encoderPin1, INPUT_PULLUP); //Enable internal pllup
pinMode(encoderPin2,INPUT_PULLUP); //Enable internal pllup
digitalWrite(encoderPin1, HIGH); //turn pullup resistor ON
digitalWrite(encoderPin2, HIGH);
attachInterrupt(0, updateEncoder, CHANGE); //interrupt pin number 2
attachInterrupt(1, updateEncoder, CHANGE); //interrupt pin number 3
digitalWrite(7,LOW);
Serial.println("CLEARDATA"); // clear excel sheet
Serial.println("LABEL,Time,Error, Angle, Num Rows"); // column headers
}
void loop() {
row_excel++; // row number + 1
Serial.print("DATA,TIME,"); // excel record current data and time
Serial.print(Error);
Serial.print(",");
Serial.print(Angle);
Serial.print(",");
Serial.println(row_excel);
// if rows are more than 500, then start filling the rows again
if (row_excel > 500){
row_excel = 500;
Serial.println("ROW,SET,2");}
if (Reversecount >500)
{
analogWrite(9,pwm1); //pwm pulse to conrol motor speed
digitalWrite(6,LOW); //motor rotate Forward direction
digitalWrite(7,LOW);
while(1);
}
if(frw == 1) //if set frw =1 means motor rotate Forward direction
{
analogWrite(9,pwm1); //pwm pulse to conrol motor speed
digitalWrite(6,LOW); //motor rotate Forward direction
digitalWrite(7,HIGH);
}
else if(frw == 2) //if set frw =1 means motor rotate Forward direction
{
analogWrite(9,pwm1); //pwm pulse to conrol motor speed
digitalWrite(6,HIGH); //motor rotate Forward direction
digitalWrite(7,LOW);
}
}
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue --;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue ++;
Use the following code for void setup() and write the code for void loop()
The encoder that is connected to the motor shaft has four terminals – VCC, GND, A, B
The motor terminals are M+(red) and M-(Black)
The pattern of the pulses may be used to determine the direction by taking two consecutive pairs
of ENCA and ENCB channel data. The logic levels are considered after every rising or falling
pulse. Taking consecutive pairs the four bit data can be written as follows: Start with rising edge
of ENC A as the first edge
1.For the first two edges in the order ENCA ENCB ENCA ENCB = 1110
2. For edges two and three ENCA ENCB ENCA ENCB = 1000
3. For edges three and four ENCA ENCB ENCA ENCB = 0001
4. For edges four and five ENCA ENCB ENCA ENCB = 0111
5. For edges five and six ENCA ENCB ENCA ENCB = 1110 – repeats the sequence
So if we detect that the encoder edges are in one of these four sequences, the encoder value may
be increased by 1 to show that the motor is running in forward direction. The code for that is
shown as:
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue ++;
Reverse Direction of Rotation (Encoder Waveforms)
The encoder pulses from A and B channels appear as in the above diagram for a typical direction
of motor rotation-reverse in this case). The pattern of the pulses may be used to determine the
direction by taking two consecutive pairs of ENCA and ENCB channel data. The logic levels are
considered after every rising or falling pulse. Taking consecutive pairs the four bit data can be
written as follows:
1.For the first two edges in the order ENCA ENCB ENCA ENCB = 1011
2. For edges two and three ENCA ENCB ENCA ENCB = 1101
3. For edges three and four ENCA ENCB ENCA ENCB = 0100
4. For edges four and five ENCA ENCB ENCA ENCB = 0010
5. For edges five and six ENCA ENCB ENCA ENCB = 1011 – repeats the sequence
So if we detect that the encoder edges are in one of these four sequences, the encoder value may
be reduced by 1 to show that the motor is running in reverse direction. The code for that is shown
as:
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue --;
Lab Programs for Students
1. Draw the schematic of the connections between the Arduino controller, motor driver board and
DC motor and the encoder feedback. Describe how the Arduino controller can be used to drive
the motor in FWD and REV direction.
2. Write the program for PI control of DC motor.
Plot the response of Angle vs Time for a target rotational position of 360 deg. Compute the
overshoot and steady state error for the DC motor position.
3. Write the program for Proportional control of DC motor with a gain Kp = 1/2 and the pwm
defined by pwm = Error *Kp . Plot the response of Angle vs Time and determine the Steady state
error.
4. Write the program for Proportional, Integral and Difference control of DC motor with Kp = 1/8,
Ki = 1/32 and Kd = 1/16. Plot the response of Angle vs Time and determine the Steady state
error.
5. Write the program for Fuzzy logic control of DC motor. Tune the PID parameters to get a
response with minimum overshoot and minimum steady state error. Plot the response of Angle
vs Time and determine the Steady state error.
To run the motor in forward direction, set pwm1 and provide as input to ENA for the
driver while IN1 = 0. IN1 =1 for the driver
void loop()
{
pwm1 = 80; //Sets initial torque to overcome static friction
analogWrite(9,pwm1); //pwm pulse to conrol motor speed
digitalWrite(6,LOW); //motor rotate Forward direction
digitalWrite(7,HIGH);
delay(3000); // 3 seconds run the motor
// To turn off the motor set both IN1 = 0 and IN2 =0 by the following code
analogWrite(9,pwm1); //pwm pulse to control motor speed
digitalWrite(6,LOW); //Turn off motor and stay in continuous loop
digitalWrite(7,LOW);
while(1);
}
Code for Reverse Direction Rotation
Write a program to run the motor in reverse direction for three seconds and then turn off the
motor.
void loop()
{
pwm1 = 80; //Sets initial torque to overcome static friction
analogWrite(9,pwm1); //pwm pulse to conrol motor speed
digitalWrite(6,HIGH); //motor rotate reverse direction
digitalWrite(7,LOW);
delay(3000); // 3 seconds run the motor
//To turn off the motor set both IN1 = 0 and IN2 =0 by the following code
analogWrite(9,pwm1); //pwm pulse to control motor speed
digitalWrite(6,LOW); //Turn off motor and stay in continuous loop
digitalWrite(7,LOW);
while(1); //Stay here in continuous loop
}
Weblink: https://www.parallax.com/package/plx-daq/
Ste
p 2: After downloading, we can find a PLX-DAQ-All.zip file in the download folder.
Step3: Extract the files and click plx_daq_install.exe file for installation
After the installation is over we can find the folder named PLX-DAQ in the desktop.
In the PLX-DAQ folder, there is an excel file, PLX-DAQ spread sheet. Open that
spread sheet you can find the excel file shown below.
Make sure the baud rate in the Data acquisition menu is same as the one set
in the coding.
After executing the program loaded in the Arduino, go to excel spread sheet
and press connect tab on the Data acquisition menu
Once the data have been displayed, select the Angle and Error columns to
plot the graph
X-axis can be set to display time scale by the following steps:
-keep the cursor on the plot area
-right click in the plot area and choose the “Select data”
-go to horizontal axis label-press the edit button and select the time column
in the excel spread sheet
PID with Fuzzy control
Annexure 2
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue --;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue ++;