Working with the Brushless DC Motor

Connecting the brushless DC motor

The motor has connections for DC power, and we used a Plush 6amp Brushless Speed Controller, a third party ESC for regulating motor speed.

The power setup should be very straightforward; however, because of the signal noise and current draw from the motor, we suggest powering the motor from a separate DC supply and not from the Arduino board.  Though it’s not necessary, it’s easy to do and can prevent later complications.

ESC attached to a brushless DC motor. Connecting the middle lead is not necessary.

The control leads on the ESC are simple to connect too.  One is connected to ground, another deals with the PWM control signals and so should be connected to a PWM pin on the Arduino, and the middle one is Vout. The middle output is not necessary and was not used in the final design.

Controlling The Brushless DC Motor

The built in Arduino Servo library includes everything needed to control a brushless DC motor when Servo.h is included.  If you are having problems with Eclipse finding the module Servo.h, you can manually find the Servo.h and Servo.cpp files and move them into your current project folder.

To use the motor, first create an instance of type Servo. We’ll call this instance “motor”. Then, call

motor.attach(*pin*)

where *pin* is the pin on the board that’s connected to the motor’s control lead.

To set a speed for the motor, use

motor.write(*desired speed*)

In Servo.h, it states that the desired speed is an angle (or step) from 0 to 180. An explanation of how motor speed is derived from a degree angle can be found here.

Problems Encountered

The motor’s specs say that it will only work on the Seeduino’s pins 9 and 10, but these pins were already in use.  However, the motor worked on pins 5 and 7 as well as 9 and 10, so any PWM I/O pin should work.

When setting the motor speed, you cannot instantly assign an arbitrary angle while the motor is in stop position, the motor needs to be increased gradually. In order to start teh motor to start at 80, for example, start at 0 and work up to 80 in increments. Once the motor has started, you have more leeway in the angle jumps: going from 180 to 80 can be done.  We found that the motor did not begin to rotate until 45.

Timing the motor initialization with the beginning of the program was also a problem.  If the motor is not working properly (especially if the motor is not starting) when you are certain it should (e.g. you’re using Serial print statements to check that motor.write is getting the right arguments, logic analyzers to see that the correct PWM signal is being sent to the motor, and have checked that all wiring and power supplies are correct), then the problem may be a timing issue.  ENsure the motor is gradually approaching its starting speed, and play around with longer delays.

Here is some sample code taken from our motor control testing that illustrates everything covered above.

#include "Servo.h"

#define MOTOR_PIN			10
#define MOTOR_MAX_SPEED		        180
#define MOTOR_START_SPEED               80

int motor_current_speed = 0;
int motor_increment = 1;
int max_reached = 0;

Servo motor;

// 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);
	motor_current_speed = speed;

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

void motorSpeedUp()
{
/*
Speed up quicker than normal if speed is less than 100.
Motor's thrust to current relation is not linear - the motor needs a certain
minimum amount of current to generate sufficient thrust to initially lift the ball.
From observation, that minimum current is around speed 100.
*/
	int increment = (motor_current_speed < 100) ? motor_increment + 3: motor_increment
	motorSetSpeed(motor_current_speed + increment);
}

void motorSlowDown()
{
	motorSetSpeed(motor_current_speed - increment);
}

void motorStop()
{
	motor.write(0);
}

/*
!!! Very important! Motor has to start at 0 and reach desired speed gradually.
It will NOT work if you go directly to speed 60 or 100, etc.
If this isn't working for you, try increasing the delay.
*/
void motorStartAt(int start_speed)
{
	int i;
	for (i=0; i < start_speed; i+=5) {
		motorSetSpeed(i);
		Serial.println(i);
		delay(100);
	}
}

void setup()
{

	// Setup deb
	Serial.begin(9600);

	// Motor
	delay(1000);
	motor.attach(MOTOR_PIN);
	motorStartAt(motor_start_speed);
	delay(1500);
}

/*
Speeds the motor up until it hits 170,
then slows it down to the start speed again.
Repeats.
*/
void loop()
{

        if (!max_reached) {
            motorSpeedUp();
        } else {
            motorSlowDown();
        }
        if (motor_current_speed < MOTOR_START_SPEED) {
            max_reached = 0;
        } else if (motor_current_speed > MOTOR_MAX_SPEED) {
            max_reached = 1;
        }
        delay(500);
}

7 thoughts on “Working with the Brushless DC Motor

    • Hey Willi, you don’t actually need it. That was a generic header file for the .c file of the same name created by my IDE. I’ve removed that include for clarity.

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>