Arduino - Motor PID speed control


In this instruction, I will show how to control motor speed with PID algorithm, by Arduino UNO
With PID control, speed of motor can be archived exactly. This instruction mainly introduces about making program in Arduino UNO, and program in Computer (Visual Studio) to control motor speed by PID algorithm
Arduino UNO is used to store program motor control, PID algorithm, communicating with computer through COM Port Computer will have HMI made by Visual Studio to communicate with Arduino. HMI will show motor speed graph, change motor speed setting, and PID gain
Let's go in detail


Step 1: Hardware and Software needed
To make this project, you will need following hardware:

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

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


4. Motor base http://bit.ly/2DZJOZV


The motor with encoder, you can choose any DC motor but you need to know how many pulse of encoder per revolution. In case you don't know, you can make simple program with Arduino, then rotate motor shaft to know how many pulse of encoder per revolution. In my case, it is 200 pulses per revolution.

About software, you will need Arduino IDE to program Arduino UNO, and Visual Studio to make HMI on computer In my case, I use Visual Studio 2008, you can use newest version if you can




Step 2: Hardware connection

Make circuit like this diagram, it's easy for us: encoder from motor will connect to pin 2 and 3; H-bridge is used to control motor speed, then pin 4, 5 and 6 will connect to H-bridge. And, output of H-bridge is connected to motor

Then install the circuit to motor base like picture



Step 3: Arduino Code
Arduino code will do:
(1) Calculate motor speed
(2) Send motor speed to Computer
(3) Calculate PWM pulse (base on PID algorithm)
(4) Push result of PWM to H-brigde
The entire of code for Arduino UNO can be download at http://bit.ly/2P7CQbC



Step 4. Code works at Computer
Visual Studio 2008 is used to make HMI program, in which:
(1) Send speed setting to Arduino
(2) Send PID gain to Arduino
(3) Receive motor speed, show on graph

Note that, communication between Arduino and Visual Studio by COM communication
The code can be download at http://bit.ly/2PqlYvQ


Watch video to see how it works

