0% found this document useful (0 votes)
2 views

Lab Manual for Position control of motor V2

This document serves as a lab manual for an experiment on position control of a DC motor using an Arduino UNO as a PID controller. It details the hardware setup, including connections between the Arduino, motor driver, and encoder, as well as the functioning of the PID control system. The manual also includes programming objectives and code examples for controlling the motor's position through PWM signals based on encoder feedback.

Uploaded by

2024ht65673
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Lab Manual for Position control of motor V2

This document serves as a lab manual for an experiment on position control of a DC motor using an Arduino UNO as a PID controller. It details the hardware setup, including connections between the Arduino, motor driver, and encoder, as well as the functioning of the PID control system. The manual also includes programming objectives and code examples for controlling the motor's position through PWM signals based on encoder feedback.

Uploaded by

2024ht65673
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 30

Birla Institute of Technology & Science, Pilani

Work Integrated Learning Programmes Division


M.Tech. Design Engineering
LAB MANUAL –Advanced Control Systems
Title: POSITION CONTROL OF DC MOTOR

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.

Fig.1 Block diagram of DC motor position control system


In fig.1 Arduino UNO act as a PID controller. A DC motor is connected to PID controller
through motor driver. The rotation of the motor is sensed by an encoder. The error signal is
generated by comparing the input, target position r(n) with the encoder value y(n). In
accordance with the error signal the PWM signal is generated by the PID controller using the Kp,
Ki and Kd values. The motor will try to align to a new position according to the PWM signal.
The motor keeps on changes its position until it attains the target position.
The connectivity of Arduino UNO with LM298 (driver circuit) and DC motor with encoder in
Fig.2
Fig. 2 Connectivity between Arduino UNO with L298 and DC motor with Encoder
Hardware Connectivity
The following modules are shown connected in Fig.1. We have Arduino UNO and L298 shown
are connected with motor encoder.

Arduino UNO connection with L298:

Arduino UNO L298


9 ENA
7 IN1
6 IN2

Arduino UNO connection with EncoderMotor:

Arduino UNO Encoder Motor


2 Channel A
3 Channel B

L298 connection with Motor:

L298 Motor
OUT 1 Motor +
OUT 2 Motor -
Fig2. L298 module
Pin Name Description

IN1 & IN2 Motor A input pins. Used to control the


spinning direction of Motor A

IN3 & IN4 Motor B input pins. Used to control the


spinning direction of Motor B

ENA Enables PWM signal for Motor A

ENB Enables PWM signal for Motor B

OUT1 & Output pins for Motor A


OUT2

OUT3 & Output pins of Motor B (Not Used)


OUT4

12V 12V input from DC power Source

5V Supplies power for the switching logic


circuitry inside L298N IC

GND Ground pin

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.

Fig.PID Controller 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.

PID Controller Interfacing


The design and interfacing of the PID controller can be done using the Arduino
microcontroller. In the laboratory, the Arduino based PID controller is designed using the
Arduino UNO board, electronic components, thermoelectric cooler, whereas the software
programming languages used in this system are C or C++. This system is used to control the
temperature within the laboratory.
PWM =(Kp*Error)+(Ki*Sumerror)+(Kd*Derivative of Error)
Where,
Error = Set_Point - Measured_value
Sumerror=Sumerror+(Error*dT)
Derivative = (Error – Previous_Error)/dT

Program Objective- Position Control of DC Motor


1) Set the target encoder pulses required for the motor to move starting from origin. In one
rotation the number of edges of encoder pulses is 70 x 4 = 280
2) Initialize the PWM with a default Duty cycle so that the motor can overcome the starting
friction. The PWM signal will be connected to ENA channel of the motor driver.
3) As the motor starts rotation, the encoder pulses in Channels A and B will start generating
square wave pulses that need to be measured by the controller board.
4) When motor rotates beyond the target position, direction of the motor is reversed and
approached zero error position.
5) The motor is made to go forward and reverse until the zero error position is achieved.
6) Once the rotor oscillates about the zero error position, the motor input is turned off
completing the position control experiment.

Code for position control of motor:


const int IN1 = 7; //Defining the pins of Arduino kit and mapping them to motor driver
const int IN2 = 6;
const int ENA = 9;
int encoderPin1 =2;
int encoderPin2 =3;
volatile int lastEncoded =0;
volatile int encoderValue =0;
float encoderpr;
volatile int Error =0 ;
volatile int DError =5;
volatile int pwm1 =150;
long lastencoderValue =0;
//int lastMSB =0;
//int lastLSB =0;
int rotation=280,Errorcopy,sumerror,differ;
int frw=1;
int Reversecount;
float Angle;
int row_excel=0;
void forward();
void reverse();

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 ++;

