Lessons on Arming ESC with Arduino

I find this question often in the internet - and I also see it go unanswered. Here is a stepwise guide to arm the Brushless ESC using Arduino. The usual disclaimer applies: 1) this is a general guide to know your arming point - not a specific answer; 2) this may kill your arduino / your ESC / your motor or your computer - am not responsible.

Having gotten them out of the way:

#include <Servo.h>

Servo motor;

void setup ()
{
  motor.attach(9); 
  Serial.begin(9600);
  int i = 0;

  //Give some time before you start anything like switching on your ESC / Motor

  Serial.print("Arming Test Starts in ");
  for(i =10; i > 0; i--)
  {
     Serial.print(i);
     Serial.print(".. ");
  }

  Serial.println();

// Watch for the tone when the ESC gets armed

  for(i = 50; i < 130; i++)
  {
     motor.write(i);
     Serial.println("i");
     delay(500);
  }
}

void loop()
{
}

When I run this on my ESC, it first gives 10sec to setup / switch on all the stuff. When you switch on your ESC, you will hear a double beep (note this tone). Now the second loop after the delay starts - where it sends one degree worth of pulse every 500 millisecs to the ESC. I have intentionally made a wide range (50 - 130), whereas your ESC will probably arm very close to neutral.

When the signal to the ESC reaches 87 - 93, pay attention - the ESC will let out another beep. This is different from the one you heard when switching it on.

There is a bit of experimentation needed here to pinpoint the exact arming position. For my ESC, now - all I do is the following, to arm it.

 void setup()
{
   motor.attach(9);
   motor.write(91); 
   delay(300);
}

Note 1: My ESC arms at a signal of “91”. For your ESC, it may be 90 or 92.
Note 2: The delay is crucial. I have gone down till 200 millisecs and still got it working. Try pushing the limit, and post as reply if you can get it.

Once the ESC has been armed, then it is a simple case of treating the angle as the run signal to the ESC. For example - see the code below

void loop()
{
  motor.write(105); delay(1000);
  motor.write(91); delay(2000);
}

will repeatedly run the motor for 1 second, and brake it for 2 seconds. Now, once the ESC is armed - the signal code “91” is merely treated as a Servo angle signal and will not repeatedly arm the ESC (until you switch the power off and on again).

I am still trying to get the forward and reverse turns on my motor reliably - it happens sporadically. I will post a second post once I have got it down pat.

I hope this helps.

Here, I provide a sample code that managed to run the car autonomously (meaning: it ran without any Tx / Rx).

#include<Servo.h>

Servo esc; 

void setup()
{
  esc.attach(9);
/*
As you can see - I am not arming the ESC here.
For some reason, the ESC is now on a persistently armed mode now. 
Upon powering, the ESC automatically arms. 
Given sparse documentation for the ESC, I am not examining this behavior change. 

However, if your ESC refuses to arm, see the first post in this thread.
*/

//Again - this is useful only during the testing part. For autonomous running, it is pointless.

  int i=0;
  Serial.begin(9600); 
}

void loop()
{
  int i=0;
  // Start at Servo Degree 70 and go till just above neutral. 
  // Note, Neutral is at 94 for this ESC.
  // This will run it in one direction.
  for(i=70;i<95;i++)
  {
    esc.write(i);
    delay(200);
  }
//Run for 2 seconds at moderately high speed (70).
  esc.write(70); delay(2000);
// Apply Brakes for 40 millisecs.
  esc.write(100); delay(40);
// Apply throttle in opposite direction for 2 seconds.
  esc.write(110); delay(2000);
// Bring down throttle to neutral.
  for(i=110;i>90;i--)
  {
    esc.write(i);
    delay(200);
  }
// Apply brakes again - to change directions for 40 millisecs.
  esc.write(70); delay(40);
}

This code has not been rigorously tested at all. For example, there is no reason why I used 40 millisecs instead of, say, 35. All I have noticed is that at the pulse frequency (50Hz / 20 millisecs) this code doesn’t work. So, in all likelihood, 21ms could also work. Also - I don’t know what will happen if I bring the run throttle (70 and 110) closer to neutral (say,
85 and 100). In some cases, the ESC behavior abruptly changes, and the direction shifting doesn’t happen (it stops running in one of the directions).

However, this code has allowed the RC car to move forward and in reverse without any external input at all. (time for a drink).

Given below is a photo of the car I had used for this purpose - it is a Traxxas / TT rip-off rally frame. The big (1/10) frame has plenty of room / power for carrying the Arduino board, a 7200 mAh NiMH battery for the car, a 10000mAh USB power bank (used to power the Arduino board) and everything else in between. I have not provided the connection drawing, because it is - at this point - trivial.