Professional Documents
Culture Documents
Title:
1. Conceptual Design
The project consist in a DC motor controlled by an Arduino having an encoder as feedback. Taking the
derivative of the encoder signal it is possible to get the velocity and then compare to the input (desired velocity)
getting an error and correcting this error through a PID controller in the Arduino. The velocity control was then
applied to an electronic pulley to lift different masses with constant velocity.
The Block Diagram is showed below:
Fall 2014
2. Detailed Design
The picture bellow represent the project which data came from:
The desired project consist on a simulation of a motorized pulley, which in this case carry a load of 85 grams. The
programming code is attached on Appendix. The sensor utilized is an encoder attached on the motor that send pulses
Fall 2014
to Arduino that controls the motor velocity and direction.
The description of each wire in the wire diagram showed on Figure 2 is:
Table 1 - Wire Diagram description.
Wire
1
2
3
4
5
6
7
8
9
10
Function
Motor Power Supply
Motor Ground
Encoder Power Supply
Encoder Ground
Set of Pulse Output Line
Set of Pulse Output Line
Power Supply 5V(not used)
Ground
Pulse 1
Pulse 2
Fall 2014
a)
Only P.
Only P=0.09
Velocity (rad/s)
10.00
8.00
6.00
4.00
2.00
0.00
0
7.00
8.00
9.00
Time (s)
Output
Desired Velocity
= 0.775
b) Only PD
For a Kp=0.15 and Kd=0.003 the graphic Velocity x Time found was:
P=0.15 D=0.003
Velocity (rad/s)
10.00
8.00
6.00
4.00
2.00
0.00
0.00
1.00
2.00
3.00
4.00
5.00
6.00
Time (s)
Output
Desired Velocity
= 0.375
Fall 2014
c) Only PI
For a Kp=0.15 and Ki=0.003 the graphic Velocity x Time found was:
P=0.1 I=0.003
12.00
Velocity (rad/s)
10.00
8.00
6.00
4.00
2.00
0.00
0.00
1.00
2.00
3.00
4.00
5.00
6.00
7.00
8.00
9.00
7.00
8.00
9.00
Time (s)
Output
Desired Velocity
= 0.275
Velocity (rad/s)
10.00
8.00
6.00
4.00
2.00
0.00
0.00
1.00
2.00
3.00
4.00
5.00
6.00
Time (s)
Output
Desired Velocity
= 0.365
Fall 2014
4. MATLAB simulation
Gabriel: PD simulation:
Theory:
Analyzing the plots of the topic number 3 the system is very likely to be a 1 st order system. Based on the theory we
have a Transfer Function of a first order system being:
+ 1
A step input of 8.37 rad/s was applied and the S.S. output is 8.37(average)
= 0.375
() =
0.375 + 1
lim () = ()
0
8.37
= lim
=1
0.375 + 1
() =
() =
1
0.375 + 1
Matlab code:
G=tf(1,[0.375 1]);
opt=stepDataOptions('StepAmplitude',8.37);
[v,t]=step(G,opt);
plot(t,v,'-','LineWidth',2);grid on; title('PD controller');
ylabel('velocity[rad/s]');xlabel('time[s]');hold all
%importing experimental data to matlab using the import data button
%variables time and vel are the experimental data vectors
plot(time,vel,'r--o');legend('input','output'); xlim([0 3.5])
Plot Result:
Fall 2014
+ 1
A step input of 8.37 rad/s was applied and the S.S. output is 8.37(average)
() =
= 0.365
() =
0.365 + 1
To find D.C gain (A), apply the final value theory:
lim () = ()
0
8.37
= lim
=1
0.365 + 1
Therefore:
() =
1
0.365+1
Matlab code:
G1=tf(1,[0.365 1])
opt=stepDataOptions('StepAmplitude',8.37)
[v,t]=step(G1,opt);
plot(t,v,'-','LineWidth',2);grid on; title('PID controller');
ylabel('velocity[rad/s]');xlabel('time[s]');hold all
%importing experimental data to matlab using the import data button
%variables time and vel are the experimental data vectors
plot(time,vel,'r--o');legend('input','output'); xlim([0 3.5])
Plot Result:
Fall 2014
5. Conclusion
Abdon: PID control have so many applications. PI controllers are preferred to control first order plants. On the other
hand, PID control is vastly used to control two or higher order plants. In almost all cases fast transient response and
zero steady state error is desired for a closed loop system. PID is preferred is that it provides both of these features at
the same time. This project also showed that project is harder than you can think, project and design cost time and
money and cannot be made with no planning.
Gabriel: This project showed to me how powerful a PID control can be. Despites its simplicity compared to another
control types, it proved itself very effective. I learned that is very important to tune the gains of the system as best as
possible because it makes a huge difference. While P takes account on how fast the system respond, D is sensitive to
how big the error is changing (making the system stabilize faster) and I make sure that the error that is stacking (not
being corrected) will be fixed. I also have learned that when building a 100% handmade structure or mechanism to a
is very important to be careful when taking measurements and building the parts of the mechanism because when we
mount it, all the little mistakes made during the process will stack and the final equipment will not be as good as
desired.
Fall 2014
Appendix.
#include <Wire.h> //I2C protocol library
#define driver
0x0f // driver adress
#define DirectionSet
0xaa //direction header
#define Nothing
0x01// bit filler
#define MotorSpeedSet
0x82 //speed header
#define encoder0PinA 2
#define encoder0PinB 4
volatile long encoder0Pos=0;
long newposition;
long oldposition = 0;
unsigned long newtime;
unsigned long oldtime = 0;
long vel;
int error=0;
int sumerror=0;
int last_error=0;
float Kp=0.1;
float Kd=0.01;
float ki=0.001;
float PID;
int velo;
int spd=25;
void MotorSpeedSetA (unsigned char speedA){
Wire.beginTransmission(driver);
Wire.write(MotorSpeedSet);
Wire.write(0);
Wire.write(speedA);
Wire.endTransmission();
}
void MotorDirectionSet(byte dir)
{
Wire.beginTransmission(driver);
Wire.write(DirectionSet);
Fall 2014
Wire.write(dir);
Wire.endTransmission();
}
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
delayMicroseconds(10000); //wait for motor driver to initialization
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH);
// turn on pullup resistor
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH);
// turn on pullup resistor
attachInterrupt(0, doEncoder, RISING); // encoDER ON PIN 2
Serial.begin (9600);
Serial.println("start");
// a personal quirk
}
void loop() {
MotorSpeedSetA(spd);
delay(10); //this delay needed
MotorDirectionSet(0b1000); //0b1010 Rotating in the positive direction
// delay(10000);
newposition = encoder0Pos;
newtime = millis();
vel = (newposition-oldposition) * 1000 /(newtime-oldtime);
velo=(vel*60/6280); //RPM
//Serial.print ("speed = ");
Serial.println (velo);
Serial.println (newtime);
oldposition = newposition;
oldtime = newtime;
error=80-velo;
sumerror=sumerror+error;
PID=+(Kp*error)+ (Kd * (error - last_error)) + ki*sumerror;
last_error=error;
spd=spd+int(PID);
delay(200);
}
void doEncoder()
{
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
encoder0Pos++;
} else {
encoder0Pos--;
}
}