Sunday, June 10, 2012

Arduino - Control ESC/Motor Tutorial



Summary
This is a tutorial of how to control an electronic speed control (ESC)and brushless motor using an Arduino.

Description
This tutorial is about controlling a brushless motor, the type commonly used in RC hobbies, and controlling the motor using an Arduino.  The goal is to use the Arduino Servo library, give an input from 0 to 180, and see the motor move based on our input.

Before we begin
Hooking up the Arduino to an RC hobby ESC is always the same.  The difference is that you will need to know how to arm your ESC.  This means you'll need to look for the manual that tells you how to arm your ESC.

When reading your ESC manual, you'll most likely notice that the literature/manual was written for people who have other RC equipment.  My manuals have always talked about the need to adjust the throttle in order to trigger an event like arming or programming modes.  We will be substituting the throttle with the input we give the Arduino.

Safety (always)
"You'll shoot your eye out" - A Christmas Story
Experimenting with the combined equipment of an Arduino, ESC, motor, and computer can cause harm to you or your equipment under certain situations.  Here's some items to consider for some of the components involved.

Motor
Make sure there is nothing attached to your motor (i.e. no props).  Don't test with props attached.  I jumped out of my chair, swearing, the first time the motor ran because I didn't expect it to work.  In custom trial and error, you never know what's going to happen.

Secure the motor to something while experimenting.  You don't want the motor jumping around when it unexpectedly comes to life.  If you need an ideal example, please how Ray29erau has his motor secured in his youtube video.

Protect Your USB ports
While an Arduino may be relatively cheap, let me save you a USB port.  No matter what you are thinking of doing, don't connect the positive line of your ESC to your Arduino pin labeled 5v.   If you connect your battery to the ESC, connect your Arduino to your computer by USB, and connect the gnd, signal, AND 5V into the Arduino..... you will probably damage (lose, fry, kill, etc) whatever USB port your Arduino is plugged into on your computer.   There's a good possibility you could lose the Arduino board too.  For a full explaination, please see "10 ways to Destroy an Arduino".... more specifically it's "Method #5".

Battery
General battery safety is recommended.  I'm using a lithium polymer (LiPo) battery.  If you want to know more on LiPo's, check out this page.  If you have a question or doubt about something you are doing with a LiPo battery, find someone who knows about the safe handling/charging of battery/LiPo's and ask.  For example, I bought mine from an awesome local hobby shop.  If I had questions about what I bought and the answers weren't included with the manual or couldn't be found online then I would ask the people that sold the gear to me.

D.) Other
This is the other category.  This is all meant to be fun.  When experimenting, there may be times you feel uncomfortable or unsafe about doing something in a project.  At times like these, find a person, forum, or group (Arduino forums linked) to ask and make your situation safe at all times.
 
Steps
Control the ESC/Motor using an Arduino
  1. Connect the ESC to motor.
  2. Connect the ESC to Arduino - pay attention or you will kill a USB port/Arduino (Protect Your USB Ports).
  3. Connect the Arduino to you computer.
  4. Upload your sketch to the Arduino.
  5. Use the Serial Monitor to arm the ESC
  6. Done!!! Do other stuff....


Begin
1. Connect the ESC to motor.

Simply enough, connect the ESC to the motor (Figure 1.1).  Notice that my yellow wire is in the middle.  Both the black and the red wires are on the outside.  If your ESC doesn't have colored wires (as seen on another ESC Figure 1.2), don't worry.  Getting the outside wires mixed up would only make the motor spin in the wrong direction.  There would be no harm in getting the outside wires wrong.  If you find your motor is spinning really fast when you think it should be stopped...  you only need to reverse the polarity between the ESC and motor.  


Figure 1.1 - Motor connected to ESC

Figure 1.2 - Two ESC's next to each other

2. Connect the ESC to Arduino.

Connect the Arduino's pin labeled "GND" to the ESC (Figure 2.1).  For this project, I am using pin 9 for the signal, yours may be different.  Connect the Arduino's pin labeled "9" to the ESC's white signal line (Figure 2.2).  That's it for step two.
As discussed in above in the safety section under "Protect Your USB Ports", DO NOT connect the Arduino pin labeled 5V to the ESC. (Figure 2.3)


Figure 2.1 - Arduino GND to ESC

Figure 2.2 - Arduino pin #9 to ESC

Figure 2.3 - DONT DO THIS
Figure 2.3 - DONT DO THIS

3. Connect the Arduino to your computer.
Connect the Arduino to your computer (Figure 3.1). It's super-easy.

Figure 3.1

4. Upload your sketch the Arduino.
Open up your Arduino IDE. Click here to open up the reference page (it has the Arduino sketch).  Copy the sketch on the reference page and paste it into your own sketch.  Upload the sketch to your Arduino (Ctrl + U).


5. Use the Serial Monitor to arm the ESC.

In the Arduino IDE, select "Tools" then select "Serial Monitor".  At this point, plug your battery into the ESC.  Your ESC will probably be different that mine.  This is where it's all about trial and error now.

Your ESC will be different but mine always gives a series of beeps.  According to the manual, the series of beeps tells me that the the ESC is on.  At this point, the manual (mine is found here) says the following:
"The  H . K i n g   ESC will not arm unless you
move your throttle stick to the lowest position. When
the H.King ESC receivesthe low throttle command, it
will arm and play a double tone through the motor,
indicating it is armed and now ready to run." 
Great.  I have no idea what this correlates to in the values from 0 to 180.  That's okay.  I did my trial and errors by typing numbers between 0 and 180 into the Arduino IDE Serial Monitor.  I tried the lows (0, 5, 10, 15, 20), the middle (90), and the high (170, 175, 180).  What I found was that sending "10" will arm the ESC and it will start spinning when I enter (send) "55" or higher from the Serial Monitor (Figure 5.1). Figure 5.1 shows what happens when I type "10" and then "55" into the Serial Monitor.

