Introduction: Control Speed Motor PID

This is briefly instruction to control motor speed using PID algorithm. Also in this project, motor speed will be print out at computer screen

Step 1:

Connect motor to Arduino through H-bridge

Program Arduino as:

void loop() {
if (stringComplete) {

// clear the string when COM receiving is completed

mySt = ""; //note: in code below, mySt will not become blank, mySt is blank until '\n' is received

stringComplete = false;

}

//receive command from Visual Studio

if (mySt.substring(0,8) == "vs_start"){

digitalWrite(pin_fwd,1); //run motor run forward

digitalWrite(pin_bwd,0);

motor_start = true;

}

if (mySt.substring(0,7) == "vs_stop"){

digitalWrite(pin_fwd,0);

digitalWrite(pin_bwd,0); //stop motor

motor_start = false;

}

if (mySt.substring(0,12) == "vs_set_speed"){

set_speed = mySt.substring(12,mySt.length()).toFloat(); //get string after set_speed

}

if (mySt.substring(0,5) == "vs_kp"){

kp = mySt.substring(5,mySt.length()).toFloat(); //get string after vs_kp

}

if (mySt.substring(0,5) == "vs_ki"){

ki = mySt.substring(5,mySt.length()).toFloat(); //get string after vs_ki

}

if (mySt.substring(0,5) == "vs_kd"){

kd = mySt.substring(5,mySt.length()).toFloat(); //get string after vs_kd

}

}

void detect_a() {

encoder+=1; //increasing encoder at new pulse

m_direction = digitalRead(pin_b); //read direction of motor

}

ISR(TIMER1_OVF_vect) // interrupt service routine - tick every 0.1sec

{

TCNT1 = timer1_counter; // set timer

pv_speed = 60.0*(encoder/200.0)/0.1; //calculate motor speed, unit is rpm

encoder=0;

//print out speed

if (Serial.available() <= 0) {

Serial.print("speed");

Serial.println(pv_speed); //Print speed (rpm) value to Visual Studio

}

//PID program

if (motor_start){

e_speed = set_speed - pv_speed;

pwm_pulse = e_speed*kp + e_speed_sum*ki + (e_speed - e_speed_pre)*kd;

e_speed_pre = e_speed; //save last (previous) error

e_speed_sum += e_speed; //sum of error

if (e_speed_sum >4000) e_speed_sum = 4000;

if (e_speed_sum <-4000) e_speed_sum = -4000;

}

else{

e_speed = 0;

e_speed_pre = 0;

e_speed_sum = 0;

pwm_pulse = 0;

}

//update new speed

if (pwm_pulse <255 & pwm_pulse >0){

analogWrite(pin_pwm,pwm_pulse); //set motor speed

}

else{

if (pwm_pulse>255){

analogWrite(pin_pwm,255);

}

else{

analogWrite(pin_pwm,0);

}

}

}

Step 2: Work at Visual Studio C++

Coding in Visual Studio C++ is quite long, see code at this link

https://drive.google.com/file/d/0B1UeJfx4pZ1GV1YzN1k0aElPb2c/view?usp=sharing

Step 3: RUN It

Run it with speed as you wish

See more instruction at our blog: http://engineer2you.blogspot.com/2016/12/arduino-motor-pid-speed-control.html

Comments

author
JustinSTO (author)2017-08-02

Is there an equivalent motor that can be used for this system, it is very difficult to find the DSE38BE27-001 AX060121 DC motor with encode.

author
AnnaMai (author)JustinSTO2017-08-03

you can use any dc motor which has encoder, then find factor kP kI kD for it.

author
JustinSTO (author)AnnaMai2017-08-04

Thank you so much for the answer, there is one more concern I have. I will be using a motor that has an encoder with 211.2 counts per revolution, can this code in C++ be able to handle the amount of data that will be flowing through it at 2000 RPM (ie. there will be over 1 million points of data a minnute or 10,000 points a second. )?

author
Sanaaa (author)2017-07-18

Would you please give the precise specs for the motor and the link for it

author
AnnaMai (author)Sanaaa2017-07-21

It's here bro

http://www.dhgate.com/product/1pcs-used-good-japanese-dc-motor-with-encoder/206203142.html

About This Instructable

2,817views

43favorites

License:

Bio: just share what i have to make life funny engineer2you.blogspot.com
More by AnnaMai:Esp8266 Esp12e WebserverControl Speed Motor PIDRaspberry Remote Car
Add instructable to: