ESC Calibration & Programming

Calibrating the 4 Mystery 12A Electronic Speed Controllers (ESCs) seemed to be a daunting task given the vague documentation, but the process turned out to be very simple.  Unlike the Turnigy ESC used for the previous project, the Mystery ESCs we used were brand new and needed to be calibrated to read the pulse width modulation (PWM) signal generated by the Arduino Uno.  In addition, the Mystery ESCs also provided a number of programmable options (e.g. breaking).  This section will explain how to calibrate and program the Mystery ESCs.

ESC Calibration

Calibration, in terms of ESCs, means to set the max and min speeds of the motor in relation to the max and min width of the PWM signal sent by the Arduino.  A PWM signal is simple a square wave signal consisting of high and low (5v and 0v) signals for certain durations.  Some sample PWM waves are shown below.

Sample PWM Signals. Retrieved from http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

The PWM signal read by the ESC is the same type as a servo signal, meaning the Servo library from Adruino can be used to calibrate and control the ESCs.  The ESC sets the speed of the motor depending on the ratio of high to low signals.  Calibration involves programming the ESC to understand the PWM waves corresponding to the stop and maximum speeds of the motor.

The default signal range for most servo motors and ESCs is a high signal width between 1000 and 2000 microseconds over a repetition period of 20 milliseconds (assuming a 50hz PWM signal).  For the quad copter, however, we want the range to be as wide as possible to allow for greater incremental control of the motor.  To this end, we calibrated the ESCs to read a signal width from 700 to 2000 microseconds with 700 being the stop speed and 2000 being the max speed.  We found that the ESC could not read a signal lower than 700 microseconds.

Calibrating the Mystery ESCs was quite simple.  To enter programming mode, the maximum servo signal (2000 microseconds) is sent to the ESC, the ESC is powered on and waits for two seconds, then the minimum servo signal is sent (700 microseconds).  Once the ESC emits a series of confirmation beeps (special wave signals sent to the motor to emit beeping sounds), the ESC is calibrated.

Motor, ESC, and Arduino

ESC calibration and motor testing. Motor is attached to a plastic plate, which is held by a clamp.

The Arduino Uno can calibrate the ESCs with some relatively simple code shown below.  Once the ESCs were attached to their motors, the signal and signal ground connectors were attached to an Arduino PWM pin and a GND pin respectively.  Then the Arduino Uno is powered and emits a 2000 microsecond servo signal before the ESC is powered on, so the first signal the ESC receives is the maximum signal.  Once the ESCs have been powered on for two seconds, the user sends a command to the Uno to emit a 700 microsecond signal.  If the user waits more than two seconds, the ESC will enter programming mode.

#include <Servo.h>

#define MAX_SIGNAL 2000
#define MIN_SIGNAL 700
#define MOTOR_PIN 9

Servo motor;

void setup() {
  Serial.begin(9600);
  Serial.println("Program begin...");
  Serial.println("This program will calibrate the ESC.");

  motor.attach(MOTOR_PIN);

  Serial.println("Now writing maximum output.");
  Serial.println("Turn on power source, then wait 2 seconds and press any key.");
  motor.writeMicroseconds(MAX_SIGNAL);

  // Wait for input
  while (!Serial.available());
  Serial.read();

  // Send min output
  Serial.println("Sending minimum output");
  motor.writeMicroseconds(MIN_SIGNAL);

}

void loop() {  

}

ESC Programming

Although not required for the quad copter, the ESC can be programmed with a number of different options.  This is useful to understand in case the ESC is accidentally programmed and needs to be factory reset.  Like calibration, programming mode is entered by emitting the maximum servo signal when the ESC is powered on.  After several seconds, the ESC will enter programming mode.

In programming mode, each option is specified by a unique set of tones.  In our Mystery ESCs, the first set of tones indicate whether the break should be turned on or off (break will stop the motors instead of letting them wind down on a minimum speed signal).  To set an option, the minimum servo signal should be emitted when the appropriate tones are heard.  Once an option is set, the ESC will emit some confirmation beeps and must be powered off for 5 seconds before more options can be programmed or for normal operation.

The calibration code from above can also be used to program the ESCs.  For more details about the programming options available on the Mystery 12A Blue Series ESCs we used, consult the manual.

For even more advanced and risky ESC programming, see this thread on how to flash the ESC firmware.

