# 4.0 Introduction

One of the many fun things about embedded computers is that you can move physical things with motors. But there are so many different kinds of motors (servo, stepper, DC), so how do you select the right one?

The type of motor you use depends on the type of motion you want:

R/C or hobby servo motor

Can be quickly positioned at various absolute angles, but some donât spin. In fact, many can turn only about 180Â°.

Stepper motor

Spins and can also rotate in precise relative angles, such as turning 45Â°. Stepper motors come in two types: bipolar (which has four wires) and unipolar (which has five or six wires).

DC motor

Spins either clockwise or counter-clockwise and can have the greatest speed of the three. But a DC motor canât easily be made to turn to a given angle.

When you know which type of motor to use, interfacing is easy. This chapter shows how to interface with each of these motors.

###### Note

Motors come in many sizes and types. This chapter presents some of the more popular types and shows how they can interface easily to the Bone. If you need to turn on and off a 120 V motor, consider using something like the PowerSwitch presented in Recipe 3.3.

###### Note

The Bone has built-in 3.3 V and 5 V supplies, which can supply enough current to drive some small motors. Many motors, however, draw enough current that an external power supply is needed. Therefore, an external 5 V power supply is listed as optional in many of the recipes.

# 4.1 Controlling a Servo Motor

## Problem

You want to use BeagleBone to control the absolute position of a servo motor.

## Solution

Weâll use the pulse width modulation (PWM) hardware of the Bone and control a servo motor with the `analogWrite()` function.

To make the recipe, you will need:

The 1 kâ¦ resistor isnât required, but it provides some protection to the general-purpose input/output (GPIO) pin in case the servo fails and draws a large current.

Wire up your servo, as shown in FigureÂ 4-1.

###### Note

There is no standard for how servo motor wires are colored. One of my servos is wired like FigureÂ 4-1: red is 3.3 V, black is ground, and yellow is the control line. I have another servo that has red as 3.3 V and ground is brown, with the control line being orange. Generally, though, the 3.3 V is in the middle. Check the datasheet for your servo before wiring.

The code for controlling the servo motor is in servoMotor.js, shown in ExampleÂ 4-1.

##### Example 4-1. Code for driving a servo motor (servoMotor.js)
```#!/usr/bin/env node

// Drive a simple servo motor back and forth

var b = require('bonescript');

var motor = 'P9_21', // Pin to control servo
freq = 50,  // Servo frequency (20 ms)
min  = 0.8, // Smallest angle (in ms)
max  = 2.5, // Largest angle (in ms)
ms  = 250,  // How often to change position, in ms
pos = 1.5,  // Current position, about middle
step = 0.1; // Step size to next position

console.log('Hit ^C to stop');
b.pinMode(motor, b.ANALOG_OUTPUT, 6, 0, 0, doInterval);

function doInterval(x) {
if(x.err) {
console.log('x.err = ' + x.err);
return;
}
timer = setInterval(sweep, ms);
}

move(pos);      // Start in the middle

// Sweep from min to max position and back again
function sweep() {
pos += step;    // Take a step
if(pos > max || pos < min) {
step *= -1;
}
move(pos);
}

function move(pos) {
var dutyCycle = pos/1000*freq;
b.analogWrite(motor, dutyCycle, freq);
console.log('pos = ' + pos + ' duty cycle = ' + dutyCycle);
}

process.on('SIGINT', function() {
console.log('Got SIGINT, turning motor off');
clearInterval(timer);             // Stop the timer
b.analogWrite(motor, 0, freq);    // Turn motor off
});```

Running the code causes the motor to move back and forth, progressing to successive positions between the two extremes. You will need to press ^C (Ctrl-C) to stop the script.

## Discussion

Servo motors are often used in radio-controlled airplanes or cars. They generally donât spin, but rather turn only 180Â°, just enough to control an elevator on a wing or steer wheels on a car.

The servo is controlled by a PWM signal, which is controlled by the `analogWrite()` function, which sends a pulse 50 times each second (50 Hz or every 20 ms). The width of the pulse determines the position of the motor. A short pulse (1 ms, for example) sends the motor angle to zero degrees. A long pulse (2 ms, for example) sets the angle to 180 degrees.

The code in ExampleÂ 4-1 defines a `move()` function, which moves the motor to a different angle every time it is called. The `setInterval()` function schedules `sweep()` to be called every quarter second (250 ms) to step the servo to a new position.

At the end of the code, the `process.on()` function detects when the user has pressed ^C (Ctrl-C), stops the timer, and turns off the motor. If you donât turn off the motor, it will keep buzzing, even if it isnât moving.

Not all GPIO pins support the PWM hardware; Recipe 3.4 discusses which pins you can use.

###### Note