71 comments:

  1. Replies
    1. so we just didn't need the UART PCB and we don't need to edit arduino code even when using arduino uno?

      sorry to bother you but i really need a fast answer

      Delete
    2. Right, Arduino UNO already had UART PCB inside. When Arduino UNO connect to Computer via USB Port, an COM Port will be shown -> use this COM Port No. to communicate between Arduino UNO and Computer.
      About the code, i try to compile for UNO, it run perfectly. Let's try it!

      Delete
    3. Can you give me scematick arduino-motor?

      Delete
    4. Hi, schematic is from this post https://www.engineer2you.com/2016/12/arduino-motor-speed-control-pwm.html

      Delete
  2. How can i try to input the value of speed, kp, ki, kd by using serial monitor in arduino program?

    thank you
    Fungkyking01@gmail.com

    ReplyDelete
    Replies
    1. Hi. Unfortunately i already removed this model (motor, circuit,...) -> can't make project again as your mention.
      You should find an example to read data input from serial port -> then, import parameters (kP, kI, kD) to formular. It's not difficult, let's do it

      Delete
  3. Bro Can you kindly Provide the whole circuit diagram. its quite confusing which connection goes where. thnx in advance

    ReplyDelete
  4. Please come to thí link to see connection
    http://engineer2you.blogspot.com/2016/12/arduino-motor-speed-control-pwm.html?m=1

    ReplyDelete
  5. Bro I followed all the steps you mentioned and made the project with Arduino Uno. The problem I get is that the PID is not working, the motor keeps on rotating with a constant speed of 530 RPM and when I apply some load to the motor the speed reduces and does not go back to 538 RPM. Also I can't send commands to arduino. like i want the motor to rotate with a speed for 700 RPM and 300 RPM for example, it does not work when i press the send button on HMI.

    ReplyDelete
    Replies
    1. Hi,
      (1) First step is make sure you can send command (and convert it to integer) into Arduino. You can search on web this kind of project, or see here http://engineer2you.blogspot.com/2016/12/arduino-uart-communication.html
      (2) Tuning PID parameter is not easy. Each motor will have each parameter. First tuning, you should make kP, kI some small value, kD=0, then see motor reaction. Then gradually increase or decrease kP, kI. Normally, no need kD.

      Delete
  6. Is there an equivalent motor that can be used with this system, it is very difficult to find the one you used.

    ReplyDelete
    Replies
    1. You can use any DC motor, then find kP kI kD for it

      Delete
  7. Hi this is one s brilliant!! I'm want to design kind of this but slightly different..
    There is LCD or 7 segment using the rotary encoder rpm 0-8000 per 1 rpm changes, first we need to a rpm then once after pressing start arduino need to rpm of the motor
    Can you suggest me any enocder motor up to 8000rpm n how to control the motor?
    Help me pls

    ReplyDelete
    Replies
    1. Hi, There's rearly motor with encoder 8000 ppr (pulse per round). If you need 8000ppr encoder, you have to use external encoder, connect to motor shaft by coupling. I was wondering if what application you need 8000ppr encoder? Could you share? We will make it together (because i'm free now haha)

      Delete
  8. I want to draw Set Speed in chart with series 2 is color Red, Can you help me

    ReplyDelete
    Replies
    1. Please try yourself in Visual Studio. I think it's not difficult.

      Delete
    2. Set Speed in Textbox I run Series2 but i don't know convert Text

      Delete
    3. /this->chart1->Series["Series2"]->Points->AddXY(i,System::Convert::ToDouble(textBox1)); i++;
      // this->chart1->ChartAreas["ChartArea1"]->AxisX->Minimum=i;

      Delete
    4. Thank you: i did convert textbox1->text ok

      Delete
  9. Can you please guide me about the specifications of motor with encoder? And also where to buy it from in INDIA?

    ReplyDelete
    Replies
    1. Hi, you can buy any DC motor which has encoder inside.

      Delete
  10. Hey , can you explain to me how to convert speed RPM to PWM ?

    ReplyDelete
    Replies
    1. Hi, i don't know calculation to convert speed rpm to PWM. This calculation is difficult, depends on characteristic of motor, load.
      Instead of calculation speed to PWM, we use PID algorithm. How it works?
      Let's think, PWM=0% -> speed is 0rpm; PWM=100% -> speed is max, let's say 2000rpm
      PID will calculate PWM depend on error of speed feedback and speed setting -> output to PWM pulse to reach setting speed.
      Hope i can help you.

      Delete
  11. Hi
    thanks for sharing this brilliant works . I have couples of question , first what version of visual studio you use and if I have motor with 2 wires only and it's gear motor , do u think that i still need encoder cuz I want to control the speed by using ur way in where if I need 450 rpm and the motor should rotate the desired speed , Do u think my motor able to do , here is my motor characters https://www.alibaba.com/product-detail/VTV-24v-dc-motor-1500-rpm_60645604396.html?spm=a2700.7724838.2017115.195.2bc1680aS46x0Z
    thank you so much

    ReplyDelete
    Replies
    1. Hi,
      I use Arduino 1.6.11, but you can use latest version -> it's no problem
      Your suggested motor has no encoder -> impossible to control speed. Without encoder, how could we know speed? You should choose another motor with encoder.
      Thanks for visit my blog.

      Delete
  12. This comment has been removed by the author.

    ReplyDelete
  13. how i can calculate the parameter of dc motor (j.B.L.)?
    2-Are you can send me code of pid controller without using parameters(j.B.L)?

    ReplyDelete
    Replies
    1. Hi, i don't calculate parameter of DC Motor
      The code of PID controller (without using parameter DC Motor) is in my blog. Please read it all.
      Thanks for visit.

      Delete
  14. ok..
    but are you have any away to calculate parameter of dc by matlab ?

    ReplyDelete
    Replies
    1. Hi, i know your mean: using calculated parameter to make PID parameter. Unfortunately, this project is not aimed to do that, this just tuned PID by experience and make it run.

      Delete
  15. Hola, ill be making this the next week,i hope ull be here for my questions,and i want to thank you for sharing this project with the internet :)

    ReplyDelete
    Replies
    1. i didnt find near me the needed equipments, so can i use the same concept with Arduino UNO +ESC 30A + A brushless motor ?

      Delete
    2. Sure, but you must have a way to let Arduino UNO know speed of brushless motor.

      Delete
    3. Okey, do you have any suggestions how i do that?

      Delete
    4. Please search on Google the way how to read speed of brushless motor

      Delete
  16. good morning, i have the next problem Excepción no controlada del tipo 'System.FormatException' en mscorlib.dll could you help me?, please

    ReplyDelete
    Replies
    1. Hi, please make program with Visual Studio step by step, then try to find where error comes from

      Delete
  17. hello,
    what is 60 , 200.0, and 0.1 in the following line ?
    pv_speed = 60.0*(encoder/200.0)/0.1;

    ReplyDelete
    Replies
    1. Hi, 200 is encoder pulse for 1 round; 0.1 is sample time (this case is 0.1sec)
      encoder/200 -> we will know how many round the motor is turned
      (encoder/200)/0.1 -> round per 0.1sec
      600*(encoder/200)/0.1 -> round per 60 sec -> round per minute

      haha, if so, above code is wrong, the calculation should be:
      pv_speed = 600.0*(encoder/200.0)/0.1

      Thanks for your comment.

      Delete
    2. Thank you very much for your quick reply.. This Project is Awesome. It is very clear even for those don't understand the theory behind PID.
      in the arduino code pv_speed per 0.1s calculation is multiplied by 60 so that should be 600 in order to have the rpm value right.

      big thumbs up for the useful post.

      Delete
  18. when i run the visual studio code give me this error.
    Error 3 error TRK0005: Failed to locate: "rc.exe". The system cannot find the file specified. E:\test_14_2\New folder\WindowsFormsApplication3\WindowsFormsApplication3\TRACKER WindowsFormsApplication3

    ReplyDelete
    Replies
    1. i'm not sure this error. So please paste the code into your Visual Studio and try to compile it.

      Delete
  19. Hi, where did you call the function "serialEvent" in the Arduino code.

    ReplyDelete
    Replies
    1. Hi, please visit this link to know about function "serialEvent"
      https://www.engineer2you.com/2016/12/arduino-serial-communication-visual.html

      Delete
  20. Sir
    if (e_speed_sum >4000) e_speed_sum = 4000;
    if (e_speed_sum <-4000) e_speed_sum = -4000;
    what above lines in code are doing???is it assigning rated shaft speed if it exceeds rated speed value???

    ReplyDelete
    Replies
    1. you're right. this prevents motor reaching rated speed in case of wrong PID parameter.

      Delete
    2. so if my motor rated speed is 225 , then i have use 225 in place of 4000 right???what -4000 indicates , reverse direction of motor???

      Delete
    3. Yes. Please replace it with your max speed.
      If i make this kind of KIT with 50$ (motor, H-bridge, Arduino UNO, mechanical assembly parts), ship over the world. Will you purchase with pre-pay by Paypal? How to you think?

      Delete
  21. can please explain why you selected 2,3,4,5,6 pins???if i am using arduino uno can it be ok same pins ???can u give description why you used those pins.

    ReplyDelete
    Replies
    1. Hi, please visit this link, you will understand function of pin 2 ~ 6, then you can replace it by UNO
      https://www.engineer2you.com/2016/12/arduino-motor-speed-control-pwm.html

      Delete
  22. sir pin 4 of H-bridge, if high then motor rotates in forward direction correct or not???same goes with pin5???sir ardiuno it is given IN1,IN2,IN3,IN4 as inputs for two motors and two enable pins En A ,En B .so pin 4 and 5 of H-BRIDGE IS EQUIVALENT TO IN1 AND IN2???

    ReplyDelete
    Replies
    1. Yes, Arduino Pin 4&5 to H-bridge IN1&2
      Arduino Pin6 to H-bridge ENA
      Just try it, you will get it :)

      Delete
    2. Hi, i have just update picture of connection between Arduino and H-bridge on Step1. Please take a look.

      Delete
  23. serial.available()<=0 means what???data not available???can you justify this line of your code.

    ReplyDelete
  24. sir for me current speed in visual studio not displaying,what shall i do???
    No waveform is coming but motor working fine.i dont know motor parameters,i am just trying z-n tuning method.

    ReplyDelete
    Replies
    1. Hi, firstly, you have to make sure that Arduino can communicate to Visual Studio by COM communication. Please come here
      https://www.engineer2you.com/2016/12/arduino-serial-communication-visual.html
      After confident about communication COM between Arduino and Studio, you will be able to show motor speed.

      Delete
  25. can i control speed without encoder by estimation ??

    ReplyDelete
    Replies
    1. HI, if by estimation, you can control it by PWM, please visit this link
      https://www.engineer2you.com/2016/12/arduino-motor-speed-control-pwm.html

      Delete
  26. Dear sir, I am using the motor shield l293d in my project ,thus istead of using pin 2 for encoder A, I use pin 19 which is also an interrupt pin. However the output pwm_pulse is always 0 even with any kp ki kd values. Then I try to divide the code into mutilple parts and try to see if it work properly. At first I tested the encoder function, it only work when i hidden the timer setup. Then I add the ISR() function and try to print out the pv_speed, but at this point I only got the 0 value on the monitor. so i guess the problem is from here. Could you please suggest me any idea to fix the problem ? thank you in advance.

    ReplyDelete
    Replies
    1. Hi, you can only use Pin 2 or Pin 3 (where is used for INT0 or INT1) for encoder A. Please try again with each section of code, you will understand. Thank you.

      Delete
  27. Electric motor repair can take many forms, ac motor repair depending on what kind of electric motor you have and the nature of its use in your business.

    ReplyDelete
  28. Hi,
    I want to use MATLAB Guide instead of Visual Studio, may I get the code for MATLAB Guide.

    ReplyDelete
  29. For a fraction of that cost, you can find a reconditioned used motor that will outlive any car you put it in. Actually, car dealer F&I products I've known of some that have outlived 2 cars.

    ReplyDelete
  30. Is it possible to have the datasheet of the motor used? in the video, which is the value in sec of the x axis? whithout datasheet, how I can determine that the encoder gives 200 counts per rounds. Which is the raise time of the motor, otherwise how you can choose a period of .1 sec for the PID control? In particolar, for the motor that you cited on AMAZON, there is no datasheet available. Thanks for your tie and answer.

    ReplyDelete