25 thoughts on “ESC Calibration & Programming

  1. Great post! Helped me a lot however I am having trouble getting my esc running. The ESC is a redbrick 30A hobby king, the manual states that it uses PWM frequency of 8khz. How would I calculate the periods to find the pulse widths?

      • Hi, its a very interesting post and it was very helpful for me but I still do not understand the way you selected max and min frequency for esc signal. As you told to rashaad, the periods ar given by
        f=1/T => T=1/f=1/8000=125ms
        for redbrick 30A hobby king ESC and when I try to run the brushless motor it runs but it doesn´t reach full throttle and it starts running from its own minimum threshold not from the one that I specified in arduino code. What am I doing wrong?

  2. Glad you found it useful. Hmm interesting. I think you would actually still calibrate it the same way. 8khz seems like a bit too fast to be true…

    • you are too much, i want to learn from you, am studying mechanical eng. so i want to cross to mechatronics i will be very greatful if you can be my master

  3. Thankyou for sharing this code. This is the only one that has been able to work for me. But I have a question:

    In almost every other example I’ve seen, the MAX_SIGNAL value is set to 179
    and the MIN_SIGNAL value is set to 0, and yet putting those values into your code didnt do anything to arm my esc. However, when I used 2000 and 700 it armed flawlessly. Why is this?

  4. hello

    can someone help me i am totaly newbie in programing
    i need code for running brushless motor with arduino for regulating power i ll have potentiometer.
    can someone please send me code

    thanks a lot

    • /*
      * Brushed_H_Bridge_simple sketch
      * commands from serial port control motor direction
      * + or – set the direction, any other key stops the motor
      */
      const int in1Pin = 3; // H-Bridge input pins

      void setup()
      {
      Serial.begin(9600);
      pinMode(in1Pin, OUTPUT);

      Serial.println(“enter the value between 1 and 8″);
      }
      void loop()
      {
      if ( Serial.available()) {
      char ch = Serial.read();

      if(isDigit(ch))
      {

      int speed = map(ch, 0, 9, 0, 255);
      analogWrite(in1Pin,speed);
      Serial.println(speed);
      }
      else
      {
      Serial.print(“Motors are ready”);

      }
      }
      }

  5. Hi, Good day. does your quadcopter is an autonomous one? can ask for your favor to help us? because we are also building an autonomous quadcopter for our last year project and im a newbee to this field. Pleassee??:(

  6. Hi,

    What size/voltage battery did you use for this project?

    I have everything loaded on the Arduino and plugged in similar to your setup, but you don’t talk much about the power source.

    Let me know, thank you!

  7. hello..
    nice info,i also do by my own final year project that are include XBee S2, Arduino Uno, Battery LiPo 11.1v and quattro esc 25A (http://www.hobbywing.com/product_show.asp?id=292) and i have design my remote control to control my Quadrotor..

    here is my program,could you check my program,because i have some trouble which I try to calibrate my brushless motor by my own,from the naked eye the brushless motor seems have synchronous which I do not attach my propellers when calibrate, but when I try to fly with my full gear, my Quadrotor become unstable when try to lift up and crashed.

    #include

    Servo myservo1;
    Servo myservo2;
    Servo myservo3;
    Servo myservo4;

    int angle1;
    int angle2;
    int angle3;
    int angle4;

    void arm(){

    // arm the speed controller, modify as necessary for your ESC
    setSpeed(0);
    delay(1000); //delay 1 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
    angle1 = map(speed, 0, 100, 34, 160);
    angle2 = map(speed, 0, 100, 90, 150);
    angle3 = map(speed, 0, 100, 98, 155);
    angle4 = map(speed, 0, 100, 34, 160);
    myservo1.write(angle1);
    myservo2.write(angle2);
    myservo3.write(angle3);
    myservo4.write(angle4);
    }

    void setup()
    {
    myservo1.attach(5);
    myservo2.attach(6);
    myservo3.attach(10);
    myservo4.attach(11);
    arm();
    Serial.begin(9600);
    }

    void loop()
    {
    int speed;

    if (Serial.available()>=21){
    if (Serial.read()==0x7E){
    for (int i=1;i<19;i++){
    byte discardByte = Serial.read();
    }
    int analogMSB = Serial.read();
    int analogLSB = Serial.read();
    int analogReading = analogLSB + (analogMSB * 256);

    analogReading=analogReading/10.23;
    speed=analogReading;
    setSpeed(speed);
    Serial.print("Input =");
    Serial.print(analogReading);
    Serial.print(" motor1 =");
    Serial.print(angle1);
    Serial.print(" motor2 =");
    Serial.print(angle4);
    Serial.print(" motor4 =");
    Serial.print(angle2);
    Serial.print(" motor3 =");
    Serial.println(angle3);

    }
    }
    }

    • Hey Wan,
      Even if you have all motors running at the same speed, that doesn’t mean your copter will be stable in flight. That’s why we have sensors and the Aeroquad program to adjust the speed of each motor individually depending on the orientation of the copter.

  8. Hi,
    I have a situation that maybe you could help with. After seemingly working the way you describe, I have an issue with my ESC calibration. Of my four motors, two require the max throttle followed by minimum throttle to calibrate and be ready to respond. The problem is that the other two seem to calibrate when they are powered on. This will cause problems when the quad is built. If I throttle up and down to calibrate two of my motors, the other two will actually spin at that max throttle for two seconds.
    Any thoughts?
    Thank you!

    • Hey Niel,
      Not sure what your specific setup is, but if you have motors that functions differently you’ll have to modify the code so it doesn’t send signal to the other two motors while you’re calibrating. The code on this page is only the calibrate one motor at a time via a single pin.

  9. Pingback: Quadcopter Arrived! (Most of it) | Nick Whyte

  10. He also should see to it. Despite the school bus recession excuse to overspend.
    Request a visit from the contractor’s license bond. Needless to say most people find
    themselves disrespecting the government be looking for another person who will perform the job done on site.
    You want to hire a contractor can tell you how to hire a school bus contractor to finish.
    Instead of just being late either, and they can’t give you
    this oh I like the finished project.

    Here is my site – website (Rosemarie)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>