If your servo motor needs to run off 5 V, wire it as shown in FigureÂ 4-2. The banded wire attaches the Boneâs 5 V power supply (`P9_7`) to the power supply on the servo. We are still controlling it with a 3.3 V signal.

Here, we move the banded power wire from the 3.3 V power supply to the Boneâs 5 V power supply on pin `P9_7`. If the Boneâs built-in 5 V doesnât supply enough current, or if you need a higher voltage, connect your servoâs power supply wire to an external power supply.

Of the motors presented in this chapter, the servo motor is the easiest to drive, because the control line on the servo doesnât require much current and therefore doesnât require additional components.

# 4.2 Controlling the Speed of a DC Motor

## Problem

You have a DC motor (or a solenoid) and want a simple way to control its speed, but not the direction.

## Solution

It would be nice if you could just wire the DC motor to BeagleBone Black and have it work, but it wonât. Most motors require more current than the GPIO ports on the Bone can supply. Our solution is to use a transistor to control the current to the bone.

Hereâs what you will need:

If you are using a larger motor (more current), you will need to use a larger transistor.

Use the code in ExampleÂ 4-2 (dcMotor.js) to run the motor.

##### Example 4-2. Driving a DC motor in one direction (dcMotor.js)
```#!/usr/bin/env node

// This is an example of driving a DC motor

var b = require('bonescript');

var motor = 'P9_16',// Pin to drive transistor
min = 0.05,     // Slowest speed (duty cycle)
max = 1,        // Fastest (always on)
ms = 100,       // How often to change speed, in ms
speed = 0.5,    // Current speed;
step = 0.05;    // Change in speed

b.pinMode(motor, b.ANALOG_OUTPUT, 6, 0, 0, doInterval);

function doInterval(x) {
if(x.err) {
console.log('x.err = ' + x.err);
return;
}
var timer = setInterval(sweep, ms);
}

function sweep() {
speed += step;
if(speed > max || speed < min) {
step *= -1;
}
b.analogWrite(motor, speed);
console.log('speed = ' + speed);
}

process.on('SIGINT', function() {
console.log('Got SIGINT, turning motor off');
clearInterval(timer);       // Stop the timer
b.analogWrite(motor, 0);    // Turn motor off
});```

## Discussion

This is actually the same code that you used to drive the servo motor (Recipe 4.1). The only difference is how the parameters are set. We are now using the PWM hardware to control the speed of the motor rather than the position. If the duty cycle is `1`, the voltage to the motor is on all the time, and it runs at its fastest. If the duty cycle is `0.5`, the voltage is on half the time, so the motor runs slower. A duty cycle of `0` stops the motor.

You can use this same setup to drive a solenoid. After all, a solenoid is a DC motor that goes back and forth rather than spinning. Generally, you would drive a solenoid with an on or off signal, as opposed to using a PWM signal.

At the end of the code, the `process.on()` function detects when the user has pressed ^C (Ctrl-C), stops the timer, and turns off the motor. If you donât turn off the motor, it will continue to spin.

How do you change the direction of the motor? See Recipe 4.3.

# 4.3 Controlling the Speed and Direction of a DC Motor

## Problem

You would like your DC motor to go forward and backward.

## Solution

Use an H-bridge to switch the terminals on the motor so that it will run both backward and forward. Weâll use the L293D: a common, single-chip H-bridge.

Hereâs what you will need:

Lay out your breadboard as shown in FigureÂ 4-4. Ensure that the L293D is positioned correctly. There is a notch on one end that should be pointed up.

The code in ExampleÂ 4-3 (h-bridgeMotor.js) looks much like the code for driving the DC motor with a transistor (ExampleÂ 4-2). The additional code specifies which direction to spin the motor.

##### Example 4-3. Code for driving a DC motor with an H-bridge (h-bridgeMotor.js)
```#!/usr/bin/env node

// This example uses an H-bridge to drive a DC motor in two directions

var b = require('bonescript');

var enable = 'P9_21';    // Pin to use for PWM speed control
in1    = 'P9_15',
in2    = 'P9_16',
step = 0.05,    // Change in speed
min  = 0.05,    // Min duty cycle
max  = 1.0,     // Max duty cycle
ms   = 100,     // Update time, in ms
speed = min;    // Current speed;

b.pinMode(enable, b.ANALOG_OUTPUT, 6, 0, 0, doInterval);
b.pinMode(in1, b.OUTPUT);
b.pinMode(in2, b.OUTPUT);

function doInterval(x) {
if(x.err) {
console.log('x.err = ' + x.err);
return;
}
timer = setInterval(sweep, ms);
}

clockwise();        // Start by going clockwise

function sweep() {
speed += step;
if(speed > max || speed < min) {
step *= -1;
step>0 ? clockwise() : counterClockwise();
}
b.analogWrite(enable, speed);
console.log('speed = ' + speed);
}

function clockwise() {
b.digitalWrite(in1, b.HIGH);
b.digitalWrite(in2, b.LOW);
}

function counterClockwise() {
b.digitalWrite(in1, b.LOW);
b.digitalWrite(in2, b.HIGH);
}

process.on('SIGINT', function() {
console.log('Got SIGINT, turning motor off');
clearInterval(timer);         // Stop the timer
b.analogWrite(enable, 0);     // Turn motor off
});```

