The Arduino Inventor's Guide (30 page)

BOOK: The Arduino Inventor's Guide
2.45Mb size Format: txt, pdf, ePub

The library allows you to create a type of data structure called an
object
. An object is simply a container for variables and functions that are predefined. Functions that are associated with the object are referred to as
methods
. In this sketch, the line
Servo myServo;
creates a new
Servo
object named
myServo

.

You can give an object any name you like, but we recommend using a descriptive name, like
myServo
, so it’s recognizable. Now you can use that name to reference all the servo commands that are available to you in the Servo library. For example, the method
myServo.attach()
tells the Arduino which pin the servo is attached to. If you had multiple servos, each one would get a unique name so that you could control all of them independently.

As an example, think of a robot arm that moves at the shoulder, elbow, and wrist, using a servo for each joint. The code for it would create three
Servo
objects named
shoulderServo
,
elbowServo
, and
wristServo
so that you could position each one accurately and at a different orientation from the others. Each one of those
Servo
objects would have its own set of methods that you could use separately.

For the Balance Beam, you’ll use only one servo. The setup of the sketch tells the Arduino that you have a servo attached to pin 9 with the method
myServo.attach(9)

. It then tells the Arduino to move the servo to a position of 90 degrees via the method
myServo.write(90)

. The Servo library converts the angle in degrees of rotation to the appropriate pulse width behind the scenes. This is built into the
write()
method.

Now, plug the black wire of your servo into ground and upload your code to the Arduino, and the servo will rotate to 90 degrees. It’s safe for now to leave your servo wired up.

NOTE

Although the servo’s full range of motion is 180 degrees, we recommend keeping the
write()
value between 10 and 170 degrees, especially for servos with plastic gears. Overextending a servo’s range can do irreparable damage.

To move the servo again, just pass another number within the bounds of the servo’s range of motion (10–170) to the
write()
method and upload the sketch again. Play with your servo for a bit, passing in different values.

Okay, so you know how to get the servo to move just once. Now, here’s some code that really gets it moving.
Listing 6-2
moves the control of the servo into a loop and repeats a motion.

LISTING 6-2:
Servo blink sketch

#include
<
Servo
.h>
Servo
myServo;
void
setup
()
{
  myServo.
attach
(9);
}
void
loop
()
{
  myServo.
write
(10);
  
delay
(1000);
  myServo.
write
(170);
  
delay
(1000);
}

This piece of code is a servo version of the blink sketch from
Project 1
. The servo moves to 10 degrees, waits for 1 second, moves to 170 degrees, waits for 1 second, and then repeats. We fondly refer to this as “robot march,” because when you have 20+ people doing it at once, it sounds like a robot army marching to take over the world.

Wow! You’re on a roll here. But servos really become interesting when you can control the servo yourself, without having to reprogram it each time. It’s time to get the potentiometer involved.

Complete the Balance Beam Sketch

For the final sketch, you’ll program the potentiometer to control the rotation of the servo. Modify your sketch as shown in
Listing 6-3
:

LISTING 6-3:
Using the
map()
function to control a servo with a potentiometer

  
#include
<
Servo
.h>
  
Servo
myServo;

int
potVal;
  
int
anglePosition;
  
void
setup
()
  {
    myServo.
attach
(9);
  }
  
void
loop
()
  {
    potVal =
analogRead
(A0);

   anglePosition =
map
(potVal, 0, 1023, 10, 170);
    myServo.
write
(anglePosition);
    
delay
(20);
}

This sketch reads the value of the potentiometer, translates it into an angle value, and then writes that value to the servo. There are some new commands in here, so we’ll go over it step-by-step.

The top portion of this code looks just like the first two example listings. It includes the Servo library and creates a
Servo
object named
myServo
. It also declares two global variables

named
potVal
and
anglePosition
. These variables will be used to store the raw value of the potentiometer and a calculated angle position for the servo, respectively.