lastEncoded = encoded; //store this value for next time


if(rotation >encoderValue) {frw =1; Error = rotation - encoderValue;}
else {frw =2; Error = encoderValue -rotation;Reversecount++;}
Errorcopy=Error;
DError=Error-Errorcopy;
encoderpr=encoderValue;
Angle=(encoderpr*360)/280;//Angle1/360;
pwm1 = (Error/8) + (sumerror/32)+80;
sumerror = sumerror +Error;
if(sumerror>500) sumerror = 0; //reset integral error with max limit
if (Error <1) {frw =2;}
}
Hardware Connections using Arduino Uno board

Use the following code for void setup() and write the code for void loop()

DC Motor and Rotary Encoder

Brand: Cytron Motor + Encoder Specifications IG420014X00044R


 Voltage: 12VDC
 Rated Torque: 2.24 kg.cm (0.22 N.m)
 Rated Speed: 1400 RPM
 Rated Current: 5500mA
 Rated Power output: 41.3W
 Gear ratio: 4:1
 Encoder Output: 70 PPR
Motor and Encoder connection:
 Black wire to Motor Gnd – (Motor)
 Red wire to Motor Vcc+ (Motor)
 Brown wire to Sensor Vcc+ (Encoder)
 Green wire to Sensor Vcc- (Encoder)
 Blue wire to Channel A (Encoder)
 Purple wire to Channel B (Encoder)

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)

Forward Direction of Rotation (Encoder Waveforms)


Channel A and Channel B encoder pulses are shown for forward direction here. In every edge of
the interrupt subroutine, the logic level of ENCA and ENCB are recorded. Using bit shift
operation and adding the logic levels for the next edge, the four bit values of ENCA ENCB
ENCA ENCB are determined and moved into a variable called sum.

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.

Code for Forward Direction Rotation

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
}

Proportional Gain Controller


Write a program to run the motor in forward direction with only proportional gain
Using Kp = 1/8 the equation for pwm
Use pwm1 = (Error/8) +80 in the original program.
The initial PWM of 80 is chosen to overcome the frictional torque during start
Proportional Integral Derivative Gain Controller
Write a program to run the motor in forward direction with PID control.
Calculate (Error –PreviousError) * Kd and use in the PWM equation.
At the end of the loop we can save PreviousError = Error. Next time the loop executes
DifferenceError = Error – PreviousError may be calculated.
pwm1 = (Error/8) + (sumerror/32)+DifferenceError/32+ 80;
The gains for Kp, Ki and Kd shown here are 1/8, 1/32 and 1/32 respectively.
Gains may be changed and the results observed
Annexure 1

Step 1: Download PLX-DAQ tool from web

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.

Now enable the Enable content tab as shown below:


If you find the below menu in the excel spread sheet, click enable and click ok
 Procedure for transferring data from Arduino Uno board to Excel
spread sheet:
 Upload the code to the Arduino and don’t disconnect it.
 Now begin the data logging process using the data acquisition tool in the
excel spread sheet.
 Check the com port in Data acquisition menu is matched with the com port
used for Arduino Uno

 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

Fuzzy Logic Control

A fuzzy control system is a control system based on fuzzy logic—a


