Control Speed Motor PID

6,124

47

10

Published

Introduction: Control Speed Motor PID

About: just share what i have to make life funny engineer2you.blogspot.com

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

Share

    Recommendations

    • Oil Contest

      Oil Contest
    • Clocks Contest

      Clocks Contest
    • Planter Challenge

      Planter Challenge
    user

    We have a be nice policy.
    Please be positive and constructive.

    Tips

    Questions

    10 Comments

    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.

    5 replies

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

    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. )?

    I'm not sure. Let's try

    Thank you for the help! Also I believe I figured out my issue, I am using a Sparkfun Promicro 5V arduino. And I think the amount of data flowing through it is overloading it, because i keep getting a sub-string error that says the length of the string is overloaded, and when using an arduino uno I don't get this issue.

    You can use any type DC motor which has encoder! then find PID factor for it.

    Another question, is there a step somewhere that will allow me to change the PORT selection without having to use PORT4 every time?

    1 reply

    You need to add one more function to change port name for COM port

    I think it should has exception error to prevent program error if port name is wrong. Let's try yourself first.

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

    1 reply

    It's here bro

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