In the
loop()
function, the variable
potVal
stores the raw analog-to-digital converter value from the
analogRead(A0)
function. As you turn the knob on the potentiometer, the voltage on the wiper pin will vary between 0 V and 5 V. Remember that
analogRead()
will convert a voltage from 0 V to 5 V to a number between 0 and 1,023. However, the values 0 to 1,023 aren’t very useful for controlling the servo. As we mentioned before, the servo needs to stay between 10 and 170 degrees.

Thankfully, Arduino has a built-in
map()
function that allows you to take one range of numbers and find the equivalent value in a different range. The variable
anglePosition
stores an angle position that is calculated from
potVal
using the
map()
function

. The
map()
function uses five parameters:
map(input, fromLow, fromHigh, toLow, toHigh)
. In this example, it maps the value of
potVal
from the range of 0 to 1,023 to a new range of 10 to 170. This is a really nifty function in Arduino that makes scaling and translating between value ranges super easy!

The sketch also adds a short delay of 20 ms to give the servo enough time to move before it reads the potentiometer again. A 20 ms delay is the minimum delay that the servo needs. You may also recall that it’s the time period of the PWM signal that’s used to control the angle.

Once you have this sketch updated, upload it to your Arduino. Now when you turn the potentiometer, the servo moves with it. Pretty sweet! Next you’ll take your newfound superpower and build a balancing game out of it.

BUILD THE BALANCE BEAM

With this cool way to control a servo, we thought it would be fun to create a desktop game. You’ll create a balance beam that you control using the potentiometer and servo. A ping-pong ball will roll on the balance beam, and your goal is to get the ball as close as possible to the ends of the beam without it falling off.

Cut Out the Parts

Download the template provided at
https://www.nostarch.com/arduinoinventor/
(shown in
Figure 6-16
), print it out, and then trace it onto your cardboard. We designed this project to fit on as small a piece of cardboard as we could.

FIGURE 6-16:
Balance Beam frame template (not full size)

Using a craft knife, cut all the solid lines along the perimeter of each shape, as well as the cut-out for the motor mount. Don’t score any of the pieces just yet; you’ll do that as you go along. Remember to exercise safety when cutting. Use a metal ruler and a sharp craft knife, as shown in
Figure 6-17
, and take your time. Use a drill or a craft knife to make the six different holes in this design. If you’re using a drill, you’ll need a 1/4-inch drill bit for the screwdriver access hole, a 1/8-inch drill bit for the axle holes, and a 1/16-inch drill bit for the armature mount hole and the two motor mount holes.

FIGURE 6-17:
Cutting out the frame pieces from the template

Once you’ve finished cutting, you should have six pieces like those shown in
Figure 6-18
.

FIGURE 6-18:
All cardboard parts cut out

Build the Beam

Take the longest piece, which will be the actual beam, and carefully score the dotted line that runs along its length. This will allow you to curve the beam so that it cradles the ball. We designed the template so that the beam is 11 inches long, the length of a standard sheet of 8.5 × 11-inch paper.

Next, prepare the armature mount. This is a small trapezoidal piece about 2 1/4 inches wide by 1 inch tall. You will use this piece to connect the servo motor to the beam. Score it and bend it into a right angle, as shown in
Figure 6-19
.

FIGURE 6-19:
Preparing the armature mount

Next, cut down the drinking straw so that it’s 1 3/4 inches long, and glue it down along the center line of the beam, as shown in
Figure 6-20
.

FIGURE 6-20:
Gluing down the straw at the midpoint of the beam

Other books

You're Next by Gregg Hurwitz
The Prestige by Priest, Christopher
The Awakening by Montgomery, Elizabeth
Babylon by Camilla Ceder
Indigo Blue by Catherine Anderson
One Shot Too Many by Nikki Winter
Broken Wings by Weis, Alexandrea
Absence of Faith by Anthony S. Policastro
Trainspotting by Irvine Welsh