mathematical system that analyzes analog input values in terms of logical
variables that take on continuous values between 0 and 1, in contrast to
classical or digital logic, which operates on discrete values of either 1 or 0.
Fuzzy Sets
The input variables in a fuzzy control system are in general mapped by
sets of membership functions similar to this, known as "fuzzy sets". The
process of converting a crisp input value to a fuzzy value is called
"fuzzification". The fuzzy logic based approach had been considered by
designing two fuzzy systems, one for error heading angle and the other for
velocity control
A control system may also have various types of switch, or "ON-OFF", inputs
along with its analog inputs, and such switch inputs of course will always
have a truth value equal to either 1 or 0, but the scheme can deal with them
as simplified fuzzy functions that happen to be either one value or another.
Fuzzy controller:
Fuzzy controllers are very simple conceptually. They consist of an input
stage, a processing stage, and an output stage. The input stage maps sensor
or other inputs, such as switches, thumbwheels, and so on, to the appropriate
membership functions and truth values. The processing stage invokes each
appropriate rule and generates a result for each, then combines the results of
the rules. Finally, the output stage converts the combined result back into a
specific control output value.
The most common shape of membership functions is triangular,
although trapezoidal and bell curves are also used, but the shape is generally
less important than the number of curves and their placement. From three to
seven curves are generally appropriate to cover the required range of an
input value, or the "universe of discourse" in fuzzy jargon.
The processing stage is based on a collection of logic rules in the form
of IF-THEN statements, where the IF part is called the "antecedent" and the
THEN part is called the "consequent". Typical fuzzy control systems have
dozens of rules.
Consider a rule for a thermostat:
IF (temperature is "cold") THEN turn (heater is "high")
This rule uses the truth value of the "temperature" input, which is
some truth value of "cold", to generate a result in the fuzzy set for the
"heater" output, which is some value of "high". This result is used with the
results of other rules to finally generate the crisp composite output.
Obviously, the greater the truth value of "cold", the higher the truth value of
"high", though this does not necessarily mean that the output itself will be set
to "high" since this is only one rule among many. In some cases, the
membership functions can be modified by "hedges" that are equivalent to
adverbs. Common hedges include "about", "near", "close to",
"approximately", "very", "slightly", "too", "extremely", and "somewhat".
These operations may have precise definitions, though the definitions can
vary considerably between different implementations. "Very", for one
example, squares membership functions; since the membership values are
always less than 1, this narrows the membership function. "Extremely" cubes
the values to give greater narrowing, while "somewhat" broadens the
function by taking the square root.
In practice, the fuzzy rule sets usually have several antecedents that are
combined using fuzzy operators, such as AND, OR, and NOT, though again
the definitions tend to vary: AND, in one popular definition, simply uses the
minimum weight of all the antecedents, while OR uses the maximum value.
There is also a NOT operator that subtracts a membership function from 1 to
give the "complementary" function.
There are several ways to define the result of a rule, but one of the
most common and simplest is the "max-min" inference method, in which the
output membership function is given the truth value generated by the
premise.
Rules can be solved in parallel in hardware, or sequentially in software. The
results of all the rules that have fired are "defuzzified" to a crisp value by one
of several methods. There are dozens, in theory, each with various
advantages or drawbacks.
The "centroid" method is very popular, in which the "center of mass" of the
result provides the crisp value. Another approach is the "height" method,
which takes the value of the biggest contributor. The centroid method favors
the rule with the output of greatest area, while the height method obviously
favors the rule with the greatest output value.
The diagram below demonstrates max-min inferencing and centroid
defuzzification for a system with input variables "x", "y", and "z" and an
output variable "n". Note that "mu" is standard fuzzy-logic nomenclature for
"truth value":
Notice how each rule provides a result as a truth value of a particular membership function
for the output variable. In centroid defuzzification the values are OR'd, that is, the maximum
value is used and values are not added, and the results are then combined using a centroid
calculation
Fuzzy control system design is based on empirical methods, basically a methodical
approach to trial-and-error. The general process is as follows:

 Document the system's operational specifications and inputs and outputs.


 Document the fuzzy sets for the inputs.
 Document the rule set.
 Determine the defuzzification method.
 Run through test suite to validate system, adjust details as required.
 Complete document and release to production.
Coding for Fuzzy based PID controller:
const int IN1 = 7; //Defining the pins of Arduino kit and mapping them to motor driver
const int IN2 = 6;
int Array[20];
//int count=0;
int p=0;
const int ENA = 9;
int Kp,Ki;
int encoderPin1 =2;
int encoderPin2 =3;
volatile int lastEncoded =0;
volatile int encoderValue =0;
volatile int Error =0 ;
volatile float DError =5 ;
//volatile int positiveError=0;
//volatile int negativeError=0;
volatile int pwm1 =150;
//volatile int pwmcopy =0;
long lastencoderValue =0;
int lastMSB =0;
int lastLSB =0;
int rotation=280,Errorcopy=0,sumerror,differ;
int frw=1;
int Reversecount;
float encoderpr;
//int sen = 150;
float Angle;
int row_excel = 0; // number of lines
void forward();
void reverse();
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,DError, 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(DError);
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 ++;

lastEncoded = encoded; //store this value for next time


Array[p++]=lastEncoded;
if(rotation >encoderValue) {frw =1; Error = rotation - encoderValue;}
else {frw =2; Error = encoderValue -rotation;Reversecount++;}
encoderpr=encoderValue;
DError=Error-Errorcopy;
Errorcopy=Error;
Angle=(encoderpr*360)/280;
if(Error>100){ Kp=8;Ki=32;} //Fuzzification and Defuzzification
else if(Error>80) {Kp=9; Ki=35;}
else if(Error>60){Kp=10; Ki=36;}
else if(Error>40) {Kp=11; Ki=32;}
else if(Error>20) {Kp=12; Ki=32;}
else {Kp=16; Ki=64;}
pwm1 = (Error/Kp) + (sumerror/Ki)+55;
sumerror = sumerror +Error;
if(sumerror>500) sumerror = 0; //reser integral error with max limit
if (Error <1) {frw =2;}
}

You might also like