Control Speed Motor PID

by AnnaMai in Circuits > Arduino

25997 Views, 56 Favorites, 0 Comments

Control Speed Motor PID

Arduino motor PID speed control

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

Part list to purchase:

1. Motor with encoder: https://amzn.to/2NwsNxH

2. H-bridge: https://amzn.to/2QS2FeI

3. Arduino Pro Mini: https://amzn.to/2QS2FeI

2.PNG

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

}

}

}

Work at Visual Studio C++

3.PNG

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

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

RUN It

1.png

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