Driving a brushless DC motor using an Arduino

There are several samples on the web, that show a brushless DC motor being driven using an Arduino and an RC ESC. Most of these samples come without sketch sources, and that is kind of lame.

Now, that I am building my own ROV (more on that soon, maybe), I had a need for a solution, as most of what's on the web was either over-complicated or just didn't work. Controlling an brushless DC motor via an ESC using an Arduino is surprisingly simple, yet  a bit frustrating at times due to three facts:
  1. ESCs seem not to come with pulse widths defined (min, max) in their manuals. At least not the HobbyKing Quik 60A and the Flyermate 80A.
  2. Even if "auto throttle range" is supported, it still needs to be within an acceptable range.
  3. Figuring out the ideal range can be "labor intensive".
Below is a sketch that works just perfect with both the Quik 60A and the Flyermate 80A. The only difference between the two is that the Flyermate seems to respond better to a shorter range of 700 - 1700, while the Quik responds to 700 - 2300.

Tested on Arduino Mega2560.


#include 
Servo mServo;  // Create a servo object for the motor

int inPotPin = 1; // Analog input pin #1 reads pot value
int outPinPPM = 11; // PPM output pin #11

int throttlePulse = 1500;

int pulseDelay = 300;
int pulseMin = 700;
int pulseMax = 2300;

void setup() {
  Serial.begin(19200);
  mServo.attach(outPinPPM, pulseMin, pulseMax);
  mServo.writeMicroseconds(throttlePulse);  // Quik 60A arms in "neutral"
  
  for (int i=5; i<=0; i--) {
    Serial.print("Starting in ");
    Serial.println(i);
    delay(1000);
  }

}

void loop() {
  throttlePulse = map(analogRead(inPotPin), 0, 1023, pulseMin, pulseMax);
  mServo.writeMicroseconds(throttlePulse);
  delayMicroseconds(pulseDelay);
  Serial.print("Throttle is at: ");
  Serial.print(map(throttlePulse, pulseMin, pulseMax, -99, 99));
  Serial.println("%");
}

0 comments: