Arduino control of ESC

Hi -

I am spending some time looking at how an Arduino can be used to control a brushless motor. I am using an Arduino Duemilanove, a Hacker x-5 Pro ESC, and a Hacker A-10 brushless motor.

I am able to both arm the ESC and use it to operate the motor, but I am running into a few items that I don't quite understand that are mostly related to using the Servo library.

This first sketch is used to arm the ESC and works as expected:

// This sketch arms the Hacker X-5 Pro ESC

int escPin = 9;
int arm = 1000; // pulse width in microseconds (Start Signal)

void setup()
  {
// It appears that the ESC will accept a range of values for the arming
// sequence. This provides 10 pulses with a pulse width of 1000 us with
// with a 20 ms delay between pulses.

     pinMode(escPin, OUTPUT);
     for (int count = 0; count < 10; count++){
        digitalWrite(escPin, HIGH);
       delayMicroseconds(arm);
       digitalWrite(escPin, LOW);
      delay(20);
     }
  }

void loop()
{


}

This second sketch adds to the first one and both arms the ESC and then provides a pulse train to operate the motor at a constant speed. This also works as expected.

// This sketch arms the Hacker X-5 Pro ESC and
// then runs the attached A-10 Hacker brushless motor
// at a constant speed.

int escPin = 9;
int arm = 1000; // pulse width in microseconds for arming
int speedvalue = 1350; // pulse width in microseconds for operation

void setup()
 {

// It appears that the ESC will accept a range of values for the arming
// sequence. This provides 10 pulses with a pulse width of 1000 us with
// with a 20 ms delay between pulses.

   pinMode(escPin, OUTPUT);
   for (int count = 0; count < 10; count++){
      digitalWrite(escPin, HIGH);
      delayMicroseconds(arm);
      digitalWrite(escPin, LOW);
     delay(20);
   }
}


void loop()
  {

// Once armed the ESC needs to receive a pulse train to operate the
// the motor. The motor speed is controlled by the duration of the
// pulse width.
// This simple loop provides a pulses width a width of 1350 us and a
// separation of 20 ms.

       digitalWrite(escPin, HIGH);
       delayMicroseconds(speedvalue);
       digitalWrite(escPin, LOW);
       delay(20);

}

I would be happy with this, but I have looked over some forums and find many mentions of using the Servo library to control the ESC/motor combination. The only problem is that the only sketches that I can find refer to the Servo Sweep sketch that runs the motor speed up and down. If I arm the ESC using the above sketch and then upload the Sweep sketch to the Arduino, the motor runs as expected with the speed oscillating up and down.

I then wrote the following sketch to use the servo function to arm the ESC. This code works, but does not behave as the arm sketch above. This sketch arms the ESC, but if I then turn the power to the ESC off and then on, the ESC rearms without the sketch being run again. So something going on with the myservo.write that I am not getting...

// This sketch uses the servo library to arm the Hacker X-5 Pro ESC.
// Once loaded this code will rearm the ESC after its power has been
// turned off and on without being re-run.
// What is going on????

#include <Servo.h>

Servo myservo;

int arm = 46; // supplies a pulse width of approximately 1000 us

void setup()
{
  myservo.attach(9);
  for (int count = 0; count < 10; count++){
  myservo.write(arm);
}
}

void loop()
{

}

This last sketch arms the ESC using the servo functions but does not result in operation of the motor. I would be okay with this except that when I look at the pulse train on a scope, they look virtually identical.

// This sketch uses the servo library to arm the Hacker X-5 Pro ESC.
// Once loaded this code will rearm the ESC after its power has been
// turned off and on without being re-run.
// What is going on????

#include <Servo.h>

Servo myservo;

int arm = 46; // supplies a pulse width of approximately 1000 us
int speedvalue = 100; // supplies a pulse width of approximatley 1350 us

void setup()
{
   myservo.attach(9);
   for (int count = 0; count < 10; count++){
   myservo.write(arm);
}
}

void loop()

// This loop produces a pulse train but it does not result in
// the ESC operating the brusless motor.

{
myservo.write(speedvalue);

}


If any one has any insight to what is going one within the code, I would appreciate your feedback. I would also be interested in seeing a sketch that uses the servo library to operate the ESC/motor at a constant speed.

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –

Replies

  • I have solved most of my issues in the above post. The sketch below uses the servo library to arm, throttle up, run at various constant speeds and then disengage a brushless motor. Hope that this helps a few folks....


    // This sketch uses the servo library to arm the Hacker X-5 Pro ESC.

    #include <Servo.h>

    Servo esc; // Define the ESC as a servo object

    int arm = 1000; // defines pulse width of 1000 us
    int speedvalue;
    int steady = 300;
    int initiate = 0;

    void setup()
    {
        esc.attach(9);
        esc.writeMicroseconds(arm);

    // This command sends a pulse train
    // from pin 9 that continues until
    // the pin is called to do something else.

    /* Once armed the setup could also be used to specify the
    run speed of the motor. The commented out lines provide
    a 2 second delay between changes in speed.
       delay(2000);
       esc.writeMicroseconds(1200);
       delay(2000);
       esc.writeMicroseconds(1300);
      delay(2000);
      esc.writeMicroseconds(1400);
      delay(2000);
    */
    }


    void loop()
    {

    /*
    Calls a sub to throttle up motor from 0 rpm to a steady running value.
    The if statement is used to run the throttle up once.
    */
       if (initiate < 1){
          throttleUp();
          initiate = 1;
       }

    /*
    You can then change the speed in the main loop by changing the pulse width.
    If nothing else is going on in the loop, a delay must be included otherwise
    the servo writeMicroseconds is called to fast and there is not the proper
    time delay between pulses (I think this is the case...need to check this
    on a scope. The minimum delay is 15 ms. The lines below use a 1 second delay
    between speed settings. The loop also causes this to be run once
    */

       if (initiate < 2){
          for (int count = 0; count < 5; count++){
              speedvalue = speedvalue+50;
              esc.writeMicroseconds(speedvalue);
              delay(1000);
          }
         for (int count = 0; count < 12; count++){
            speedvalue = speedvalue-50;
            esc.writeMicroseconds(speedvalue);
            delay(1000);
         }
      initiate = 2;
      }

    esc.detach(); // Disengage ESC from pin

    }


    //**************************************************

       void throttleUp(){
           speedvalue = arm;
           for (int count = 0; count < steady; count++){
                 esc.writeMicroseconds(speedvalue);
                 speedvalue = speedvalue + 1;
                 delay(15);
           }}

  • A couple of comments. 

    - It might be easier to use servo.writeMicroseconds(). 

    - Once you do the myservo.attach(), a PWM pulse stream will be sent continuously to the ESC.  So, in setup, you might try:

        myservo.writeMicroseconds(975);  // initial low value to enable ESC

        myservo.attach(9); // start PWM stream

      No loop is needed, because once you do the write, the same PWM is maintained until you change it.

This reply was deleted.

Activity