Ludus Protoshield Hookup Guide
This Tutorial is Retired!
This tutorial covers concepts or technologies that are no longer current. It's still here for you to read and enjoy, but may not be as useful as our newest tutorials.
View the updated tutorial: Wireless Motor Driver Shield Hookup Guide
Easy Prototyping with Ludus
The Ludus Protoshield is an Arduino shield designed to make it easier and faster to connect motors and sensors to your Arduino compatible development board. It's really handy for throwing together remote control rovers and small autonomous robots. This guide will get you up and running with your very own Ludus ProtoShield or Ludus Protoshield Wireless!
Required Materials
Aside from the Ludus Protoshield, you will also need to stack the shield to a microcontroller. We recommend the SparkFun RedBoard or any other Arduino form factor boards such as the Arduino Uno or the Arduino Leonardo.
One of the main features of the Ludus Shield is to make working with motors easier for those just learning. In order to fully utilize this shield, you'll also need some motors to drive. Check out our Motors Category for some ideas.
Suggested Reading
You may find some of the following concepts useful before using your Ludus ProtoShield.
Serial Communication
What is an Arduino?
Installing Arduino IDE
Serial Terminal Basics
Hardware Overview
There are two versions of the Ludus Shield available: SparkFun Ludus ProtoShield and Ludus ProtoShield Wireless! First, let's have a look at the hardware that they have in common.
The heart of both versions of the Ludus ProtoShield is an H-Bridge Motor Driver. This allows the ProtoShield to drive two DC motors at once in both directions and even brake electronically. This H-Bridge Driver in particular, the TB6612FNG, is rated up to 1.2A per channel at 13V which means it will drive a fairly beefy hobby motor. This makes it ideal for small rover-style robots and kinetic sculptures.
Another feature that both versions have in common is the addition of power (PWR) and ground (GND) rails alongside the GPIO pins. Not only does this help you to avoid the common inconvenience of running out of GND and PWR pins, but because the pins are arranged with PWR in the center, plugging in servos is a snap! The PWR rail can even be switched between 5V (from the Arduino's voltage regulator) and Vin using the on board slide switches.
The difference between the two boards is that the standard Ludus ProtoShield includes an I2C header whereas the Ludus ProtoShield Wireless adds to that an XBee socket.
The I2C header on the standard Ludus ProtoShield is laid out so that you can plug in a device such as a Triple Axis Magnetometer or even the 9DOF Sensor Stick. With these sensors it's possible to set up a dead reckoning navigation system.
If autonomy isn't your thing, though, the Ludus ProtoShield Wireless is perfect for setting up XBee based remote control. Simply plug an XBee radio module into the socket on the shield, and you're ready to transmit wireless data using the common zigbee standard!
Simple Motor Control
In this section, we'll review how to connect a pair of motors to the Ludus ProtoShield and get them spinning. Before we do that, however, let's talk a little bit about how we talk to the H-Bridge Driver. If we look at the datasheet for the TB6612FNG we find a table like this:
This table shows the relationship between the input and output pins on the H-Bridge. Each of the two channels requires 3 pins to operate: IN1, IN2 and PWM. By driving the IN pins high or low, you can control the direction of the motor on that channel as well as disengage it completely or even short it end-to-end (like pressing the brakes). The signal that you feed to the PWM pin determines the speed of the motor on that channel. By referencing the table above, we discover that in order to make the motor turn clockwise at 50% speed, we'll need set IN1 to High, IN2 to LOW and send a 50% PWM signal (that's analogWrite(pin, 128)
in Arduino)
We can look at the silkscreen on the shield itself to find out which Arduino pins are connected to which inputs on the H-Bridge. Once we know that, we can start to write some basic example code to control the driver.
Before anything is going to move, we'll need to connect a pair of motors. If you're just starting out with robotics, we suggest the DAGU Hobby Gearmotors which are the same ones that come with our Ardumoto Shield Kit. Solder a pair of jumper wires to each of the gearmotors, and plug them into the A+, A-, B+ and B- headers. The example code also allows you to control a servo, so if you'd like to add a servo, plug it into pin 11.
Now, attach the shield to an Arduino or SparkFun RedBoard and connect a power supply, such as a 9V battery. Once that's done, we can get the example code loaded onto the Arduino.
Grab the example code from the GitHub repository here, and open it in Arduino. Connect your RedBoard or Arduino over USB, and make sure you have the correct board type and COM port selected. Now press "upload" to send the example code to the board!
If everything went well, you should now be able to open a serial terminal (such as the one built into the Arduino IDE), and type a bunch of "w"s to make the motors turn. This example was really written to be used with terminal programs, which allow you to type directly to the port without having to press return. That way, you can drive the robot by holding down the appropriate keys on your keyboard. My favorite terminal program for this is RealTerm. You can get RealTerm here.
Now that we've seen this thing in action, let's dig through the example code. Understanding how the example code works is the first step towards writing your own!
Understanding the Example Code
The example code for the Ludus ProtoShield is available from the Ludus Shield GitHub repository and is designed to let you control the H-Bridge, as well as a servo attached to pin 11, using serial communication.
You can download the code here to get started. In the meantime, let's walk through a few excerpts from the code and see if we can understand a little better what's making it work. As with most sketches, it starts with some basic setup:
language:c
#include <Servo.h>
Servo swivel;
int pwm_a = 3; // Channel A speed
int pwm_b = 6; // Channel B speed
int dir_a0 = 4; // Channel A direction 0
int dir_a1 = 5; // Channel A direction 1
int dir_b0 = 7; // Channel B direction 0
int dir_b1 = 8; // Channel B direction 1
char inbit; // A place to store serial input
int swivelpos = 90; // Servo position
void setup()
{
Serial.begin(9600); // Pour a bowl of serial
swivel.attach(11); // Attach servo to pin 11
swivel.write(swivelpos);
pinMode(pwm_a, OUTPUT); // Set control pins to be outputs
pinMode(pwm_b, OUTPUT);
pinMode(dir_a0, OUTPUT);
pinMode(dir_a1, OUTPUT);
pinMode(dir_b0, OUTPUT);
pinMode(dir_b1, OUTPUT);
draw(); // Draw the driving instructions to the serial terminal
}
As you can see, we started out by including the servo library and creating a servo object called "swivel". Next, we declare a handful of variables to keep track of which pins are responsible for which functions, and also variables for the servo position and incoming serial characters. The setup()
function is where serial communication is initialized, the servo object is attached and the control pins are all set as output devices. Finally, we call the function draw()
, which we'll look at in a minute.
language:c
void loop()
{
if(Serial.available()){ // Wait for serial input
inbit = Serial.read();
switch(inbit){ // Switch based on serial in
case 'w': // Move Forward
forward(200);
delay(30);
shutoff();
break;
case 's': // Move Backward
reverse(200);
delay(30);
shutoff();
break;
case 'q': // Turn Left while moving forward
turnL(200);
delay(30);
shutoff();
break;
case 'e': // Turn Right while moving forward
turnR(200);
delay(30);
shutoff();
break;
case 'a': // Spin Left in place
spinL(200);
delay(30);
shutoff();
break;
case 'd': // Spin Right in place
spinR(200);
delay(30);
shutoff();
break;
case 'x': // Short brake
brake();
break;
case 'z': // Spin servo (on pin 11) left
servoL();
break;
case 'c': // Spin servo (on pin 11) right
servoR();
break;
}
}
}
The main loop of the example code just waits to see input on the serial line and then stores the incoming value and compares it against a list of cases. By scrolling through the switch/case statements, you can see the behavior associated with each serial character. The rest of the code is composed of the various procedures that are called in the main loop. Let's look at a few of these:
language:c
void draw() // Serial Instructions
{
Serial.println(" ");
Serial.println(" ------------------------- ");
Serial.println(" | | | | ");
Serial.println(" | Q | W | E | ");
Serial.println(" | turnL |forward| turnR | ");
Serial.println(" ------------------------- ");
Serial.println(" | | | | ");
Serial.println(" | A | S | D | ");
Serial.println(" | spinL |reverse| spinR | ");
Serial.println(" ------------------------- ");
Serial.println(" | | | | ");
Serial.println(" | Z | X | C | ");
Serial.println(" |servo L| brake |servo R| ");
Serial.println(" ------------------------- ");
Serial.println(" ");
}
This one is pretty straightforward! The draw()
procedure is just a bunch of print statements that tell you which keys are attached to which functions.
Finally there are a bunch of procedures that actually set the speed and direction of the motors. These are the functions that you'll want to borrow for your own code because they wrap up all of the control pin stuff we talked about in the last section into intuitive commands like "forward," "turn," and "brake." All of the motion commands are basically structured the same, for example:
language:c
void forward(int speed) // Move Forward
{
digitalWrite(dir_a0, 0);
digitalWrite(dir_a1, 1);
digitalWrite(dir_b0, 0);
digitalWrite(dir_b1, 1);
analogWrite(pwm_a, speed);
analogWrite(pwm_b, speed);
}
The brake()
and shutoff()
functions are structured the same as the motion procedures except that in the case of brake()
, all of the pins are written high, and in the case of shutoff()
, all of the pins are written low. The brake()
procedure actually shorts the motor so that it resists turning. The shutoff()
function simply shuts off power to the motors so that they come to a rolling stop.
Finally, there are the servo control functions, which increment or decrement the servo position variable before writing it to the servo:
language:c
void servoL() // Spin servo (on pin 11) left
{
if(swivelpos>10){
swivelpos = swivelpos-10;
swivel.write(swivelpos);
}
}
The only kind of clever thing going on here is that we check ahead of time whether we've reached the limits of the servo so we can't increment beyond its range of motion.
Going Wireless
If you have the Ludus ProtoShield Wireless, you can free your project from its USB tether! Do do this, you'll need a pair of XBee radio modules and an XBee Explorer USB. Even if you're not familiar with XBee, you should be able to run the example code wirelessly as the radio modules should be configured properly by default. For an introduction to XBee, check out this SparkFun tutorial for getting started with XBees. There's a lot more you can do with XBee than what we'll cover here.
The first step is to plug an XBee radio into the ProtoShield. The silkscreen on the board shows which orientation it should go. Make sure that the slide switch marked "HW_Ser" and "SW_Ser" is set to "HW_Ser". This will connect the XBee radio to the hardware serial lines of the Arduino. Next, plug your XBee Explorer into the USB port on your computer, and open the serial terminal program that you were using in the Simple Motor Control section. Open the COM port for the XBee Explorer and switch the Arduino on.
The example code should now work exactly as it did before, only this time, your serial commands are being sent over the air! What's happening is that the XBee radio is acting like a wireless serial tunnel. As far as the Arduino knows, there's a USB cable hooked up to the serial line.
Resources and Going Further
Hopefully by now you've built yourself a robot to play with! Getting moving is just the start, though. For more information, check out the resources below:
- TB6612FNG Motor Driver Datasheet
- Ludus ProtoShield GitHub Repository
- Ludus ProtoShield Wireless GitHub Repository
- Example Code
- Arduino Software Serial Library
Check out some of our other robotics tutorials to take your Ludus ProtoShield bot to the next level.