Control Speed Motor PID

13,534

48

11

About: just share what i have to make life funny see my page www.engineer2you.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

    • Fandom Contest

      Fandom Contest
    • Colors of the Rainbow Contest

      Colors of the Rainbow Contest
    • Frozen Treats Challenge

      Frozen Treats Challenge

    11 Discussions

    0
    None
    pvelazquez gomez

    2 months ago

    I'm trying to compile the arduino code but it says that "'stringComplete' was not declared in this scope"
    Can you upload the *.ino?

    0
    None
    JustinSTO

    1 year ago

    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
    0
    None
    AnnaMaiJustinSTO

    Reply 1 year ago

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

    0
    None
    JustinSTOAnnaMai

    Reply 1 year ago

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

    0
    None
    JustinSTOAnnaMai

    Reply 1 year ago

    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.

    0
    None
    AnnaMaiJustinSTO

    Reply 1 year ago

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

    0
    None
    JustinSTO

    1 year ago

    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
    0
    None
    AnnaMaiJustinSTO

    Reply 1 year ago

    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.

    0
    None
    Sanaaa

    1 year ago

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

    1 reply
    0
    None
    AnnaMaiSanaaa

    Reply 1 year ago

    It's here bro

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