Be careful when doing trial and error with the motor.  When figuring out the ranges, high and low could be backwards.  For example, high might be "0" and low might be "180".  The first time my motor spun was when I sent 180, coincidentally I also found out that this was the high end of the range.

Figure 5.1
6. Done!!!  Do other stuff....

If you have figured out how to make your motor spin.  Congrats! It's a fun learning experience.  Most likely, you are trying to get your motor spinning for some other project and this was one of the first steps.  Good luck!








64 comments:

  1. Cheers this was a great help

    ReplyDelete
  2. Thanks a bunch, your tutoril is very clear and helpful.
    it works as expected following your 5 steps method.

    regards

    ReplyDelete
  3. this is great! thanks

    ReplyDelete
  4. Hey, thanx for the post it's really helpful.
    Unfortunately i'm having real trouble arming my ESC, i'm using the Hobbywing 20A ESC. I don't have a RC transiever so i have to arm it manually using an arduino as u demonstrated, the manual states that the ESC has to be armed by positioning the throttle stick to the low level , then a sequence of musical beeps will play.

    Nothing happens! , the ESC RANDOMLY beeps 2 sequential beeps, i don't know why it beeps i don't know why it stops! I've tried your code among every other available code onlinewith NO Success!! ... any help would be appreciated!

    Thanks alot!

    ReplyDelete
    Replies
    1. Try the following code (this code is the second example (Arduino - Control ESC/Motor Tutorial ex2.) without any code in the loop. This code is just to get the motor or motors armed. Connect your ESC to the Arduino just like it shows in this example.
      Upload the code posted below to your Arduino. disconnect power from both the ESC and the Arduino. Try power one on before the other (maybe a timing issue).

      If that doesn't work, change the values in the startup of the code. The idea of the code posted below is to arm your ESC by writing 0 to 60 (out of 180), in steps of 5, the ESC will arm. If this doesn't work, try going varying the start values or the increments.

      On a side note - Make sure you're motors are secured to something when testing like this because you never know when they will start working for some reason.



      #include "Servo.h"

      #define MOTOR_PIN 9 // This is the left motor
      #define MOTOR_PIN_R 10
      #define MOTOR_MAX_SPEED 90 // NOT REALLY NEEDED
      #define MOTOR_START_SPEED 60

      /*
      * This is the max/min speed values restriction
      */
      int motor_left_minimum = 68;
      int motor_left_maximum = 118;
      int motor_right_minimum = 68;
      int motor_right_maximum = 118;

      int motor_current_speed = 0;
      Servo motor; // This is the left motor
      Servo motorRight;

      String left;
      String right;
      void setup()
      {

      // 115200 default for blusmirf gold
      //Serial.begin(115200);

      // 9600 default for the xbee pro series1
      Serial.begin(9600);

      // Motor
      delay(1000);
      motor.attach(MOTOR_PIN); // This is the left motor
      motorRight.attach(MOTOR_PIN_R);
      motorStartAt(MOTOR_START_SPEED); // Arming procedure
      delay(1500);
      }



      void loop()
      {

      }





      // Wrapper function for Servo's ".write(*speed*)" function
      void motorSetSpeed(int speed)
      {


      // Don't let the motor go above or below pre-determined max and min
      if (speed > MOTOR_MAX_SPEED)
      speed = MOTOR_MAX_SPEED;
      else if (speed < MOTOR_START_SPEED)
      speed = MOTOR_START_SPEED;

      motor.write(speed);
      motorRight.write(speed);
      motor_current_speed = speed;

      //Serial.print("current motor speed = ");
      //Serial.println(motor_current_speed);



      }



      void motorStartAt(int start_speed)
      {
      int i;
      for (i=0; i < start_speed; i+=5) {
      motorSetSpeed(i);
      Serial.println(i);
      delay(100);
      }
      }

      Delete
  5. Hey
    Thanks for the informative article. I tried to implement it as is, but have been getting some weird results. When I open up the Arduino Serial Monitor, there is no "Initializing" message. Also, when you enter a number, it gives the ASCII value (ex. entering space gives 32. No matter how high the number I enter, it does not activate the motor. I was wondering if you would be able to offer any suggestions. I am using an Arduino Leonardo

    ReplyDelete
    Replies
    1. I don't have a Leonardo but I think that you might have to look at a couple of items.

      1. - It's documented that for the Leonardo, you will need to use the following code to write anything (to the Serial Monitor).

      while (! Serial);

      I can't test this but I'm guessing that it should be put before anything is written while in the Setup(). For example, take the reference code for this article:

      // Set everything up
      void setup()
      {
      // Put the motor to Arduino pin #9
      myMotor.attach(9);

      // Required for I/O from Serial monitor
      Serial.begin(9600);

      // Wait for the Serial to be setup
      while (! Serial);

      // Print a startup message
      Serial.println("initializing");
      }

      The code "while (! Serial);" was added before executing Serial.println("initializing"); I can't test this so, I'm only guessing. For reference, I learned this from the "tronixstuff" ( http://tronixstuff.wordpress.com/2012/06/21/first-look-the-arduino-leonardo/ ) and from the follwing link:
      http://arduino.cc/forum/index.php?topic=110085.0

      2. After you get the "initializing" to print on the Serial Monitor, I would use the second example.
      http://techvalleyprojects.blogspot.com/2012_10_01_archive.html

      This example writes steps from 0 to 60 in the setup in order to arm the motors. This would lead you to the second challenge... figuring out how to arm and move your motor.

      The reason this is the second challenge is because your motor(s) may not arm the same way that my motors did in the example used.

      I'm confident that after getting "Serial.println("initializing");" to work in your code with your Leonardo, you will be able to write to the Serial Monitor in in order to find a way to get your motor(s) to move.

      Good luck, hope this helps.

      Delete
  6. Well i followed all the steps above and used a potentiometer to control the position being sent to the motor, plugged everything in and connected the battery, nothing happened. Turned the potentiometer until it was sending a value of 10, the esc beeped then the motor spun a little and the esc burst into flames, what am i doing wrong? Using a hobbyking 10A esc

    ReplyDelete
    Replies
    1. Hi Scarecrow,
      What motor and type of battery are you using with the ESC? While I don't know your specific situation, here are some things that come to mind.

      Bad ESC, bad motor, or a mismatch of battery/esc/motor could be the culprit. I've put some links at the bottom that might explain on your experience.

      Also, I didn't use a potentiometer (pot) with anything I've done. Maybe just using the serial monitor (Ctlr+m) in the Arduino IDE to arm and move your motor would be a good way to start?

      Also, note that there are two general steps to getting your motor moving, arming the esc and moving the motor. Based on feedback, I've noticed that the arming procedure may be different for your equipment. In the second code post for this article, I was able to arm the ESC by writing 0 to 60 in steps of 5 (0 then 5 then 10.. etc.) when the Arduino powered on. After this procedure, the I got the correct sequence of beeps, as documented in the Hobbyking instructions. After the arming sequence is complete, I could get the motor to move by writing any value to it over 65. To get it to stop, I would write 65. Again, (based on feedback) it appears that the arming sequence for others may be different. For an example of what was used for two motors (and the arming sequence above), see:
      http://techvalleyprojects.blogspot.com/2012/10/arduino-control-escmotor-arduino-code.html


      Other links that might explain your experience:
      Bad motor with shorted windings or other damage can cause the ESC to catch on fire.
      https://www.hobbyking.com/hobbyking/forum/forum_posts.asp?TID=19641

      Always make sure your ESC is rated at a power level higher than your motor can handle. And always use fresh quality LiPo batteries. A low grade battery will cause the Speed Controllers FET's to overheat and eventually burn.
      http://www.hobbyking.com/hobbyking/store/uh_listCategoriesAndProducts.asp?catname=hexTronik+ESC&idCategory=185&ParentCat=182

      Choosing the correct motor/battery/esc:
      http://www.modelairplanenews.com/blog/2011/05/29/choosing-a-motor-speed-control-battery-pack-taking-the-mystery-out/


      Hope this helps! Good luck

      Delete
  7. Hi! I am a college student trying to learn how to program some stuff for my class.

    The ESC I'm using is the LRP Ai Runner Reverse. The code is not working as intended, so I have some questions:

    1) Where do I type in the numbers for the serial monitor? I know this sounds like a ridiculously silly question, but I'm assuming it's the bar on top with the send button to the right? I have been using that.

    2) The code only types "initializing" and then "I have received: n+48", where n is the value from 0-9 that I have typed. What's more, when I type in 12, for example, I get this output:

    I have received: 49
    I have received: 50

    That is, the program interprets my entry as 1, and then 2!

    Help? ---Thanks!

    ReplyDelete
    Replies
    1. That is a cool ESC that you are working with.

      In response to the ref code used on: http://techvalleyprojects.blogspot.com/2012/06/arduino-control-escmotor-arduino-code.html.

      Before going into the long explaination, here is what you need to see all the numbers you typed in. In the bottom of the "Serial Monitor", the combobox on the left (probably says "No line ending" by default) will have an option for "Newline". Select it. This will add "\n" (ASCII value 10) after you click "send" in the "Serial Monitor". For more general background information, you should check out ladyada's tutorial on Serial Data:
      Current: http://learn.adafruit.com/adafruit-arduino-lesson-5-the-serial-monitor/overview
      Previous version: http://www.ladyada.net/learn/arduino/lesson4.html

      With


      Full explanation:

      "Where do I type in the numbers for the serial monitor? I'm assuming it's the bar on top with the send button to the right?" - You got it, thats the right place! The Serial Monitor in the Arduino IDE can be found two ways. Click on "Tools" then click on "Serial Monitor". Or the shortcut key for the Serial Monitor is "Ctrl+Shift+M". Either way will get you there. When the Serial Monitor is open, you can type into the Textbox or Text Field near the top. After you enter the values, click on the send button to the right of the textbox.

      "2) The code only types "initializing" and then "I have received: n+48", where n is the value from 0-9 that I have typed. What's more, when I type in 12, for example, I get this output:

      I have received: 49
      I have received: 50"

      When you get the output "initializing", the code has reached the line "Serial.println("initializing");". This is significant becuase it tells you that the code has reached the last line of "setup()". As important, by reaching the last line in "setup()" we can assume that the next thing that we do will be to enter into "loop()". This is important to see because if we didn't see it, we can assume that the code is not reaching that line when executing (it's a way to debug).
      In the example that you are using, the code will print out each character that has been received. Here are the following lines of code and the relavant output that you posted.

      The code:
      if (ch != 10){
      // Print out the value received
      // so that we can see what is
      // happening
      Serial.print("I have received: ");
      Serial.print(ch, DEC);
      Serial.print('\n');

      // Add the character to
      // the incomingString
      incomingString += ch;
      }

      Your input (into the Serial Monitor textbox):
      12

      Your output:
      I have received: 49
      I have received: 50

      Description:
      The Arduino will read the characters "12", one by one. As long as the characters you sent don't include a "New Line" character, it print the characters back to you, one by one. The code above shows you, character by character, what you have sent. It then adds it to a String.

      If you go to the left combo box on the bottom of the Serial Monitor and select the option for "Newline", then you would receive the above output (same as you got before) as well as the following output after that prints:

      Additional output with "Newline" selected:

      Input:
      12

      Output:
      initializing
      I have received: 49
      I have received: 50
      I am printing the entire string
      12
      Printing the value:
      12
      Value is between 0 and 180


      Hope this helps - Sorry for the delay (weather and work delays). Good luck!

      Delete
    2. LRP Ai Runner Reverse - Kinda want one now. Made a swamp boat (fan boat) a few months ago out of a cannobolized uav. Would have been really cool to have one of these.

      Just took a look at the manual for: LRP Ai Runner Reverse. Just as a note for the examples here, they were written for hobby esc/motors.

      Reason why I mention this is because you'll find that the esc's I used had to be "armed". This meant that to use them, I had to find a way to arm them. In many example sketches you'll find that people are writing a set of values 0 to 60 in increments of five when starting the sketch/arduino. You shouldn't need to do this. According to the manual for a LRP Ai Runner Reverse you should be able to just start writing values to the esc without having to arm it first.

      Using the servo library you should be able to control this with no problems. The example you are trying to use would work great for one esc.

      Delete
    3. Thanks for the detailed response!

      The reason I'm trying to "arm" the ESC is because I need to figure out what values the ESC outputs so I can mimic that with the Arduino (I'm working on a project that requires switching between manual driving and autonomy). The robot is also large enough so that I cannot use servos to program things, which only adds to the difficulty.

      I think though that I have confused your code for something else - It would be more accurate to figure out what values the receiver is outputting, no? I guess this is kind of off-topic, but if you know of any tutorial to figure out how to send values to the motors and make them spin forwards and backwards, I would be really grateful!

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

      Delete
    5. I'll admit, it's a tough subject to get into (but great learning experience) because much of the terminology involved belongs to several different subjects. It gets easier to replicate this once you do are able to make it happen once.

      "The reason I'm trying to "arm" the ESC is because I need to figure out what values the ESC outputs so I can mimic that with the Arduino (I'm working on a project that requires switching between manual driving and autonomy). The robot is also large enough so that I cannot use servos to program things, which only adds to the difficulty."

      Most likely, you'll need a motor driver or an ESC to control you motors. For example, let's use the rc equipment in this post. Normally, someone wanting to use this on a hobby RC vehicle will connect everything in the following manner:

      receiver (signal input)
      /
      Motor<-- ESC <
      \
      battery (power)

      This is supposed to look like Motor<--ESC< above/connected to ESC is receiver and below/connected to ESC is battery (power)

      We want to control the same motors so we replace the receiver with an Arduino.

      Arduino (signal input)
      /
      Motor<-- ESC <
      \
      battery (power)
      This is supposed to look like Motor<--ESC< above/connected to ESC is Arduino (signal input) and below/connected to ESC is battery (power)

      Using the arduino, we can pretend to be the reciever. Using the Servo.h library we can send input to the ESC. (Note: While the library we are using to control a motor is called "Servo.h", forget about the name. Its just a word for a library, we are using this library to control the motor. This sounds complicated in a way but its not. We are using the Servo.h library because it can send the correct signal input to the esc.

      In this way, we can use whatever means needed to communicate with the Arduino that will control the motor.

      An obvious limitation in using hobby motor/esc's is that the motors can only go one direction. Your ESC

      The only problem that I've run into is that you'll have to experiment a little with your values. You can write the values 0 to 180 in the servo library. You have to experiment with sending these values to your motor/esc (safely) in order to map the values appropriately.

      Some motor/esc's have to be "armed", meaning that they will do nothing until you put the throttle to low or some other combo. This is a safety feature for rc hobby equipment since it is assumed that the motor is capable of injuring people. Some motor/esc's don't need to be armed (I think this is your esc) where the ESC is just ready to start working as soon as it has power.

      Out of curiousity (and probably helpful for others), what motor, ESC, battery are you using?



      Cool example of motor control:
      http://arduino.cc/forum/index.php/topic,8652.0.html

      Some reasons why you can use the Arduino Servo.h library to "control" that controls a motor:
      http://www.instructables.com/id/How-to-Make-400Watt-Brushless-Mini-Sumo/step6/How-to-control-ESC-with-arduino/

      Good ESC info:
      http://www.stefanv.com/electronics/escprimer.html

      http://forum.rc-airplane-world.com/viewtopic.php?f=47&t=1285

      http://en.wikipedia.org/wiki/Electronic_speed_control
      DC ESCs in the broader sense are PWM...

      Delete
  8. I have a LRP AI Runner and I'd love to know how you got it working. Every time I send it any signal it either stutters (5,6) or just goes full throttle (10+). Thanks for all the tutorials you've made!

    ReplyDelete
    Replies
    1. Awesome, you got it running! That's the majority of the work (the rest is fine tuning)

      Do you have a link for the LRP AI Runner and it's manual?

      Doing a quick look all I can find is:
      http://www.lrp.cc/en/products/electronic-speed-controls/brushed-forwardbrakereverse/produkt/ai-runner-reverse/details/

      This is the LRP A.I. Runner Reverse. Also, read the comments above at it applies to this.

      According to the manual for this esc, it implies that it finds the max/min throttle of the user. There is a setup procedure according to the manual and it probably uses this to "learn" for as long as it has power.

      Before we dig into the manual, here's some thoughts. We are pretending to be the receiver (see above comments). According to the manual for the ESC (in the link above), the arduino and it's "Servo.write(some value);" will be the "transmitter". For the code on this page our throttle or transmitter will be the line, "myMotor.write(val);" (ref: http://techvalleyprojects.blogspot.com/2012/06/arduino-control-escmotor-arduino-code.html).

      Taken from the manual (at the esc link above):

      "After wiring up the speed-control, it is ready to operate. No setup is required. The speed-control "learns" the neutral, full-speed forward and full-speed reverse points while the car is running. Please note: Before you plug in the drive battery, set the transmitter to neutral position and then start the model in the forward direction.

      If you have made a mistake so far, don’t worry: Unplug the battery for about 10 seconds and start over again.
      After the run, first unplug the battery and then switch off the transmitter. When you start again, first switch on the transmitter and then plug in the battery."


      This snippet on the setup makes me think that I need to decide on a middle value to write to the ESC, then give power to the esc, then start by moving forward.

      I would be prepared for trial and error. And safety always.. mount or secure your motor to something before trials.

      To help, use the code posted on the next comment, it's the reference code but modified to use three new values: MAX_VALUE, MIN_VALUE, NEUTRAL_VALUE. The only changes are the new values, the NEUTRAL_VALUE is written to the ESC in the setup, and the number that you send the arduino must be between the MAX_VALUE and MIN_VALUE in order to be written.

      Hope this helps.

      Delete

    2. /*
      * This code is in the public domain.
      * (Do whatever you want with it.)
      */

      // Need the Servo library
      #include

      // This is our motor.
      Servo myMotor;

      // This is the final output
      // written to the motor.
      String incomingString;

      int MAX_VALUE = 35; // This is the max value
      int MIN_VALUE = 5; // This is the min value
      int NUETRAL_VALUE = 20; // This is the middle value between max/min


      // Set everything up
      void setup()
      {
      // Put the motor to Arduino pin #9
      myMotor.attach(9);

      // Required for I/O from Serial monitor
      Serial.begin(9600);

      // Start the motor in the middle (neutral position)
      myMotor.write(NUETRAL_VALUE);

      // Print a startup message
      Serial.println("initializing");
      }


      void loop()
      {
      // If there is incoming value
      if(Serial.available() > 0)
      {
      // read the value
      char ch = Serial.read();

      /*
      * If ch isn't a newline
      * (linefeed) character,
      * we will add the character
      * to the incomingString
      */
      if (ch != 10){
      // Print out the value received
      // so that we can see what is
      // happening
      Serial.print("I have received: ");
      Serial.print(ch, DEC);
      Serial.print('\n');

      // Add the character to
      // the incomingString
      incomingString += ch;
      }
      // received a newline (linefeed) character
      // this means we are done making a string
      else
      {
      // print the incoming string
      Serial.println("I am printing the entire string");
      Serial.println(incomingString);

      // Convert the string to an integer
      int val = incomingString.toInt();

      // print the integer
      Serial.println("Printing the value: ");
      Serial.println(val);

      /*
      * We only want to write an integer between
      * 0 and 180 to the motor.
      */
      if (val > MIN_VALUE && val < MAX_VALUE)
      {
      // Print confirmation that the
      // value is between 0 and 180
      Serial.println("Value is between 0 and 180");
      // Write to Servo
      myMotor.write(val);
      }
      // The value is not between 0 and 180.
      // We do not want write this value to
      // the motor.
      else
      {
      Serial.println("Value is NOT between 0 and 180");

      // IT'S a TRAP!
      Serial.println("Error with the input");
      }

      // Reset the value of the incomingString
      incomingString = "";
      }
      }
      }

      Delete
  9. could the same connection of ESC be used with 89c52 microcontroller

    ReplyDelete
    Replies
    1. I can't speak for the 89c52 microcontroller, but it looks like it could.

      In the example above, the Arduino Servo library is used to write the value 0 to 180 to the ESC. If you can mimic the Arduino's Servo control behaviour in the same way with the 89c52 microcontroller then the example above would work.

      If it is a smaller motor (like ones in toys), you can use a simple npn transistor, power supply, and pulse width modulation (pwm) on the base pin of the transistor to control a motor.

      Example of small motor control:
      http://www.instructables.com/id/Use-Arduino-with-TIP120-transistor-to-control-moto/
      http://itp.nyu.edu/physcomp/Tutorials/HighCurrentLoads


      Someone mimics pwm on the 89c52 here:
      http://www.keil.com/forum/12277/

      Delete
  10. why do you use 0 to 180 output data?Can I use 0 to 255?

    ReplyDelete
  11. 0 to 180 is the default range of the Servo.h library. This range represents the angle of the shaft in degrees.
    http://arduino.cc/en/Reference/ServoWrite

    You can use 0 to 255 by mapping the range. Two examples:
    http://arduino.cc/en/Reference/map
    http://playground.arduino.cc/ComponentLib/servo (the example is at the bottom, this is for a different library)


    ReplyDelete
  12. Im am using JDrones ECS 20 AMP http://store.jdrones.com/product_p/acesc20amp.htm, for a arducopter, and I don't have any RC Controls (only arduino and ECS) for manual calibration, so your guide is very useful, thanks

    ReplyDelete
  13. Another Question, im aim my ESC and motor at 55, later I heard 2 beeps, after that, i put 60 and the motor spin, my question is, does the brushless motor have a sound like squeal? I not sure is normal that sound or have a problem with friction or something.

    ReplyDelete
    Replies
    1. The following youtube videos show three different sounds:
      1. http://youtu.be/aADN7iCx9E4
      In this video, at about 6:30, you can clearly hear the sound of the motor spinning. The sound of my motors most closely resemble the motors in this video.

      2. http://youtu.be/VItgYtk5Kqs
      Another example of how motors spinning can sound.

      3. http://youtu.be/s2Tzg0R28L0
      This is the video that is linked in the tutorial. At about 3:15, the motor is started. When the motor begins to spin, you can hear the distinct sound it makes. My motors do make this sound.

      Another good source for questions is a local hobby shop that sells RC motors/ESC's. They may be able to show you what a couple motors sound like or they may be able to tell you if the motor/esc sound is a problem.

      As a side note, one of the initial problems I had when mounting motors to a frame was the mounting screws were just slightly to long. For that case specifically, I got shorter screws and spacers which solved the problem.

      Hope this helps.

      Delete
  14. I send appreciate to you. My mind is confused for many days about how to command brushless motors with esc using Arduino
    Thank you again..
    I hope you improve yourself and this site also

    ReplyDelete
    Replies
    1. Kind words, thank you. I am glad that the material was helpful. Good luck on your path with the project.

      Delete
  15. Nice article! I just fried the programming card for my ESCs tonight by connecting a 2S battery to the connector labelled battery.(perhaps they mean regulated 5v?)

    Not having a radio-set nearby, I found this article to be just the thing. Programming is still about as much 'fun' as using the transmitter, but by lunch tomorrow I'll have a program that should do what I want.
    It sure would be lovely if the protocol that the programming card uses was public, is it's so much quicker and less convoluted than the sticks-up, sticks-down malarky.

    Nothing an arduino listening to the communication or a $40 cro wont solve!
    -enhzflep-

    ReplyDelete
  16. great intro!! tnx

    ReplyDelete
  17. Hello there!
    Thanks for very interesting article, but I have a question to ask. I have a ESC marked as Opto, that means it has no internal BEC (Battery Eliminator Circuit which produces +5V from LiPo battery), therefore ESc does not power its +5V line. Does a safety measure concerning USB port apply here? It seems that USB (or other external power) is the only thing powering Arduino if I use BECless ESC, so I cannot really disconnect it.
    And another question. How does Servo library work here? Could the same be done using simple analogWrite(0..255)?

    ReplyDelete
  18. Merci beacoup !!:

    ReplyDelete
  19. Will it be possible to connect the ESC to the Arduino VIN output pin so you don't need an external battery just for the ESC?

    9V > Arduino > ESC > Motor

    ReplyDelete
    Replies
    1. 9V on the pin labeled "VIN" will power the Arduino. The pin labeled "5v" on most Arduino's will only provide 400 to 800ma (or less) (depending on the Arduino). This most likely won't provide enough power for your motor. Generally motors will pull money.

      The idea here is that a lipo powers an esc/motor. The arduino only provides a signal to the esc (The arduino tells the esc/motor what to do).

      lipo > esc > motor
      ^
      |
      pwm pin
      |
      9v > Arduino


      Also, I would recommend using one power source (9v) for the Arduino and a different power source (lipo) for the the esc/motor (based on experience of controlling.

      if you are worried about harming your Arduino, check out:
      http://ruggedcircuits.com/html/ancp01.html

      Good luck.





      Delete
  20. I guess I haven't learned that my ascii art doesn't work well in blogspot.

    So here is what the diagram is supposed to look.

    lipo > esc > motor

    9v > Arduino - pwm pin -> esc (esc mentioned above)

    ReplyDelete
  21. Hi, congrats for the post, i beleive if i had some more time it would have been useful to me. i am trying to use the reference sketch that u have here but its not working it only gives me:

    initializing
    I have received: 49
    I have received: 48
    I have received: 49
    I have received: 48

    I wonder if am doing anything wrong because i connect the esc just like u did and everything but the motor is not moving just doing , beepbeepbeepbeepbeep any idea,


    thanks

    ReplyDelete
    Replies
    1. Not sure why but the 'newline' option in the serial monitor is selected by default. I guess its not this way for everyone, I'll make an edit. Thanks!

      Someone else had this problem too. This is answered in one of the earlier comments but the short answer is that you need to select 'newline' from the combobox in the serial monitor.

      from the earlier post:
      Description:
      The Arduino will read the characters "12", one by one. As long as the characters you sent don't include a "New Line" character, it print the characters back to you, one by one. The code above shows you, character by character, what you have sent. It then adds it to a String.

      If you go to the left combo box on the bottom of the Serial Monitor and select the option for "Newline", then you would receive the above output (same as you got before) as well as the following output after that prints:

      Additional output with "Newline" selected:

      Input:
      12

      Output:
      initializing
      I have received: 49
      I have received: 50
      I am printing the entire string
      12
      Printing the value:
      12
      Value is between 0 and 180



      As for that beeping.... for most motor/esc's that I've seen, they will just beep at me when they have power. They beep once every few seconds to tell me that they are powered. For the esc/motors I've used, the motors/esc will make a distinct low to high beeping sound when they are armed. When you hear this, the motors will move when you send them the minimum value.

      There is some code that was written for two motors. You should be able to upload that to the arduino, wire it as shown above, and it will arm your motor/esc. To control the motor/esc, you'll have to send the values as shown (for two motors) on that page even if you have one motor/esc.

      good luck!!!

      Delete
  22. Just thank you for this post.
    I am trying to build a tricopter my only problem so far is how to choose the lipo. I have 3 motors 2350 kv max 15A continue, and 3 esc 30A. If need to choose a lipo which will not burn my esc... if you can help me that would be great. Meanwhile I will have a look on a link you provide before on this subject.

    ReplyDelete
  23. Great info! Second post I've read on this site and the detail and information in the posts is fantastic and very useful :-) Thanks again!

    ReplyDelete
  24. Hi, how can this rotate clockwise and anti -clockwise with programming... I just have no idea

    ReplyDelete
  25. i am using 2300mah 11.1v battery,when i run one bldc motor through esc with propeller at 60 as input it run,as i increase from 60 to 79 its speed increases but as i enter 80 as input motor stops and battery shows the voltage 2.86 v,when i disconnect the battery then battery shows again 11.1v and same thing happened when i run four bldc without propeller the motor stops at 70 as input. now tell me what i have to do with this problem?

    ReplyDelete
  26. Hi there,

    Firstly your tutorial is brilliant, really helpful however I have a few questions.

    I am very new to Arduino control systems and for my final year at Universtiy Honours Project I undertook the task of producing a working hull crawling robot. Basically it is a submarine tank that can crawl across the submerged hull of boats. I have an Arduino Uno controlling it, I have a 2 motor gear box to drive the tracks and a 1 central brushless motor that provide the thrust to keep it in contact with the boat.

    The brushless motor is a N5045/07-KV800 Outrunner Brushless Motor, which draws up to 40A, I am using a variable power supply and have managed to get the motor running using the following sketch that I found on in the Arduino forums, I am also using a Turnigy Marine 60A ESC, basically a hobbywing seaking.


    // this uses the Arduino servo library included with version 0012

    // caution, this code sweeps the motor up to maximum speed !
    // make sure the motor is mounted securily before running.

    #include

    Servo myservo;

    void arm(){
    // arm the speed controller, modify as necessary for your ESC
    setSpeed(0);
    delay(2000); //delay 2 second, some speed controllers may need longer
    }

    void setSpeed(int speed){
    // speed is from 0 to 100 where 0 is off and 100 is maximum speed
    //the following maps speed values of 0-100 to angles from 0-180,
    // some speed controllers may need different values, see the ESC instructions
    int angle = map(speed, 0, 100, 0, 180);
    myservo.write(angle);
    }

    void setup()
    {
    myservo.attach(9);
    arm();
    }


    void loop()
    {
    int speed;

    // sweep up from 0 to to maximum speed in 20 seconds
    for(speed = 0; speed <= 100; speed += 5) {
    setSpeed(speed);
    delay(1000);
    }
    // sweep back down to 0 speed.
    for(speed = 95; speed > 0; speed -= 5) {
    setSpeed(speed);
    delay(1000);
    }
    setSpeed(0);
    delay(5000); // stop the motor for 5 seconds
    }

    That operates the motor for about 2-3 seconds however if i change the values that much it on longer operates.

    Using your code it emits 6 short beeps then 1 long beep, Even after typing many many values into the serial monitor I still get no response from the motor at all.

    Any help would be greatly appreciated!

    Kind regards

    Tom

    ReplyDelete
  27. Thanks for your great tutorial! =]
    I just have a question, do you think I can use this to control motors of a quadcopter? I heard that having more incremental steps means more control for the motors and I think 0 to 180 is not a wide range.
    I'm confused whether to use your code or this one: http://robots.dacloughb.com/project-2/esc-calibration-programming/

    ReplyDelete
  28. I really appreciate you sharing this info! I've bee looking for some insights on motor and process control, but I haven't had any success yet. This helped a ton though, and I can't wait to learn more.

    http://www.imsgc.com.au/Whatwedo

    ReplyDelete
  29. Many thanks for your very interesting article! I also had troubles with the "newline" problem! :-)
    I suggest you write a couple of lines in you article about this, so it can be frustrating for many of us.
    Jamal Owens, maybe your problem is you don't set the combo, down in the serial window, to say "newline".
    Otherwise the sketch doesn't work.

    ReplyDelete
  30. "Very nice post. I just stumbled upon your blog and wanted to say that I've really enjoyed browsing your blog posts. Thanks for sharing thsi post on
    Monitor and Control Your Projects
    it improves project time management, Maximizes Productivity and improve busines"

    ReplyDelete
  31. Great article!! Really helped me a lottt..... I could say the only post that helped me when even my college teachers couldnt help!!
    And for those whose motor is not starting...use this code...tried and tested!!!

    // Need the Servo library
    #include

    // This is our motor.
    Servo myMotor;

    // This is the final output
    // written to the motor.
    String incomingString;


    // Set everything up
    void setup()
    {
    // Put the motor to Arduino pin #9
    myMotor.attach(9);
    myMotor.write(0);
    delay(1000);
    myMotor.write(10);
    delay(1000);
    myMotor.write(20);
    delay(1000);
    myMotor.write(30);
    delay(1000);
    myMotor.write(40);
    delay(1000);
    myMotor.write(55);
    delay(1000);
    myMotor.write(65);
    delay(1000);
    myMotor.write(75);
    delay(1000);
    myMotor.write(100);
    delay(1000);
    }

    void loop()
    {

    myMotor.write(170);
    delay(5000);
    }

    ReplyDelete
  32. Hi!
    First of all great tutorials and perfectly explained.
    I have a little problem I can't solve. I begin a project with RC car and in future I would like to make it an autonomous vehicle. I'm using Tamiya's M-05 Chassis with stock ESC (TBLE-02S). In manual to change form forward to reverse you need to push remote controller from forward to reverse, return to neutral and then again push to reverse (I think it's for safety reasons to protect gears).
    My problem is the same, just instead a remote control I use Joystick attached to my arduino (When I try to reverse I pull reverse return to neutral and then again reverse). If I make it autonomous the reverse wouldn't work because of this first reverse pull ...I think.
    I've also tried your code from the next post "Arduino - Control ESC/Motor (Arduino Code)" with little changes I make it work with my brushed motor and the result is the same(to reverse from forward I'm doing FWD->Neutral->REV->Neutral->REV; I want to make it: FWD->Neutral->REV).
    I'm posting part of my code(because of post limit) to clear things a little bit:

    void setup() /****** SETUP: RUNS ONCE ******/
    {
    Serial.begin(9600);
    SteeringServo.attach(ServoSteeringPIN); // attaches the servo to the servo object
    MotorServo.attach(MotorPIN); // attaches the servo to the servo object

    }//--(end setup )---


    void loop() /****** LOOP: RUNS CONSTANTLY ******/
    {
    SteeringPotValue = analogRead(SteeringPotPin); // Get the value as user moves pot
    MotorPotValue = analogRead(MotorPotPin); // Get the value as user moves pot

    // scale it to use it with the servo (value between MIN and MAX)
    SteeringServoPosition = map(SteeringPotValue, 0, 1023, ServoMIN_H , ServoMAX_H);

    // tell servos to go to position
    SteeringServo.write(SteeringServoPosition);

    // Serial.println(SteeringPotValue);
    Serial.println(MotorPotValue);
    delay(20);

    if (MotorPotValue < 524){
    reverse();
    }
    else if (MotorPotValue > 524){
    forward();
    }
    else if (MotorPotValue == 524){
    MotorServo.write(90);
    // delay(10);
    MotorServo.write(87);
    // delay(10);
    MotorServo.write(90);
    delay(10);
    }

    }//--(end main loop )---

    /*-----( Declare Functions )-----*/
    int full_brake(){
    MotorServo.write(90);
    // delay(10);
    MotorServo.write(87);
    // delay(10);
    MotorServo.write(57);
    MotorServo.write(37);
    MotorServo.write(0);
    MotorServo.write(90);
    delay(50);
    }

    int reverse(){

    MotorServo.write(90);
    // delay(10);
    MotorServo.write(rev_MAX);
    // delay(10);
    MotorServo.write(rev_MIN);
    // delay(10);
    MotorServo.write(90);
    // delay(10);
    ReverseServoPosition = map(MotorPotValue, 523, 1, rev_MIN , rev_MAX);
    MotorServo.write(ReverseServoPosition);
    }

    int forward(){
    MotorServo.write(90);
    // delay(20);
    ForwardServoPosition = map(MotorPotValue, 525, 1023, fwd_MIN , fwd_MAX);
    MotorServo.write(ForwardServoPosition);
    }

    I've tried everything I think of (calling function to "Lie" the ESC for the first reverse, but the result is same).
    Anyway ...I'm not a great programmer, so it could be another solution to my problem.

    Thanks in advance and sorry for my bad English :)

    ReplyDelete
  33. Hi! Nice tutorial! Which ESC did you buy? and which motor are you using? I was wondering what is the rule when buying an ESC that will be compatible with the motor.

    ReplyDelete
  34. I have a 3-phase brushless motor 1100 kv, an esc to 30 A, a battery of 5 Ah LiPo 3-cell and when I sent a progression from 0 to 180 and then 180 to 0 went well and then I disconnected; I repeated and it went well. The third time I hear sound, but no longer turns.
    I'm desperate, I know you help?

    ReplyDelete
  35. Hi, I have sent a sweep from 0 to 180 and then back from the loop of the sketch and 2 times the engine worked, but always at the same speed and then the third time no longer worked. What could have happened?

    ReplyDelete
  36. Hi, I have sent a sweep from 0 to 180 and then back from the loop of the sketch and 2 times the engine worked, but always at the same speed and then the third time no longer worked. What could have happened?

    ReplyDelete
  37. I have sent a sweep from 0 to 180 and then back from the loop of the sketch and 2 times the engine worked, but always at the same speed and then the third time no longer worked. What could have happened?

    ReplyDelete
  38. Thanks for your nice tutorial. Awesome article i learnt to this article really i like it. Yes guys one important thought i have a article read here: https://www.robomart.com/servo-motors

    ReplyDelete
  39. It is nice and useful piece of info. Please keep us informing like this. Thank you for sharing this.

    Video Surveillance Vancouver | Vancouver Security Cameras

    ReplyDelete
  40. Thanks a lot for this tutorial!
    I'm currently working on a project where I have to control a 24V bldc motor with an arduino due. There are usable ESCs, but my question is, if there things so worry about, because I use an Arduino Due. This one works not with 5V, it works with 3,3V. If the ESC ist just connected with the signal pin and the GND of the arduino, this is not a problem, or is it?
    Thanks!

    ReplyDelete
  41. Hi there!
    Incredibly helpful...Thank you so much!
    However, I can only arm ESC with a value of 85, and then the only value that will turn my motor is 170. From there the only other responsive value is 95, which seems to slow the motor down. All other values just disarm the ESC! I am struggling to find any logical answer anywhere on the internet! I'm using an Arduino Mega with Afro 20A ESC(SimonK Firmware). I hope your still active on this thread! You'd be saving my skin!

    ReplyDelete
  42. Hi!
    Here is H-KING programming utility for Arduino:
    http://wrknts.blogspot.ru/2016/10/h-king-arduino.html

    ReplyDelete
  43. wow it works 10 arms it then 50 half sppedd the 150 full speed thanks

    ReplyDelete
  44. wow it works thanks
    10 arms it 50 starts and about 170 full speed

    ReplyDelete
  45. why does my motor activate at 102 and not 10?

    ReplyDelete
  46. Thirteen cards or next %e0%b8%9f%e0%b8%a3 the declare of this game is the 3 card pile. locate out if it can be played in an online casino system. Because it has limitations, for example, it must be played by 4 people or the payment amount is not always the same. The amount of payment is not always the same, which makes it hard to play. But now there are thirteen card games in the online casino system. https://918kiss2020.com/tag/%e0%b8%9f%e0%b8%a3/

    ReplyDelete