Servo Motor

The servo motor included in your Photon kit can rotate back or forth to any position between 0° and ~180° and hold its position. (In reality, this servo motor only physically rotates to about 160°, even if it is told to rotate to 180°.)

However, this type of servo motor is different from other motors that rotate continuously, like a motor used in a fan or an engine. If your device needs continuous rotation, then you need another type of motor, such as a gear motor or a continuous rotation servo motor.

The servo motor comes with 4 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 is a single-arm horn, a double-arm horn, a four-point horn, and a circular horn. 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 small screws.

The 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: The 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). Later, once you test out your code to rotate the servo motor, you may need to remove and re-position the horn, so it's lined up where you want it to be. The easiest way to do this is to rotate the servo motor to 0° and then remove and re-position the horn how you want it to be pointed when it is at this angle.

Experiment 7 of the online SparkFun Photon Experiment Guide shows how to connect the 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;

You may also want to declare a global variable to represent the current position (in degrees) of the servo motor. This isn't required, but it could make it easier to code the servo motor, especially if you create a custom function to rotate the motor. The example below declares a variable called "angle" (but you could use a different variable name).

// global variable to represent servo position (0-180 degrees)
int angle;

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, you may want to rotate your servo motor to a particular starting position when your device first starts. If so, then include this code in the setup() function.

Rotate Servo Motor to Specific Angle

Code for rotating the servo motor to a specific angle can be placed within the setup() function (only runs once), within the loop() function, or within a custom function.

Rotating the servo motor always takes four steps: (1) turn on the motor, (2) rotate the motor, (3) wait for a small time delay, and (4) turn off the motor.

1. Turn On Motor

Every time you want to rotate the servo motor, you first have to call a special function called servo.attach() to turn on the motor.

2. Rotate Motor

Then you call a function called servo.write() to rotate the servo motor to any angle from 0-180. For example, use servo.write(90); to rotate the servo to the 90° position.

3. Wait for Time Delay

You have to include a small time delay() before you turn off the motor. Otherwise, the servo motor might get turned off before it finishes rotating (because computer code runs much faster than the motor can physically rotate).

If you are rotating the motor by 180° (from 0° to 180° or from 180° to 0°), then delay(500); (0.5 seconds) should be sufficient.

If you are rotating the motor by 90°, then delay(250); should be sufficient.

If you are rotating the motor by only 1° at a time, then the delay can be just 15 milliseconds per degree: delay(15);

4. Turn Off Motor

After rotating the servo motor, you should call a function called servo.detach() to turn off the motor. Otherwise, the motor will be "jittery" as it tries to hold its position. After you turn off the motor, you may notice that it "debounces" (rotates backward slightly). This is normal.

Here's code that shows all 4 steps combined:

// set the angle to any value between 0-180
angle = 180;

servo.attach(servoPin);
servo.write(angle);
// slight delay to give servo time to rotate before detach
delay(500);
servo.detach();

REMINDER: Once you've got your servo motor working, you may need to remove and re-position the horn, so it's lined up where you want it to be for your device. The easiest way to do this is to rotate the servo motor to 0° and then remove and re-position the horn how you want it to be pointed when it is at this angle.

IMPORTANT: You will notice that this servo motor can only physically rotate to about 160°, even if the code tells it to rotate to 180°. This is a minor limitation of this particular servo motor. You may need to try out different rotation angles in your code to make your device work the way you need it to.

Use Custom Function to Rotate Servo Motor to Specific Angle

It may be simpler to include a custom function in your Photon app that will rotate the servo motor to the current value of the angle variable. This will allow you to change the value of angle and then rotate the motor, without having to add code for the 4 steps (attach, write, delay, detach) every time you need to change the servo position.

Here's an example that shows the loop() function calling a custom function called moveServo(). This example simply rotates the servo motor back and forth between 0° and 180° every 5 seconds. (This extra 5-second delay between rotations is not necessary for your app.)

void loop() {
    angle = 0;
    moveServo();
    delay(5000); // wait 5 seconds before next rotation

    angle = 180;
    moveServo();
    delay(5000); // wait 5 seconds before next rotation
}

void moveServo() {
    servo.attach(servoPin);
    servo.write(angle);
    delay(500);
    servo.detach();
}

Last updated