## Discussion

The H-bridge provides a simple way to switch the leads on a motor so that it will reverse directions. FigureÂ 4-5 shows how an H-bridge works.

The four switches connected to the motor (the big M in the center of FigureÂ 4-5) are the H-bridge. In the left diagram, two switches are closed, connecting the left terminal of the motor to the plus voltage and the right terminal to the ground. This makes the motor rotate in one direction. The diagram on the right shows the other two switches closed, and the plus and grounds are connected to the opposite terminals, making the motor spin the other way.

In the code, `in1` and `in2` are used to control each pair of switches. (The L293D has four sets of these switches, but we are using only two pairs.) So, to turn clockwise, set `in1` `HIGH` and `in2` `LOW`. To go counter-clockwise, set them the opposite way:

```function clockwise() {
b.digitalWrite(in1, b.HIGH);
b.digitalWrite(in2, b.LOW);
}

function counterClockwise() {
b.digitalWrite(in1, b.LOW);
b.digitalWrite(in2, b.HIGH);
}```

The L293D also has an enable pin (pin 9, on the lower right), which is used to control the speed of the motor by using a PWM signal. (See Recipe 4.2 for details on how this works.)

At the end of the code, the `process.on()` function at the end of the code detects when the user has pressed ^C (Ctrl-C), stops the timer, and turns off the motor. If you donât turn off the motor, it will continue to spin.

###### Note

The previous example uses a motor that works with 3.3 V. What if you have a 5 V motor? The banded wire (running from `P9_7` to pin 8 of the L293D) in FigureÂ 4-6 attaches the L293D to the Boneâs 5 V power supply. This will work if your motor doesnât draw too much current.

If 5 V isnât enough voltage, or if the Bone canât supply the current needed, FigureÂ 4-7 shows how to use an external power supply.

The H-bridge provides an easy way to reverse the direction of a DC motor, and attaching the enable to a PWM signal allows you to control the speed.

# 4.4 Driving a Bipolar Stepper Motor

## Problem

You want to drive a stepper motor that has four wires.

## Solution

Use an L293D H-bridge. The bipolar stepper motor requires us to reverse the coils, so we need to use an H-bridge.

Hereâs what you will need:

Wire as shown in FigureÂ 4-8.

Use the code in ExampleÂ 4-4 (bipolarStepperMotor.js) to drive the motor.

##### Example 4-4. Driving a bipolar stepper motor (bipolarStepperMotor.js)
```#!/usr/bin/env node
var b = require('bonescript');

// Motor is attached here
var controller = ["P9_11", "P9_13", "P9_15", "P9_17"];
var states = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]];
var statesHiTorque = [[1,1,0,0], [0,1,1,0], [0,0,1,1], [1,0,0,1]];
var statesHalfStep = [[1,0,0,0], [1,1,0,0], [0,1,0,0], [0,1,1,0],
[0,0,1,0], [0,0,1,1], [0,0,0,1], [1,0,0,1]];

var curState = 0;   // Current state
var ms = 100,       // Time between steps, in ms
max = 22,       // Number of steps to turn before turning around
min = 0;        // Minimum step to turn back around on

var CW  =  1,       // Clockwise
CCW = -1,
pos = 0,        // current position and direction
direction = CW;

// Initialize motor control pins to be OUTPUTs
var i;
for(i=0; i<controller.length; i++) {
b.pinMode(controller[i], b.OUTPUT);
}

// Put the motor into a known state
rotate(direction);

var timer = setInterval(move, ms);

// Rotate back and forth once
function move() {
pos += direction;
console.log("pos: " + pos);
// Switch directions if at end.
if (pos >= max || pos <= min) {
direction *= -1;
}
rotate(direction);
}

// This is the general rotate
function rotate(direction) {
// console.log("rotate(%d)", direction);
// Rotate the state acording to the direction of rotation
curState +=  direction;
if(curState >= states.length) {
curState = 0;
} else if(curState<0) {
curState = states.length-1;
}
}

// Write the current input state to the controller
console.log("state: " + state);
for (i=0; i<controller.length; i++) {
b.digitalWrite(controller[i], state[i]);
}
}

process.on('exit', function() {
});```

