This is the manual for CU Network Roboboard v2.1 and operating system in the Lego Robots configuration.
By Brian Shucker
January 2007
Updated by Kevin Bauer
January 2007
This document contains most of what you will need to know in order to use the roboboard. This includes basic information about the roboboard hardware, the IAR software development tools and the terminal interface, sensors, actuators, communication capabilities (not used for the Lego Robot class), message logging, power, error conditions, a function quick reference, and a shell command quick reference.

JP3, JP4, and JP6 should all be connected. All remaining jumpers should be left disconnected.
Connect the battery cable to the roboboard power jack. Next, connect the serial cable to the roboboard and to serial port A (COM1) on the PC. Open up TeraTerm on the PC.
Under serial port, set the port to COM1, baud rate to 115200Kbps, data to 8 bit, no parity, 1 stop bit. Set flow control to Xon/Xoff.
Under terminal, set New-line receive to CR+LF and Transmit to CR.
Turn on the roboboard. You should see the blue "heartbeat" LED blinking. In the TeraTerm window, you should see the "lego$" prompt. At this point, you can send commands through the shell. Try typing "beep" at the prompt. When you hit [enter], the roboboard should beep.
See the Shell Command Quick Reference for more details about what commands the terminal interface can understand.
drag .img file onto teraterm, reset
choose button
The roboboard processor is an Atmel at91SAM72256 microcontroller (MCU). The MCU is a standard 32-bit ARM7, similar to that used in some small PCs. It runs C code the same way that any 32-bit PC does. Unlike PC microprocessors, the roboboard MCU stores programs and variables (data) in different memory systems. The program memory is 256KBytes, and the data memory is 64KBytes.
The program memory is nonvolatile, which means that it remembers whatever is stored when the roboboard is turned off. Thus, when you turn the roboboard on, it will run the last program that you loaded, starting from the main() function. If you press the reset button or turn the board off and then on again, it will start running the same program back from the beginning. Note that if you hold the "choose" button down, the program will not run.
The data memory is volatile, which means that it forgets all stored values when the power turns off. When the board is turned off and then back on, it starts over with the initial values provided by its program.
There is also a 2MByte flash memory chip that can be used to store configuration values and log messages. This memory is also nonvolatile, so it keeps its contents when the power is off.
The roboboard supports a wide variety of on-board and off-board sensors.
Digital sensors may be connected to the digital input ports along the top edge of the board. These ports are labeled "Digital Input" and numbered from 0 to 7. Digital inputs give values of either 0 or 1 depending on the state of the sensor plugged into it. Normally, if a sensor is activated, depressed, etc. a value of 1 is delivered. If the sensor has not been tripped, the digital input will normally return a zero.
The function to take a reading from a digital input is:
digital(int p)
In this function, "p" can represent either a port number or the name of an assigned port (e.g. FRONT_TOUCH_SENSOR). The function will return either a zero or a one. Using this function in conjunction with touch sensors and shaft encoders inside loop structures are excellent ways to control a robots movement and interaction with the board.
When the roboboard is connected to a PC, it is also possible to read the value of a digital port directly from the shell. You may find this useful for testing your sensor hardware. The shell command is:
digital [port]
In this case, p must be a number (not a name). Also, remember that shell commands do not use parentheses.
Analog sensors may be connected to the analog input ports along the top edge of the board. These ports are labeled "Analog Input" and numbered from 8 to 17. Analog inputs are very similar to digital inputs, except that the values returned are in the range from 0 to 65535 instead of being either 1 or 0. The value returned from the port depends on the voltage returned by the sensor connected to it. The voltage can depend on many different things such as the position of a potentiometer, amount of light received by an IR reflectance sensor, etc.
The function to take a reading from an analog input is:
analog(int p)
In this function, "p" can represent either a port number or the name of an assigned port, just like digital inputs. The function will return an integer between zero and 65535. Analog inputs allow for certain types of control that digital functions cannot accomplish, simply because there are a range of values that can be returned.
Analog ports may be read from the shell similarly to digital ports. The shell command is:
analog [port]
Although all of the analog ports are used in the same way, there are minor hardware differences on some. The first 8 ports (8 through 15) are connected to the main analog-to-digital converter (ADC) and are identical. The last two ports (16 and 17) are connected to the secondary ADC, which is built into the processor and is slightly different. This means that a sensor that reads one value on any of the first 8 ports will read a slightly different value on ports 16 and 17. If you move a sensor between the two sets of port, you may have to recalibrate.
The roboboard contains 16 additional digital I/O ports, numbered 18 through 33. These ports can be used both as digital inputs (similarly to the regular digital inputs) and as digital outputs. However, the expanded digital I/O ports are slower than the standard digital inputs, and cannot be used with shaft encoders.
The expanded digital I/O is not normally used for lego robots. However, if you need the additional I/O, talk to the instructor.
Shaft Encoders, or slotted optical sensors essentially consist of a beam of infrared light going from one side of the encoder to the other, where a sensor is located. Whenever the beam is interrupted, the sensor delivers a logic high (or a 1 value), which is called a tick. The functions used with shaft encoders utilize this to count the number of ones delivered. This ability to count makes shaft encoders excellent devices for know how many times an axle has turned, and therefore what kind of distance it has traveled.
Shaft encoders can only be used with digital input ports (ports 0 through 7). To use the shaft encoder functions, you must include the file encoder.h at the top of your code file:
#include "encoder.h"
When this file is included, the following functions become available:
encoderStart(int p)
encoderStop(int p)
encoderRead(int p)
encoderReset(int p)
In all these functions, int p represents the port that the encoder is plugged into.
encoderStart starts the encoder running on port p. It will count ticks until it is told to stop.
encoderStop stops the encoder on port p, so it no longer counts ticks. The encoder holds whatever value it has.
encoderRead returns the current number of ticks on the encoder in port p. If the encoder is stopped, it returns the number of ticks that had occurred at the time encoderStop was called.
encoderReset resets the number of ticks on the encoder on port p to zero. This works whether the encoder is currently running or not.
Here is a sample program, followed by the explanation of what it does.
#include "robo.h"
#include "encoder.h"
/* constant declarations */
#define RIGHT_MOTOR 0
#define LEFT_MOTOR 1
#define RIGHT_ENCODER 1
#define LEFT_ENCODER 2
/* program code */
void roboMain(void)
{
/* start the encoders running */
encoderStart(RIGHT_ENCODER);
encoderStart(LEFT_ENCODER);
/* drive the robot forward */
forward(LEFT_MOTOR);
forward(RIGHT_MOTOR);
/* wait until either encoder passes 40 */
while(encoderRead(RIGHT_ENCODER) < 40 && encoderRead(LEFT_ENCODER) < 40)
{
printf("Left: %d\tRight: %d\n", encoderRead(LEFT_ENCODER), encoderRead(RIGHT_ENCODER);
}
/* stop moving and reset encoders */
alloff();
reset_encoder(LEFT_ENCODER);
reset_encoder(RIGHT_ENCODER);
}
This program tells the robot to move forward. While moving forward, the LCD screen will output the values on the shaft encoders. Once either of the shaft encoders has counted 40 ticks, the motors will shut off and the encoders will be reset.
The shaft encoders are polled at 1000Hz, which means that they may lose accuracy when counting more than 250 ticks per second. They will certainly lose accuracy above 500 ticks per second. Since the encoder counts both edges (when the optical switch is blocked, and when it is unblocked), the typical setup with a lego pulley wheel will result in 12 ticks per revolution. Make sure to construct your shaft encoder so that it operates fast enough to be useful, but slow enough to remain accurate.
The roboboard has a built-in 3-axis accelerometer (it is the square chip near the LEDs, marked "A7260"). This device measures the acceleration of the board in the X, Y, and Z axes. The X axis is parallel to the long side of the board, Y is parallel to the short side of the board, and Z is perpendicular to the board.
The accelerometer is actually three different analog sensors--one for each axis. The functions to read the accelerometer are:
accelerometerX()
accelerometerY()
accelerometerZ()
Each function reads one axis, as indicated in the name. These functions return a value between 0 and 65535, which is proportional to the current acceleration along that axis. The range for the accelerometer is roughly -2g to +2g (-19.6 meters/sec to +19.6 meters/sec). So a value of zero means -2g, a value of 65535 is +2g, and a value of 32768 means zero acceleration.
While these are the theoretical values, each accelerometer has a slight bias, so it is important to measure what it reads with zero acceleration, and calibrate appropriately.
The accelerometer can be used is several ways. First, it can determine if the robot changes speed. For example, if the robot bumps into something, it will experience a sudden acceleration (or if you prefer, a deceleration) that can be detected by monitoring the accelerometer values.
Another use of the accelerometer is as a tilt sensor. The accelerometer can detect the acceleration due to gravity, which is why the reading on the Z axis is approximately +1g when the board is lying still and flat. If the board is tilted, then gravity will no longer be acting only along the Z axis, so there will be less acceleration along Z and more along X and/or Y (depending on which way the board is tilted). Reading the values on the X and Y axes and applying some simple trigonometry will allow you to compute the orientation of the board relative to the earth.
The dip switches on the Roboboard are in the little red piece numbered from 1 to 4. Each one can be turned off or on, and by varying which switches are on and off, all numbers from 0 to 15 can be represented. For example, if all of them are off, then the number 0 is represented. Turning on switch 1 adds 1 to the number. Turning on switch 2 adds 2 to the number. Switch 3 adds 4, and switch 4 adds 8. Therefore, to get 7, switches 1, 2, and 3 would be turned on (4+2+1=7).
Dip switches are very handy, especially later in the course when a robot needs to be able to choose between multiple strategies. The following are the 2 functions to use when utilizing the dip switches
dipSwitch(int sw)
dipSwitches()
The first function reads the value of a single switch (represented by int sw), just like a digital sensor. If the switch is turned on, a 1 value will be returned. If it is off, 0 will be returned.
To read the value of all the switches, use the second function. So, to choose between three strategies (labeled Strat1(), Strat2(), Strat3()), something similar to the following could be used.
if (dipSwitches() == 2)
Strat1();
else if (dipSwitches() == 4)
Strat2();
else
Strat3();
In this case, the robot could choose between three different strategies depending on which switches were turned on before the robot was turned on.
The choose button works just like a digital input. The function to read its value is:
chooseButton()
This will return a 1 if the switch is pressed or a zero if not, just like a digital input.
The choose button also has a special function. If the button is held down as the roboboard is turned on, then it will not run the main program. This is useful so that you can turn on the board to use the shell and reprogram it, without having it turn on motors or whatever else the currently loaded program does. Once the board has started up, the choose button works just like a digital input.
The Roboknob (located on the top of the board, near the analog inputs) is essentially an analog input, and can be used in the same way. The function for the Roboknob is
roboKnob()
This function will return a value between 0 and 65535 (just like an analog input), depending on the position of the knob.
The roboknob is useful for calibration, among other things. For example, if you would like the robot to sleep for a configurable amount of time between zero and 65 seconds, you could simply use the value of the roboknob divided by 1000 as the sleep time. This way, the sleep time could be easily adjusted.
The roboboard has an internal battery voltage monitor which can be used to keep track of the charge level of the battery. The function to read the battery voltage is:
voltage()
This function returns a float, not an integer. The value is the current battery voltage, in Volts.
The battery voltage reading is not exact. There is bias in the battery monitor, and there is some normal variation in the battery voltage as the load changes (as motors turn on and off, for example). However, this function should give you a reasonable estimate of the charge of the battery.
Each of the DC motor ports on the roboboard is connected to a current sensor, which measures the flow of current through the motor. This is an indirect measure of how much load is being put on the motor. The function to read the motor current is:
motorCurrent(int mot)
In this function, mot represents the motor number. The return value is a float, which represents the current through the motor in Amps. The value is only valid when the motor is on full power, as the pulse-width modulation used to produce lower speeds will interfere with the current sensor.
Motor current is very useful for determining if a motor has stalled: when stalled, the current through the motor will increase significantly.
The roboboard maintains an internal clock that is accurate to 5ms (0.005 seconds). The clock functions are the following:
seconds()
mseconds()
sleep(float secs)
msleep(int msecs)
The seconds() functions will return a float which contains the number of seconds since the roboboard last turned on or reset. The mseconds() function is similar, but returns the time as an int which is the number of milliseconds since the board last turned on or reset.
The sleep() function causes the roboboard to wait for the specified
amount of time, in seconds. The program will pause until the time has
elapsed, and then continue. While the board is sleeping, all motors
will continue at their last setting. For example, the following code
will run motor 1 forward for 2.5 seconds and then shut it off:
forward(1); //turn on motor 1
sleep(2.5); //wait for 2.5 seconds--the motor is still running!
off(1); //turn the motor back off
The msleep() function works just the same way as sleep(), but it takes the time specified in milliseconds.
The resolution of the clock is 5 milliseconds, so sleep times are rounded down to the nearest 5ms. For example, sleep(0.016) will actually sleep for 15 milliseconds, not 16. However, the shortest possible sleep interval is 5ms, so sleep(0.001) will sleep for 5 milliseconds, not 1.
The StartTournamentClock() function can be used run the roboboard for precisely 90 seconds, the length of a touranment round. It is required that your roboMain() function call StartTournamentClock() in order to achieve this functionality.
The roboboard has a number of functions to control the motors that
will drive many of the moving parts of the robots. The motors should
be plugged into the motor ports, and these motors should then be
assigned port numbers in the programs written for the robots. Here is
an example of how to do this:
/* Constant Declarations */
int RIGHT_DRIVE_MOTOR = 0; /* assign motor port zero to the right drive motor */
int LEFT_DRIVE_MOTOR = 1; /* assign motor port one to the left drive motor */
int DUMP_TRUCK_MOTOR = 3 /* assign motor port three to the motor that activates the dumping mechanism */
Note that there are only 4 motor ports, numbered 0 through 3, so no motor should be assigned a number larger than 3.
The main functions used to control motors are forward(int m), reverse(int m), off(int m), and alloff().
In all these functions, wherever int m occurs, the name of the motor could also be used. For example, if you wanted to operate the RIGHT_DRIVE_MOTOR, either "0" or "RIGHT_DRIVE_MOTOR" could be put in the function where int m occurs.
forward(int m) turns the motor plugged
into port m on to full speed in the forward direction.
reverse(int m) turns the motor plugged into port m on to full speed in
the reverse direction.
off(int m) will stop the motor plugged into port m.
alloff() will turn all motors off.
motor(int m, int p) allows the speed
of a motor to be controlled. Every motor has speeds that range from
the integer value of -10 to +10. Any negative values represent the
reverse directions, while zero represents a stopped motor. To set the
RIGHT_DRIVE_MOTOR to half speed (a speed of 5), the programmer would
type
motor(RIGHT_DRIVE_MOTOR, 5);
Note that which direction is forward depends on how the motor is plugged in to the port. Reversing the plug will reverse the direction of the motor. It is advisable to plug the motors in such that "forward" is the intuitively forward direction; for example, calling the forward() function on the drive motors should make the robot drive in the forward direction.
The roboboard has three servo connectors, numbered 0, 1, and 2. These are used similarly to the motor ports. However, rather than commanding the motors to a particular speed, servos are commanded to a particular position. The servo itself has an internal sensor that it uses to measure and correct its position.
A standard servo connector has red, black, and white wires. Red is +, black is -, and white is the PWM signal that sets the servo position. Plug the servo in according to the markings on the roboboard (black should be closest to the board edge).
There are three functions to control the servos:
servoEnable(int s) activates the servo plugged into port s.
servoDisable(int s) deactivates the servo plugged into port s.
servoPosition(int s, char p) will move
the servo plugged into port s to position p. The position is a value
between 0 and 255. Zero moves the servo arm all the way to one side,
and 255 to the other. A value of 128 moves the servo to its center
position.
The standard C printf() function will print to the LCD screen. The newline (\n) and tab (\t) characters work slightly differently, however.
To print to the LCD, call printf() as with any other C program:
printf("hello");
If another printf() were to be executed after the previous example, the screen would output it right after "hello". A newline character will clear the display when the next printf() command is given. Right now, the screed says "hello" because of the previous statement. Now, the following is executed:
printf("world\n");
The screen would now have "helloworld" on it, as the earlier statement did not have a \n. Since this one did, if the following were now executed,
printf("New line\n");
the LCD would have "New line" on it. It cleared what was on it before because of the \n. Note: you can clear the screen entirely by printing two \n characters in a row.
The tab (\t) character moves the cursor to the start of the second line of the display. For example, this will print out the value of two sensors, one on each line of the LCD:
printf("Port0: %d\tPort1: %d\n", digital(0), digital(1));
The \t character moves the cursor to the second line, so "Port1" will appear directly below "Port0" on the screen.
Example of printf(...) for debugging: In the following example, two digital inputs are polled inside of a printf(...) function call. This code will execute infintely, since the termination condition inside the while loop is TRUE always. The sleep() function call is necessary since the printf(...) calls will occur so quickly that you will not be able to read the output on the LCD before the output changes.
while(1)
{
printf("Port0: %d\tPort1: %d\n", digital(0), digital(1));
sleep(0.25); // Pause program execution for 1/4 second
}
The roboboard has four built-in LEDs. The blue LED is the heartbeat, and is always blinking twice per second to indicate that the operating system is running. The other three LEDs (red, green, and yellow) are available to use for other purposes. LEDs are particularly valuable for indicating program state; for example, a robot might turn on the red LED when it is following the line, turn on the green LED when it sees the start light, and so on.
There are four functions to control the LEDs:
ledOn(int led) turns on the specified LED
ledOff(int led) turns off the specified LED
ledToggle(int led) turns the specified LED on if it was off, and off if it was on
ledAllOff(int led) turns all LEDs off
For each of these functions, led represents which LED to control. The LEDs are defined as LED_RED, LED_GREEN, and LED_YELLOW. Multiple LED names may be or'd together to control more than one LED at a time. For example,
ledOn(LED_RED); turns on the red LED
ledToggle(LED_GREEN | LED_YELLOW);
toggles the green and yellow LEDs
The piezo beeper built into the roboboard can produce a range of tones. The following are the basic tone functions:
beep() makes a beep at 2400Hz, lasting 0.3 seconds
tone(float freq, float length) generates a tone of the specified frequency and duration
The beep() function is very useful for debugging. With the tone() function, the frequency is in Hertz and the length in seconds. The beeper can handle frequencies of about 750Hz to 5000Hz, although the sound is loudest near 2400Hz.
Music functions to play various songs exist and are located in songs.h. Current, there are two songs implemented. To play the "Charge!" song, simply call the charge() function. Also, you may play the "Pink Panther" theme song by calling the pinkPanther() function.
It is possible to write your own music on the Roboboard. Necessary functions to write songs include setTempo(float temp) and play(char *song). The setTempo function takes a decimal number as an argument, which is interpreted as the song's tempo (the default song tempo is 0.1). the play() function takes a character string as an argument. This string must contain a series of musical notes separated by commas. For example, the Pink Panther song is implemented as the following string:
"1d#,4e,3r,1f#,4g,3r,1d#,3e,1f#,3g,1c,3b,L1e,3g,1b,8bb,2b,2a,2g,2e,2d,10e,7r,1d#,4e,3r,
1f#,4g,3r,1d#,3e,1f#,3g,1c,3b,1g,3b,1e,28eb,L3r,1d#,4e,3r,1f#,4g,3r,1d#,3e,1f#,3g,1c,3b,
L1e,3g,1b,8bb,2b,2a,2g,2e,2d,10e,12r,H3e,1d,3b,1a,3g,1f#,1bb,3a,1bb,3a,1bb,3a,1bb,3a,2g,2e,2d,20e".
The roboboard serial port is normally used for the shell. However, it is possible to print additional information to the serial port for debug purposes. The function uprintf(...) works exactly like the standard C printf(...) function, but directs its output to the serial port.
It is not possible for user programs to read from the serial port, because serial input goes to the shell.
The USB port is not currently available for lego robots.
The wireless interface is not currently available for lego robots.
There are currently no devices for lego robots that use the off-board I2C interface.
There are currently no devices for lego robots that use the off-board SPI interface.
To aid in debugging, the roboboard has a message logging system. To print messages to the log, use logprintf(), which operates the same way as printf(). However, instead of printing to the LCD screen, the message is added to the end of the log.
To read the log, use the shell command "log", which will display the entire contents of the log. To clear the log, use the shell command "log_clear" or call the function logClear().
The roboboard is powered from a single battery, which may be from 7.2V to 16V. The current lego robots batteries are 12V lead-acid cells. The battery cable must be assembled as described in the assembly manual. Proper polarity of the battery cable is critical. Here, "critical" means that parts of the roboboad will explode if you get it wrong. Follow the directions carefully, and have your work checked by a TA or instructor.
It is a good idea to keep your battery charged as much as possible. As the battery discharges, the motors will run more slowly. When the battery is fully depleted, the roboboard may fail in unexpected ways.
There are a number of ways for the roboboard to exert an error condition. For example, attempting to control motor port 5 (which does not exist--the ports only go up to 3) will cause an error. In general, using invalid port numbers, speeds that are out of range, or other commands that the board does not understand will cause an error.
When an error condition occurs, the roboboard will shut down all motors and servos, and it will start blinking all four LEDs. It will also print a descriptive error message to the serial port. Connect the serial cable to a PC and use TeraTerm to read the error message.
The following lists the functions available in the robo library.
void startTournamentClock() Start the tournament clock. This will allow your robot to run for precisely 90 seconds before automatically terminating the program execution.
void printf(...) Print to the LCD screen.
void uprintf(...) Print to the terminal over the serial connection.
void logprintf(...) Print to the log file in the roboboard's dataflash.
void logClear() Purge the log file.
void forward(unsigned int mot) Run motor number "mot" in the forward direction at the maximum speed.
void reverse(unsigned int mot) Run motor number "mot" in the reverse direction at the maximum speed.
void off(unsigned int mot) Turn motor number "mot" off.
void motor(unsigned int mot, int speed) Run motor number "mot" at speed "speed", where speed is between -10 and 10. Note: A negative speed is interpreted by the roboboard as reverse direction, and positive speeds are interpreted as forward.
void allOff() Turn off all motors that may be running.
void ao() Turn off all motors that may be running.
float motorCurrent(unsigned int mot) Returns how much current is drawn by motor number "mot".
void servoEnable(char servo) Enable servo "servo".
void servoDisable(char servo) Disable servo "servo".
void servoPosition(char servo, char position) Move servo "servo" to position "position".
void reallyAllOff(); Turn off all motors and servos that are running .
void ledOn(char leds) Turn on an led.
void ledOff(char leds) Turn off an led.
void ledToggle(char leds) Toggle LEDs.
void ledAllOff() Turn off all LEDs.
int digital(unsigned int port) Read a digital sensor port connected to port number "port". The return value will always be 0 (off) or 1 (on).
unsigned int analog(unsigned int port) Read an analog sensor port connected to port number "port". The return value will always be between 0 and 65535.
int chooseButton() Returns the current position of the choose button. Returns TRUE if the choose button is pressed.
unsigned int dipSwitches() Returns the value of the dip switches.
unsigned int dipSwitch(unsigned int num) Returns the value of dip switch number "num".
unsigned int roboKnob() Read the robo knob.
void encoderStart(unsigned int num) Start encoder number "num".
unsigned int encoderRead(unsigned int num) Returns the current encoder value for encoder number "num".
void encoderStop(unsigned int num) Stop encoder number "num".
void encoderReset(unsigned int num) Reset (set encoder count to 0) encoder number "num".
unsigend int accelerometerX() Returns the value of the accelerometer in the X direction.
unsigend int accelerometerY() Returns the value of the accelerometer in the Y direction.
unsigend int accelerometerZ() Returns the value of the accelerometer in the Z direction.
float voltage() Returns the current battery charge in volts.
float seconds() Returns the current "system time" in seconds.
unsigned int mseconds() Returns the current "system time" in milliseconds.
void sleep(float secs) Pause the program execution for "secs" seconds.
void msleep(unsigned int msecs) Pause the program execution for "msecs" milliseconds.
void tone(float freq, float length) Emit a tone from the onboard speaker of frequency "freq" and length "length".
void beep() Emit a short beep from the onboard speaker.
The following shell commands are available, which correspond
roughly to the functions listed above:
reset
seconds
forward [mot]
reverse [mot]
off [mot]
ao
alloff
motor [mot] [speed]
current [mot]
servo_enable [servo]
servo_disable [servo]
servo_position [servo] [position]
tone [freq] [time]
beep
digital [port]
analog [port]
accelerometerX
accelerometerY
accelerometerZ
voltage
robo_knob
dip_switches
dip_switch [switch]
play [song string]
charge
log
log_clear