Continuous Rotation Servo Motor

A continuous rotation servo motor can rotate continuously, like a wheel. This type of servo motor can be made to rotate in either direction (clockwise or counterclockwise).

However, if your device needs to rotate to a precise angle and hold that position, then you need a regular servo motor, such as the one included in your Photon kit.

The continuous rotation servo motor comes with several different plastic mounts (called "horns") that can be attached to the motor axis (the white part sticking out of the top of the motor – this is what actually rotates). There are double-arm horns (2 sizes), a four-point horn, a six-point horn, and circular horns (2 sizes). Each horn just slips onto the motor axis (the horn and axis have matching "teeth"). Each horn has holes, which can allow you to attach something to the arm, using the included mounting hardware (screws, etc.).

This servo motor has a built-in 3-wire connector: just plug 3 jumper wires into the connector and then plug the other end of the jumper wires into a breadboard or directly to the Photon. To make it easier to remember which wire is which, use corresponding white, red, and black jumper wires to match the servo motor wires.

NOTE: This servo motor requires 5V of power, so connect it (directly or indirectly) to the V-USB pin.

IMPORTANT: The data wire must connect to an I/O pin that supports pulse-width modulation (PWM) output. Only the following pins on the Photon can act as PWM outputs: D0, D1, D2, D3, A4, A5, WKP, RX, TX.

TIP: Be sure to attach one of the horns to your servo motor. Otherwise, you won't be able to see the servo motor rotate (and it won't provide much use to your device).

Experiment 7 of the online SparkFun Photon Experiment Guide shows how to connect a servo motor. Here is the connection diagram for Experiment 7 (ignore the wiring for the push button):

Code for Servo Motor

Library

The servo motor does need a code library with special functions that will allow you to control the servo motor. However, this library is already built-in to the Particle firmware on your Photon device.

Global Variables

In the global variables, you should declare which pin is being used as the servo motor data pin. The example below declares a variable called "servoPin" (but you could use a different variable name).

You also need to declare a Servo object variable that you will use to run the special functions in the built-in Servo library. The example below declares a variable called "servo" (but you could use a different variable name).

// if necessary, change data pin number to match your wiring
int servoPin = D0;

// declare Servo object variable called "servo"
Servo servo;

OPTIONAL: You may also want to declare a global variable to represent the direction of the servo motor rotation (counter-clockwise, stopped, or clockwise). This isn't required, but it could make it easier to code the servo motor, especially if the direction or speed of rotation will be changed by the user or are necessary to track. The example below declares a variable called "direction" (but you could use a different variable name).

// global variable to represent direction of servo rotation
int direction;

setup( ) function

There isn't any code that you need to include in the setup() function. You don't have to set a pin mode for the servo.

However, if you want your servo motor to be turned on when your device first starts, then add the necessary code to do this within the setup() function.

Turn Servo Motor On (or Off)

You have to call a special function called servo.attach() to turn on the motor. For a continuous rotation servo motor, this typically only has to be done once, so this statement could be included within the setup() function (which only runs once).

// turn on servo motor
servo.attach(servoPin);

