Continuous Rotation Servo Motor
Last updated
Last updated
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.
Servo Motor | Photon Pin |
White - Data | any I/O pin with PWM |
Red - Power (5V) | V-USB (5V) |
Black - Ground | GND |
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):
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.
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).
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).
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.
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).
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.
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.
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.
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.
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.
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.
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.
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.)
If you were to declare these constant values as part of your global variables, then your commands to control your motor would be:
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).
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.
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.
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.
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.