When you run the code, the stepper motor will rotate back and forth.

## Discussion

Stepper motors are designed to rotate in discrete steps. They operate by turning on one coil (coil 1, for example) in one direction, then turning off coil 1 and turning on coil 2, then turning on 1 in the reverse direction, then 2 in reverse, and then back to 1 forward, as shown in FigureÂ 4-9.

In ExampleÂ 4-4 (bipolarStepperMotor.js), the `states` variable is an array of the four different states listed in the previous paragraph. That is, `[1,0,0,0]` instructs to turn on coil 1 in the forward direction. After itâs been on for a while, you move to the next state, `[0,1,0,0]`. This turns off coil 1 and turns on coil 2. Then you go to `[0,0,1,0]`, which turns on coil 1 in reverse, and so on. The H-bridge (see Recipe 4.3) takes care of reversing the coil:

`var states = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]];`

Whenever you step, you just index the next element in the array. If you want to go backward, index the previous element.

There are two other state sequences given in the code, but they arenât ever used. `statesHiTorque` is like the original `states`, except that it has both magnets on at the same time, giving a stronger pull on the motor. The `statesHalfStep` alternates between having one and two coils on simultaneously to give finer control in the step size:

```var statesHiTorque = [[1,1,0,0], [0,1,1,0], [0,0,1,1], [1,0,0,1]];
var statesHalfStep = [[1,0,0,0], [1,1,0,0], [0,1,0,0], [0,1,1,0],
[0,0,1,0], [0,0,1,1], [0,0,0,1], [1,0,0,1]];```

You can easily try either of these by assigning them to the `states` variable.

Notice the banded wire running from pin 8 (lower left) of the L293D to `P9_7` in FigureÂ 4-8. This is connecting the 5 V power supply on the Bone to the L293D. The Bone outputs 3.3 V on its GPIO pins, but the stepper motor I am using really needs 5 V. Connecting the 5 V in this way provides 5 V out of the L293D to the stepper motor.

###### Note

If your stepper motor requires a higher voltage (up to 12 V), you can wire an external power supply, as shown in FigureÂ 4-10.

The stepper motor requires a more complex setup than the servo motor, but it has the advantage of being able to spin, which the servo canât do.

# 4.5 Driving a Unipolar Stepper Motor

## Problem

You want to drive a stepper motor that has five or six wires.

## Solution

If your stepper motor has five or six wires, itâs a unipolar stepper and is wired differently than the bipolar. Here, weâll use a ULN2003 Darlington Transistor Array IC to drive the motor.

Hereâs what you will need:

Wire, as shown in FigureÂ 4-11.

###### Note

The IC in FigureÂ 4-11 is illustrated upside down from the way it is usually displayed. That is, the notch for pin 1 is on the bottom. This made drawing the diagram much cleaner.

Also, notice the banded wire running the `P9_7` (5 V) to the UL2003A. The stepper motor Iâm using runs better at 5 V, so Iâm using the Boneâs 5 V power supply. The signal coming from the GPIO pins is 3.3 V, but the U2003A will step them up to 5 V to drive the motor.

The code for driving the motor is in unipolarStepperMotor.js; however, it is almost identical to the bipolar stepper code (ExampleÂ 4-4), so ExampleÂ 4-5 shows only the lines that you need to change.

##### Example 4-5. Changes to bipolar code to drive a unipolar stepper motor (unipolarStepperMotor.diff)
```var controller = ["P9_11", "P9_13", "P9_15", "P9_17"];
var states = [[1,1,0,0], [0,1,1,0], [0,0,1,1], [1,0,0,1]];
var curState = 0;   // Current state
var ms = 100,       // Time between steps, in ms
max = 22,       // Number of steps to turn before turning around```

The code in this example makes the following changes:

• `controller` is attached to the even-numbered pins on the `P9` header rather than the odd that the bipolar stepper used. (Doing this allows you to run both types of stepper motors at the same time!)

• The `states` are different. Here, we have two pins high at a time.

• The time between steps (`ms`) is shorter, and the number of steps per direction (`max`) is bigger. The unipolar stepper Iâm using has many more steps per rotation, so I need more steps to make it go around.

## Discussion

FigureÂ 4-12 shows how the unipolar stepper motor is wired a bit differently than the bipolar.

Each coil is split, so you can access the two sides separately. The difference between the five- and six-wire steppers is that the five-wire steppers have the two power lines connected to each other. The different wiring means a different energizing sequence, as seen in the different `states` array.

###### Note

If your stepper requires more voltage, or more current than what the Bone can supply, you can replace the banded wire with an external power supply, similar to the bipolar stepper example (FigureÂ 4-10).

Get BeagleBone Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.