Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Next, you'll code an app to make your robot turn 90° right. Then you'll modify the app so the robot turns 90° left and turns 180° around.
In your Arduino code editor, use the "Save As" command to save a copy of your existing driving_test
app as a different app named: pivot_test
If necessary, here are instructions for how to save a copy of an app with a new name.
Once you saved the new app name, modify the block comment near the beginning of the app code to change Driving Test
to Pivot Test
.
The most common types of turns needed for robot navigation are: turn 90° right, turn 90° left, and turn 180° around.
The RedBotMotors
class defines a method named pivot()
that can be used to turn the robot either clockwise or counter-counterclockwise. The pivot()
method turns the robot by driving both motors in opposite directions.
There are other ways to turn your robot, but the pivot()
method results in a perfectly tight turn because the robot's axis of rotation is centered between its wheels. Pivoting is the best way to turn the robot when space is limited (as it will be in your robot demonstration environment).
When the motors.pivot()
method is used in your code, the motors will start and will keep pivoting continuously. You'll use a delay()
statement to allow the motors to pivot for a certain amount of time before turning the motors off with the motors.brake()
method.
First, modify the "Press to Start" code within the if
statement in the loop()
function to remove the existing code statements that make the robot drive forward and then backward.
Next, you'll add new code so that when the robot's button is pressed, the robot will drive forward for 1.5 seconds (about 2 feet), turn 90° right, and then drive forward for another 1.5 seconds. Add this new code within the if
statement in the loop()
function (after the noTone()
statement):
The motors.pivot()
method requires one parameter inside its parentheses:
The motor power, which can be any integer (whole number) between -255
and 255
. A positive power pivots the robot clockwise (to the right), and a negative power pivots the robot counter-clockwise (to the left). A larger absolute power produces a faster pivot speed (-255
and 255
are the fastest speeds, while -1
and 1
are the slowest speeds). In this case, the power will be 100
.
PIVOT SLOWLY: Pivot the robot at a lower motor power to avoid wheel slippage. In general, try using a power of 100 for pivoting, depending on the surface.
The second delay()
of 650
milliseconds (0.65 seconds) is an estimate of how much time it will take your robot to pivot 90 degrees. You may have to change this value after testing your robot.
Follow the steps to upload the app to your robot:
Connect Robot to Computer
Turn on Robot Power
Select Correct Board and Port
Upload App to Robot
Unplug the USB cable from the robot, and place the robot on the floor. Be sure an area of about 3 feet square in front and to the right of the robot is clear of any obstacles.
Press the D12 button on your robot's circuit board. Your robot should beep and then drive forward for 1.5 seconds (about 22 inches). Then the robot should pivot 90° right, and then drive forward for another 1.5 seconds (about 22 inches).
Test out your robot's app several times to see how close the pivot is to a 90° right turn.
In the app code, the second delay()
of 650
milliseconds (0.65 seconds) is an estimate of how much time it will take your robot to pivot 90 degrees. You may have to change this value based on your testing:
If your robot is pivoting less than 90°, increase the pivot delay()
time slightly (such as: 700
ms).
If your robot is pivoting more than 90°, decrease the pivot delay()
time slightly (such as: 600
ms).
If you do change the pivot delay()
time, upload the modified app to your robot, and test it again with the new value. You may need to change the value several times to fine-tune your results.
Later in this tutorial, you'll learn how to use the wheel encoders to measure how far the wheels have turned, in order to make the robot pivot by a specific angle.
Next, you'll modify the app code so your robot will pivot 90° left. To do this, you simply need to make the robot pivot counter-clockwise by using a negative motor power.
Modify the motors.pivot()
statement so the motor power is -100
(instead of positive).
You don't need to change the pivot delay()
time because the amount of time to pivot 90 degrees should be the same whether the robot is pivoting clockwise (to the right) or counter-clockwise (to the left).
Upload the modified app to your robot.
Unplug the USB cable from the robot, and place the robot on the floor. Be sure an area of about 3 feet square in front and to the left of the robot is clear of any obstacles.
Press the D12 button on your robot's circuit board. Your robot should beep and then drive forward for 1.5 seconds (about 22 inches). Then the robot should pivot 90° left, and then drive forward for another 1.5 seconds (about 22 inches).
Test out your robot's app several times to see how close the pivot is to a 90° left turn.
Next, you'll modify the app code so your robot will pivot 180° to turn around. To do this, you simply need to allow the robot to pivot for twice the amount of time as a 90° pivot.
For a 180° turn, it doesn't matter if the robot pivots clockwise or counter-clockwise. So you can either leave the motor power in the motors.pivot()
statement as -100
(counter-clockwise) — or you can change the power back to 100
(clockwise).
Modify the pivot delay()
time so its value is twice the amount that was needed for a 90° turn. For example, if the time required for a 90° turn was 650
milliseconds, try 1300
ms for a 180° turn.
Upload the modified app to your robot.
Unplug the USB cable from the robot, and place the robot on the floor. Be sure a path of about 3 feet in front of the robot is clear of any obstacles.
Press the D12 button on your robot's circuit board. Your robot should beep and then drive forward for 1.5 seconds (about 22 inches). Then the robot should pivot 180° around, and then drive forward for another 1.5 seconds (about 22 inches), returning approximately to its starting point.
Test out your robot's app several times to see how close the pivot is to a 180° turn. You may have to adjust the pivot delay()
time in the app code, and re-upload the app to test again.
Next, you'll code an app to test your robot's wheel encoders by sending serial data to your computer.
Located directly behind each motor is a wheel encoder, which is a sensor that can count exactly how many times the motor has rotated. These left and right wheel encoder counts can be used to:
make the robot drive in a straight line (by adjusting the motor powers if one motor happens to be rotating slightly faster than the other)
calculate how far the robot has driven (by determining how many times the wheel has rotated and multiplying that by the wheel circumference)
The wheel encoder actually consists of two parts:
a Hall Effect sensor that can measure the strength of a magnetic field
a ring magnet (looks like a metal washer) attached to the motor shaft
When the motor rotates the wheel, it also rotates the ring magnet. The Hall effect sensor positioned near the ring detects changes in the magnetic field (these are referred to as "ticks") as the ring rotates. This is how the wheel encoder can count how many times the motor has rotated.
In order to function accurately, each wheel encoder sensor must be positioned correctly, relative to its ring magnet. The sensor tip must be centered within the silver band of the ring magnet (not too far inward or outward) and must be close to the ring magnet's surface (about ⅛" inch away).
Visually check the alignment of the left and right wheel encoders. If necessary, you might need to push (or pull) the sensor to position it correctly.
Open your Arduino code editor, and create a new app template.
Add a block comment at the beginning of the app code to identify your new app:
Rename the the new app as: wheel_encoder_test
If you need a reminder, here are instructions for how to rename an app.
Follow the steps to include the SparkFun RedBot Library in your app. (You don't need to add the library to your code editor again — just include the library in this new app.)
There are three classes defined in the RedBot library that you'll use in this app:
RedBotMotors
class — used to control the left and right motors
RedBotButton
class — used to control the built-in D12 button
RedBotEncoder
class — used to control the left and right wheel encoders
Your app will need to create new objects (as global variables) for these three classes. Add these code statements before the setup()
function:
As you can see, the first code statement creates a RedBotMotors
object named motors
, which your app will use to control your left and right motors.
The second code statement creates a RedBotButton
object named button
, which your app will use to check whether the D12 button is pressed. We're doing this to show you another possible way to check the button. The difference is your code won't need to identify the button's pin number and won't need to set the button's pin mode — because the RedBotButton
object does this automatically when it is created. In addition, the code statement that you'll use to read the button is slightly different (as you'll see later).
The third code statement creates a RedBotEncoder
object named encoder
, which your app will use to control both wheel encoders. This code statement does three things (in order):
It declares the class for the object. This is similar to declaring a data type for a variable. In this case, RedBotEncoder
is the name of the class in the RedBot library being used to create the new object.
It declares the object's name. In this case, the object will be named encoder
. Just like with other variables, you get to decide what to name your objects.
It indicates the I/O pin numbers for the encoders. In this case, A2
is the I/O pin used by the left wheel encoder, and 10
is the I/O pin used by the right wheel encoder.
When your robot and computer are connected with a USB cable, they can communicate with each other by transferring serial data.
In this app, your robot will send data from the wheel encoders to your computer. Your Arduino code editor has a serial monitor window that can be used to view this serial data communication.
Add this code statement within the setup()
function:
This starts the serial data communication and sets the data transfer rate to 9600 bits per second.
As you've learned, every Arduino app must have one setup()
function and one loop()
function. In addition, you can add your own custom functions to your app.
A custom function is typically used to contain code that performs a specific task or subtask. Custom functions are useful for breaking up your app into smaller code modules that are easier to understand and easier to re-use.
Custom functions are typically listed after the loop()
function. Each custom function added to your app must be given a unique name to identify it. You get to decide what to name your custom functions, but choose names that will make sense to anyone reading your code. (The same rules and recommendations for naming variables apply to naming functions).
In this case, you'll add a custom function that contains all the code to perform a test of the wheel encoders. The function will be named testWheelEncoders()
.
Add this custom function after the loop()
function (i.e., after its closing curly brace):
In line 4 above, you can see that the code statement used to check whether the built-in D12 button is pressed is slightly different when you use a RedBotButton object:
The RedBotButton
object named button
has a read()
method that can be used to detect whether or not the button is being pressed.
If the button.read()
method returns a value equal to true
, it means the button is pressed. (Otherwise, a value of false
means the button is not pressed.)
When the button is pressed, two things will occur:
Both wheel encoder counters will be reset back to zero by using the code statement: encoder.clearEnc(BOTH);
Both motors will start driving at a power of 150.
Then two local variables called leftCount
and rightCount
are declared. Each variable has a data type of long
(special type of integer) because that's what the wheel encoders use. The value assigned to each of these variables is the current encoder count (i.e., the number of magnetic "ticks" counted) returned by the encoder.getTicks()
method.
Then the wheel encoder data is sent to the computer using Serial.print()
statements. This is the data that will be displayed in the computer's serial monitor window.
Finally, if either the left or right encoder count reaches 1000 or higher (which will happen after the motors have been driving for a few seconds), the motors will be braked.
The code within a custom function is only performed if the custom function is "called" by its name within another function, such as the setup()
function or loop()
function.
Add this code statement within the loop()
function:
By listing the name of the custom function, the custom function is "called" — so the code within that custom function will be performed one time.
For this app, this will be only code statement listed within the loop()
function. Since the loop()
function repeats itself continuously, the testWheelEncoders()
function will be called repeatedly.
Connect your robot to your computer using the USB cable. Be sure the robot is standing upright on its back end (with its wheels in the air), so the robot won't drive way while it's connected to your computer.
Turn on your robot, and upload the app to your robot. After the upload is complete, do not unplug the USB cable. You have to keep the robot connected to your computer to allow the serial data communication.
In your Arduino code editor, open the serial monitor, so you can view the serial data communication from your robot:
Arduino Create (Web Editor): Click the Monitor menu link in the left navigation to display the serial monitor in the middle panel.
Arduino IDE (Desktop Editor): Under the Tools menu, select "Serial Monitor." A new window will appear displaying the serial monitor.
Press the D12 button on your robot's circuit board. Your robot's wheels should start driving. In the serial monitor, view the data showing the wheel encoder counts. When either one of the wheel encoder counts reaches 1000 (which should take about 3-4 seconds), the motors will brake.
Each line of serial data (one set of left and right encoder counts) represents the testWheelEncoders()
function being performed one time. Each time the loop()
function repeats, it calls the custom function, which sends another line of serial data to the serial monitor.
You'll probably notice that the wheel encoder counts do not stop exactly at 1000. This is normal — it takes a brief amount of time for the braking to occur. The final counts should be less than 1050.
You'll probably notice that your left and right wheel encoder counts are not exactly the same. This is normal — they should be close to each other (within about 25), but they probably won't be identical.
If one or both wheel encoders are not working properly (the count stays at zero), then turn off the robot's power, and check the wheel encoder alignment again. After correcting the alignment, turn the robot's power back on to restart the app.
CHECK ENCODERS AFTER CHANGING BATTERIES: Whenever you change the robot's batteries, be sure to check the encoder sensor positions afterwards. It's common to accidentally move the encoder sensors when changing the batteries.
First, you'll code an app to make your robot drive forward. Then you'll modify the app so the robot drives forward and then backward.
If necessary, log in to the Arduino Create web editor, or open the Arduino IDE desktop editor.
Create a new app template. If you need a reminder, here are instructions for creating a new app template.
Rename the the new app as: driving_test
If you need a reminder, here are instructions for how to rename an app.
Add this block comment at the beginning of your app code. Modify the comment to list your information.
Arduino apps can include one or more libraries. A library is a pre-built code file that makes it easier to program certain things in your app.
There is a SparkFun RedBot Library that makes it much easier to control the motors and sensors connected to your RedBot.
You will need to add a copy of the SparkFun RedBot Library to your code editor, which is a one-time process. Then you will also need to include a copy of this library in each new robot app.
You should now have an #include
statement for the RedBot library (filename: RedBot.h
) listed at the beginning of your app code.
The RedBot.h
library contains Arduino code that defines different classes of objects. Each class defines a set of properties (variables) and methods (functions) for a specific type of object.
Your robot apps will use these classes to create objects in your app code. An object is a special type of variable that represents a specific instance (member) of a class. An object has all the properties and methods defined for that class.
The objects in your robot app code will correspond to real-life parts on your robot (such as: motors, wheel encoders, mechanical bumpers, etc.).
One of the classes in the RedBot library that you'll use in your apps is the RedBotMotors
class, which defines methods to control your robot's left and right motors.
You'll need to create a new RedBotMotors
object as a global variable in your app, so you can use this object to control your robot's motors. Add this code statement before the setup()
function:
This code statement does two things (in order):
It declares the class for the object. This is similar to declaring a data type for a variable. In this case, RedBotMotors
is the name of the class in the RedBot library being used to create the new object.
It declares the object's name. In this case, the object will be named motors
. Just like with other variables, you get to decide what to name your objects.
As a reminder, whenever you upload a new app to your robot, the new app starts running immediately (even before you've had a chance to unplug the USB cable from your robot). In a worst-case scenario, your robot might accidentally drive off your desk and crash onto the floor.
Therefore as a safety feature, most of the robot apps in these tutorials will use an if
statement within the loop()
function to check whether the D12 button on the circuit board has been pressed before making the robot drive around. When the button is pressed, the speaker and built-in LED will beep and blink as a confirmation before performing other robot actions (such as driving, etc.).
Create global variables for the LED pin, speaker pin, and button pin by adding this code before the setup()
function:
Set the pin modes for the LED, speaker, and button by adding this code within the setup()
function:
Check whether the button has been pressed by adding this code within the loop()
function:
Basically, this code for "Press to Start" is the same as the final version of the "Hello World" app you completed in the previous tutorial — except the second delay()
statement was removed (because the code that will be added for "other robot actions" will act as a delay between each check of the button).
HOW TO COPY CODE: When using this IoT code guidebook, you can copy a code block simply by clicking the copy icon displayed in the upper right of the code block.
The RedBotMotors
class defines a method named drive()
that can be used to drive the motors either forward or backwards. The RedBotMotors
class also defines a method named brake()
that can be used to stop the motors.
Therefore, your motors
object has a motors.drive()
method and a motors.brake()
method (as well as any other methods defined in the RedBotMotors
class).
When the motors.drive()
method is used in your code, the motors will start and will keep driving continuously (sort of like cruise control on a car). You'll use a delay()
statement to allow the motors to drive for a certain amount of time before turning the motors off with the motors.brake()
method.
When the robot's button is pressed, let's make your robot drive forward for 2 seconds and then brake. Add this code within the if
statement in the loop()
function (after the noTone()
statement):
The motors.drive()
method requires one parameter inside its parentheses:
The motor power, which can be any integer (whole number) between -255
and 255
. A positive power drives the robot forward, and a negative power drives the robot backward. A larger absolute power produces a faster driving speed (-255
and 255
are the fastest speeds, while -1
and 1
are the slowest speeds). In this case, the power will be 200
.
SLOW DOWN: Driving the motors at high power can sometimes cause the wheels to slip due to insufficient traction with the surface. If you notice traction issues while driving, use a lower motor power (slower speed). In general, use a motor power of 200 or less for driving.
Follow the steps to upload the app to your robot:
Connect Robot to Computer
Turn on Robot Power
Select Correct Board and Port
Upload App to Robot
Unplug the USB cable from the robot, and place the robot on the floor. Be sure a path of at least 3 feet in front of the robot is clear of any obstacles. (Just to be safe, also be sure a path of 3 feet behind the robot is clear — in case your robot's motor wires were accidentally reversed during assembly.)
Press the D12 button on your robot's circuit board. Your robot should beep and then drive forward for 2 seconds (about 30 inches).
If your robot doesn't drive at all, first check that its Motor switch is set to RUN. If the switch was correct, next check the left and right motor wires on the circuit board to verify the red and black wires are correctly plugged in. If the wires were correct, replace the batteries in the robot's battery pack.
If your robot spins clockwise (to the right), unplug and reverse the red and black wires of the right motor on the circuit board.
If your robot spins counter-clockwise (to the left), unplug and reverse the red and black wires of the left motor on the circuit board.
If your robot drives backward, first check your app code to make sure you used a positive value for the motor power (not a negative value). If the app code is correct, unplug and reverse the red and black wires for each motor on the circuit board.
NOTE: If your robot drives forward but not in a perfectly straight line, this is actually normal. Even though the two motors are supposed to be identical and are receiving identical power, they might not necessarily rotate at the exact same rate. Even a minor difference in their rotation rates will cause the robot to drift either to the left or to the right as it drives (depending on which motor is rotating more slowly).
Later in this tutorial, you'll learn how to use the wheel encoders to measure the rotation rates of the motors, in order to make small power adjustments to each motor so the robot drives in a straight line.
Next you'll modify the app so the robot will drive forward for 2 seconds, stop briefly, drive backward for 2 seconds, and finally stop approximately at its starting point.
Add this code within the if
statement in the loop()
function (after the motors.brake()
statement):
Upload the modified app to your robot. Unplug the USB cable from the robot, and place the robot on the floor. Be sure a path of at least 3 feet in front of the robot is clear of any obstacles.
Press the D12 button on your robot's circuit board. Your robot should beep and then drive forward for 2 seconds (about 30 inches). It should stop and pause for 1 second before driving backward for 2 seconds (about 30 inches), returning approximately to its starting point.
If you want, you can modify the app further to try different motor powers or different delay times — just be sure you have a clear driving path to avoid crashing your robot into any obstacles.
As your last step of this tutorial, you'll code an app that uses the wheel encoders to make your robot drive straight continuously (rather than for a specific distance).
Driving straight continuously is usually combined with other robot behaviors that you'll learn about in the upcoming tutorials: detecting collisions, avoiding collisions, avoiding a line, counting lines crossed, etc.
Open your Arduino code editor, and create a new app template.
Add a block comment at the beginning of the app code to identify your new app:
Rename the the new app as: drive_straight_test
If you need a reminder, here are instructions for how to rename an app.
Follow the steps to include the SparkFun RedBot Library in your app. (You don't need to add the library to your code editor again — just include the library in this new app.)
Your app will need to create new objects (as global variables) to represent the robot's button, motors, and wheel encoders. Add this code before the setup()
function:
This app will use a different version of the "Press to Start" code.
Create global variables for the LED pin and speaker pin by adding this code before the setup()
function:
Set the pin modes for the LED and speaker by adding this code within the setup()
function:
In this version of the "Press to Start" code, you'll still press the D12 button to "start" the robot. However, once the robot is "started," you can press the D12 button again to "pause" the robot. (Pressing the button yet again will "start" the robot again.)
To do this, you'll use a global variable to keep track of whether or not the robot has been "started." Add this code statement before the setup()
function:
This code statement does three things (in order):
It declares a data type for the variable's value. In this case, bool
stands for boolean. A boolean value can either be true
or false
. In this case, true
will mean the robot is "started," and false
will mean the robot is "paused."
It declares the variable's name. In this case, the variable will be called started
. You get to decide what to name your variables. Choose names that will make sense to anyone reviewing your code.
It assigns a value to the variable. In this case, the variable's initial value will be equal to false
because we don't want to "start" the robot until the D12 button is pressed.
Next, you'll add a custom function named checkButton()
that will check whether the D12 button is pressed. If the button is pressed, the function will reverse the current value of started
from true
to false
(or from false
to true
).
Add this custom function after the loop()
function (i.e., after its closing curly brace):
The code statement that reverses the value of started
is: started = !started;
This code statement works by assigning a new value to started
that is equal to its opposite value. For a boolean variable, listing an exclamation point in front of the variable name represents its opposite value. So if started
currently has a value of true
, it will be assigned a new value of false
(or vice versa).
Now add this new code within the loop()
function:
As you can see, this code will call the checkButton()
function. Then it uses an if-else statement to perform different code (not added yet) depending on whether started
is true
or false
.
You'll add another custom function named driveStraight()
which will contain code to use the wheel encoders to make your robot drive in a continuous straight line (as long as this function is called continuously by the loop()
function).
The driveStraight()
function works similar to the driveDistance()
function, except it doesn't stop the robot after a specific distance.
Add this custom function after the loop()
function:
The driveStraight()
function checks to see whether the wheel encoder counts are increasing at the same rate (by comparing how much their current counts increased from their previous counts). If one of the wheel encoder counts is increasing at a faster rate, the function adjusts the individual motor powers to try to keep them rotating at the same rate (which makes the robot drive straight).
In order to do this, the driveStraight()
function relies on global variables to track the left and right motor powers, as well as the left and right encoder counts. Add this code before the setup()
function:
You'll also want to reset both wheel encoder counters to zero when the app first starts. Add this code statement within the setup()
function:
When the D12 button is pressed to "start" the robot, we want to make the robot drive straight continuously.
Add this code within the if
statement in the loop()
function, so it will be performed when started
is true
:
Once the robot has been "started," the D12 button can be pressed again to "pause" the robot.
When the robot is "paused," we want to make sure the robot stops driving.
Add this code within the else
statement in the loop()
function, so it will be performed when started
is false
:
Follow the steps to connect your robot to your computer, and upload the app.
Unplug the USB cable from the robot, and place the robot on the floor. Be sure the robot has a clear path to drive forward for at least 6 feet.
Press the D12 button to "start" the robot driving in a straight line. It should keep driving in a straight line continuously, so you'll have to pick up the robot at some point and "pause" it by pressing the D12 button (or you can press the Reset button).
If you want to test further, place the robot on the floor, and press the button to "start" the robot again.
Next, you'll code an app that uses the wheel encoders to make your robot pivot by a specific angle (measured in degrees).
The wheel encoders can also be used to pivot (turn) your RedBot by a specific angle by measuring the distance traveled by the wheels while pivoting.
When pivoting, the robot turns in a circle centered between the robot's wheels. The distance between the centers of the RedBot wheel treads is 6.125 inches, which represents the diameter of the robot's pivot circle. If the robot pivoted 360°, the distance traveled by each wheel would be equal to the circumference of this pivot circle:
C = 𝛑 × d = 3.14 × 6.125 = 19.23 inches
Usually you will want your RedBot to pivot by a specific angle that is less than 360° — such as 45°, 90°, 180°, etc. For any specific angle, you can calculate its arc length (i.e., a "partial circumference"):
L = 𝛂 / 360° × 𝛑 × d
The arc length (L) represents the distance each wheel will travel while pivoting by a specific angle (𝛂).
For example, when pivoting by 90°, the arc length is:
L = 90° / 360° × 𝛑 × d = 0.25 × 3.14 × 6.125 = 4.81 inches
Once this arc length is calculated for a specific angle, the wheel encoders can be used to control how long the wheels are pivoted.
In your Arduino code editor, use the "Save As" command to save a copy of your existing drive_distance_test
app as a different app named: pivot_angle_test
If necessary, here are instructions for how to save a copy of an app with a new name.
Once you saved the new app name, modify the block comment near the beginning of the app code to change Drive Distance Test
to Pivot Angle Test
.
You'll add another custom function named pivotAngle()
which contains code to make your robot pivot by a specified angle by using the wheel encoders.
Add this custom function after the loop()
function (i.e., after its closing curly brace):
KEEP BOTH CUSTOM FUNCTIONS: Be sure to keep the driveDistance()
custom function in your app code. You'll use this custom function again to modify this app as a final step.
Remember that the code within a custom function is only performed if the custom function is "called" by its name within another function, such as the setup()
function or loop()
function.
When calling the pivotAngle()
custom function, you must pass in a value for the angle (degrees) by listing a number inside the parentheses after the function's name:
A positive angle will pivot the robot clockwise to the right.
A negative angle will pivot the robot counter-clockwise to the left.
You'll use the pivotAngle()
function to make your robot pivot 90° right.
First, delete the driveDistance(36);
code statement within the if
statement in the loop()
function (after the noTone()
statement), and then replace it with this code statement instead:
By listing the name of the custom function, the custom function is "called" — so the code within that custom function will be performed one time. By listing 90
inside the parentheses, the robot will pivot clockwise by 90 degrees.
Follow the steps to connect your robot to your computer, and upload the app.
Unplug the USB cable from the robot, and place the robot on the floor. Create a "plus sign" on the floor (using masking tape, etc.). The "plus sign" should consist of two lines about 12 inches long (i.e., slightly longer than the robot) that cross at a right angle (90°).
Place the robot on the "plus sign" so its wheels are centered on one line, while the front of the robot is aligned with the other line, which will act as the starting point (0°) for the pivot angle. The diagram below shows the proper starting alignment.
Press the D12 button on your robot's circuit board. Your robot should beep and then pivot 90° right.
Use the "plus sign" to visually check how the alignment of the pivoted robot compares to 90° right.
Align the robot with the lines, and test again. Repeat the test several times to determine if the pivoting needs to be adjusted with a correction value.
The pivotAngle()
function contains a local variable named correction
which has been set to -5.0
because during our testing, our robot was pivoting about 5 degrees too far when using a motor power of 100. The reason for this is because it takes a small amount of time for the robot to apply the brakes and come to a complete stop.
If your robot is pivoting too much (or too little), you'll want to change the value assigned to correction
in the pivotAngle()
function:
If your robot is pivoting too much, subtract from the correction value. For example, if your robot is pivoting 5 degrees too much (95°), subtract 5 from correction
, changing it from -5.0
to -10.0
.
If your robot is pivoting too little, add to the correction value. For example, if your robot is pivoting 5 degrees too little (85°), add 5 to correction
, changing it from -5.0
to 0.0
.
If you do adjust the correction
value, upload the modified app to your robot, and test again to ensure the pivot angle is accurate (within 5 degrees of the intended angle).
Next, you'll modify the app code so your robot will pivot 90° left. To pivot counter-clockwise to the the left, you specify a negative angle when calling the pivotAngle()
function.
Modify the call to pivotAngle()
within the loop()
by changing the angle from 90
to -90
.
Upload the modified app to your robot. Align the robot on the "plus sign," and press the D12 button to verify that your robot pivots 90° left.
Next, you'll modify the app code so your robot will pivot 180° around.
Modify the call to pivotAngle()
within the loop()
by changing the angle to 180
.
Upload the modified app to your robot. Align the robot on the "plus sign," and press the D12 button to verify that your robot pivots 180° around.
Finally, you'll modify the app to make your robot drive in a pattern using multiple calls to the driveDistance()
function and the pivotAngle()
function.
You'll make the robot follow the pattern shown in the diagram below. When the robot reaches the end, it will turn around and retrace its path back to the start.
First, delete the pivotAngle(180);
code statement within the loop()
function, and then replace it with this code instead:
Upload the modified app to your robot. Align the robot on the "plus sign," and press the D12 button to verify that your robot drives and pivots following the pattern. The robot should return back to its staring point (though it probably won't be perfectly aligned back on the "plus sign").
In the next tutorial, you'll program apps to make your robot detect objects in its path.
Next, you'll code an app that uses the wheel encoders to make your robot drive straight for a specific distance (measured in inches).
The ring magnet attached to each motor shaft has 4 pairs of N-S poles, similar to the diagram below.
As the motor shaft and its attached ring magnet complete one full rotation, the wheel encoder detects 4 changes (or "ticks") in the magnetic field as the magnetic poles pass by the sensor. Each wheel encoder keeps track of the total number of "ticks" it has counted.
However, each rotation of the motor shaft only turns the wheel a certain number of degrees. The RedBot motors have a gearbox ratio of 48:1, which means it actually takes 48 rotations of the motor shaft to make the wheel complete one full revolution.
We can use this information to calculate how many "ticks" counted by the wheel encoder would represent one revolution of the wheel:
4 ticks per motor rotation × 48 motor rotations per wheel revolution = 192 ticks per wheel revolution
Based on the size of the RedBot's wheels, we can also calculate the distance that the RedBot travels during one wheel revolution. The distance is equal to the circumference of the wheel (i.e., the distance around the outer edge of the wheel). The circumference of a circle is its diameter multiplied by pi (approximately 3.14).
Since the RedBot's wheels have a diameter of 65 mm (2.56 inches), the distance traveled per wheel revolution is:
C = 𝛑 × d = 3.14 × 2.56 inches = 8.04 inches per wheel revolution
So for your RedBot's wheel encoders, the following is true:
192 ticks counted by wheel encoder = 1 wheel revolution = 8.04 inches traveled
By keeping track of the total number of magnetic "ticks" counted for each motor, you can use the wheel encoders to perform several useful robot behaviors:
Drive in a straight line by making small adjustments in the individual motor powers applied to the left and right motors, to make sure they rotate at the same rate (which is necessary for straight driving).
Drive for a specific distance by calculating how far the wheels have traveled while driving. (This is typically combined with adjusting the left and right motor powers to drive straight.)
Pivot (or turn) by a specific angle by calculating how far the wheels have traveled while pivoting (or turning) in a circle. This can be used for pivoting on both wheels or turning on one wheel.
Open your Arduino code editor, and create a new app template.
Add a block comment at the beginning of the app code to identify your new app:
Rename the the new app as: drive_distance_test
If you need a reminder, here are instructions for how to rename an app.
Follow the steps to include the SparkFun RedBot Library in your app. (You don't need to add the library to your code editor again — just include the library in this new app.)
Your app will need to create new objects (as global variables) to represent the robot's motors, button, and wheel encoders. Add this code before the setup()
function:
Create global variables for the LED pin and speaker pin by adding this code before the setup()
function:
Set the pin modes for the LED and speaker by adding this code within the setup()
function:
Check whether the button has been pressed by adding this code within the loop()
function:
You'll add a custom function named driveDistance()
which contains code to make your robot drive in a straight line for a specified distance by using the wheel encoders.
Add this custom function after the loop()
function (i.e., after its closing curly brace):
Remember that the code within a custom function is only performed if the custom function is "called" by its name within another function, such as the setup()
function or loop()
function.
When calling the driveDistance()
custom function, you must pass in a value for the distance (inches) by listing a number inside the parentheses after the function's name.
You'll use the driveDistance()
function to make your robot drive straight for 36 inches. Add this code statement within the if
statement in the loop()
function (after the noTone()
statement):
By listing the name of the custom function, the custom function is "called" — so the code within that custom function will be performed one time. By listing 36
inside the parentheses, the robot will drive straight for 36 inches.
The driveDistance()
function could also be used to make your robot drive backward — just pass in a negative number when calling the function.
Follow the steps to connect your robot to your computer, and upload the app.
Unplug the USB cable from the robot, and place the robot on the floor. Create a "start line" on the floor (using masking tape, etc.). Line up the front edge of the robot with the front edge of the start line. Be sure a path of at least 3 feet in front of the robot is clear of any obstacles.
Press the D12 button on your robot's circuit board. Your robot should beep and then drive forward in a straight line for 36 inches.
Then measure the distance from the front of the start line to the front of the robot, in order to measure the actual distance traveled and see how close it is to 36 inches.
Line up the robot with the start line, and test again. Repeat the test several times to determine the average distance.
The driveDistance()
function contains a local variable named correction
which has been set to -1.0
because during our testing, our robot was driving about 1 inch too far when using a motor power of 150. The reason for this is because it takes a small amount of time for the robot to apply the brakes and come to a complete stop.
If your robot is driving too far (or not far enough), you'll want to change the value assigned to correction
in the driveDistance()
function:
If your robot is driving too far, subtract from the correction value. For example, if your robot is driving 0.5 inch too far (36.5 inches), subtract 0.5 from correction
, changing it from -1.0
to -1.5
.
If your robot is not driving far enough, add to the correction value. For example, if your robot is driving 0.5 inch too little (35.5 inches), add 0.5 to correction
, changing it from -1.0
to -0.5
.
If you do adjust the correction
value, upload the modified app to your robot, and test again to ensure the driving distance is accurate (within 0.5 inch of the intended distance).