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


motor_start = true;


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


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


//print out speed

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


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;



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



if (pwm_pulse>255){








Step 2: Work at Visual Studio C++

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

Step 3: RUN It

Run it with speed as you wish

See more instruction at our blog:


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.

AnnaMai (author)JustinSTO2017-08-03

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

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

Sanaaa (author)2017-07-18

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

AnnaMai (author)Sanaaa2017-07-21

It's here bro

About This Instructable




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