NOTE: You can stop the motor from rotating, while still keeping the motor turned on (so it's ready to rotate again when you need it to).

However, if you need to completely turn off the motor, then call the servo.detach() function. This would be useful if the motor only needs to rotate for a specified period of time (to complete an action) and then might spend a long time unused.

// turn off servo motor
servo.detach();

If the servo motor is completely turned off (detached), then you will need to include a servo.attach() statement before your code can rotate the motor again.

Rotate Servo Motor in Specific Direction (or Stop Rotation)

You can make the servo motor rotate clockwise, counter-clockwise, or stop.

Code for controlling the servo motor rotation can be placed within the setup() function (only runs once), within the loop() function, or within a custom function.

There are two different methods for controlling the rotation of a continuous rotation servo motor. Both work by changing the timing of the electrical pulses sent to the servo motor. You can use either method, but you should probably just use one, in order to keep your code simpler and avoid any issues.

METHOD 1: servo.writeMicroseconds()

A continuous rotation servo motor can be controlled by calling the servo.writeMicroseconds() function, which typically accepts values from 1000-2000. A value of 1000 should rotate the motor counter-clockwise at full speed. A value of 2000 should rotate the motor clockwise at full speed. A value of 1500 should cause the motor to stop rotating (and without any vibration). Intermediate values can be used to change the speed of the rotation.

// rotate counter-clockwise full-speed
servo.writeMicroseconds(1000);

// rotation stopped
servo.writeMicroseconds(1500);

// rotate clockwise full-speed
servo.writeMicroseconds(2000);

If necessary, you can fine-tune the values listed above based on testing with your actual servo motor. You could go as low as 700 or as high as 2300.

CAUTION: If you adjust the endpoint values too far (too low or too high), you might damage the motor.

METHOD 2: servo.write()

A continuous rotation servo motor can also be controlled by calling the servo.write() function, which accepts a value from 0-180. A value of 0 should rotate the motor counter-clockwise at full speed. A value of 180 should rotate the motor clockwise at full speed. A value of 90 should cause the motor to stop rotating (and without any vibration). Intermediate values can be used to change the speed of the rotation.

// rotate counter-clockwise full-speed
servo.write(0);

// rotation stopped
servo.write(90);

// rotate clockwise full-speed
servo.write(180);

Rotate Servo Motor for Specific Period of Time

If you need your device to only rotate for a specific period of time, then simply use a delay() statement to wait for a specific amount of time in milliseconds (1000 milliseconds = 1 second) before stopping the motor.

servo.writeMicroseconds(2000); // rotate clockwise
delay(5000); // allow to rotate for 5 seconds
servo.writeMicroseconds(1500); // stop rotation

OPTIONAL: Declare Constants for Servo Rotation Values

You can declare constants (as part of your global variables) to represent the possible directions of the servo motor rotation. This isn't required, but in some cases, it might make it easier to write (and read) your code.

The example below declares 3 constants that can be used to control the direction of the servo rotation if you are using the servo.writeMicroseconds() function. (If necessary, you can change the names or values of these constants based on what you need your device to do.)

// global variables (constants) to represent direction of servo rotation
const int COUNTER_CLOCKWISE = 1000;
const int STOPPED = 1500;
const int CLOCKWISE = 2000;

If you were to declare these constant values as part of your global variables, then your commands to control your motor would be:

servo.writeMicroseconds(COUNTER_CLOCKWISE);

servo.writeMicroseconds(STOPPED);

servo.writeMicroseconds(CLOCKWISE);

You could even create global variable constants for that represent different speeds of rotation (CLOCKWISE_SLOW, CLOCKWISE_FAST, etc.).

If you are using the servo.write() function instead, you would change the values of the constants (so the values are between 0-180).

Adjust Servo Motor Stop Point

You may need to adjust the stop point for your continuous rotation servo motor. Normally, using servo.write(90); or servo.writeMicroseconds(1500); should cause the motor to stop rotating (and not vibrate). However, it's possible your servo motor still might be slowly rotating or vibrating at these values.

If necessary, you can adjust the stop point by:

  • manually turning an adjustment screw on the motor

  • adjusting values in your code

Either way, you first need a simple app that turns on your servo motor using servo.attach() and instructs the motor to not rotate using either a servo.write(90); or servo.writeMicroseconds(1500); statement.

// if necessary, change data pin number to match your wiring
int servoPin = D0;

// declare Servo object variable called "servo"
Servo servo;

void setup() {
    // turn on servo motor
    servo.attach(servoPin);
}

void loop() {
    // stop rotation
    servo.writeMicroseconds(1500);

    // alternate code (use either one but not both)
    // servo.write(90);
}

OPTION 1: ADJUST MANUALLY

The continuous rotation servo motor has a built-in trimpot screw inset on one side (next to its wires). You can use a small screwdriver to turn this screw slightly clockwise or counterclockwise until your motor stops rotating (and does not vibrate) when it is running a servo.write(90); or servo.writeMicroseconds(1500); statement.

OPTION 2: ADJUST USING CODE

Another option is to try slightly different values in your code to see which value causes the servo motor to actually stop rotating.

If you are using the servo.write() function to control your motor, you can set a trim value, so that your motor will actually be stopped whenever you use a servo.write(90) statement. The trim value can be positive or negative – try different values to see what works.

// adjust trim (value can be positive or negative)
servo.setTrim(5);

// adjust trim until motor completely stops
servo.write(90);

If you are using the servo.writeMicroseconds() function to control your motor, then you can change the value from 1500 to something slightly higher or lower until your motor completely stops.

// adjust value until motor completely stops
servo.writeMicroseconds(1500);

Last updated