Understanding the Build Your First Robot Sketch

Extended comments on the code


Here's a closer look at the inner workings of the Arduino code for the Build Your First Robot.

#include <IRremote.h>
#include <Servo.h>
#include "pitches.h"

These lines of code include (insert) three additional files, which provide extra features to the sketch.

  • IRremote is a third-party object library that must be added to the /libraries directory in your Arduino sketchbook folder. An Arduino 1.0 compatible version of this library is provided with the sketch. You can also download it from its source, Multi-Protocol Infrared Remote Library for the Arduino. If you are using the Arduino 1.0 IDE be sure the library you get is compatible with it!
  • Servo is an object library that's included with the Arduino environment. It operates one or more radio control servo motors.
  • pitches.h is a simple text file file of pre-defined numeric constants; these constants are easy-to-remember words with numeric values to make it easier to specify a note to play through the speaker. The pitches.h file is located with the sketch.
Servo servoLeft;
Servo servoRight;

These two lines are object constructors; they define two Servo objects that represent the physical servo motors on the robot. The names of the objects -- servoLeft and servoRight -- are descriptive to help you follow what they are for.

int RECV_PIN = 5;
IRrecv irrecv(RECV_PIN);
decode_results results;

In these lines the code sets up the infrared receiver, which allows the robot to be commanded by an IR TV/VCR remote. Note that the receiver input is connected to pin D5.

volatile int pbLeft = LOW;
volatile int pbRight = LOW;
boolean started = false;

Each of these lines define a variable used elsewhere in the sketch. Variables are temporary holders of data that can be re-used.  The int and boolean keywords specify the kind of variable; int means a 16 bit (two byte) integer (whole number), and boolean means a true/false (yes or no). The volatile keyword is commonly used when sharing variables with interrupt functions (see the text below on interrupts).

void setup() {

Every Arduino sketch must contain a setup function. In this function go any programming statements that literally set up the Arduino before things get going. The statements are executed only once.

pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, OUTPUT);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, LOW); 

The two bumper switches on the front of the robot are connected to Arduino pins D2, D3, and D4. These code lines use the pinMode statement to specify pins D2 and D3 are inputs, and D4 is an output. They then use the digitalWrite statement to indicate whether the pins are LOW (0V) or HIGH (5V).

Though pins D2 and D3 are inputs, they're made HIGH to set their internal pullup resistor. This is necessary for proper operation of the switches.

Finally, pin D4 is made LOW so that it acts as a 0V reference for the switches.

pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
digitalWrite(6, LOW);
digitalWrite(7, HIGH);

Here more pins are set set as outputs. Pin D6 is made LOW to act as 0V ground; pin D7 is made HIGH to act as 5V power.

pinMode(12, OUTPUT); 
digitalWrite(12, LOW);

These lines define pin D12 as a 0V ground connection to the piezo speaker. The other lead of the piezo speaker connects to pin D13.

servoLeft.attach(10);
servoRight.attach(9);

The two lines of code tell the Arduino that D10 and D9 are set to drive servo motors.

irrecv.enableIRIn();
Serial.begin(9600);

This starts the infrared receiver, and begins serial connection back to the PC. Messages sent from the Arduino are received into the Serial Monitor window. The messages are used to check proper operation (debug) of the sketch.

attachInterrupt(0, hitRight, FALLING);
attachInterrupt(1, hitLeft, FALLING);

The bumpers on the front of the robot use an Arduino feature known as hardware interrupts to determine when the switches are activated. Interrupts literally "interrupt" the action of the sketch to take time out to run some specified piece of code.

  • 0 and 1 specify the interrupt number (0 = pin D2, 1 = pin D3)
  • hitRight and hitLeft are the sketch functions that are called when an interrupt occurs
  • FALLING is a directive that tells the Arduino to trigger the interrupt when the signal to pin D2 or D3 falls; that is, changes from HIGH to LOW.
void loop() {

Every Arduino sketch must include a loop function. Inside this function are the programming statements that repeat over and over again as the robot operates.

if (pbLeft == HIGH) {
  int tones[] = {NOTE_C4,  NOTE_B3, NOTE_C4};
  int toneDurations[] = {4,4,4};
  reverse();
  makeTone(tones, toneDurations, sizeof(tones)/sizeof(int));
  delay(500);
  spinRight();
  delay(1500);
  forward();
  pbLeft = LOW;
  Serial.println("pbLeft");
}

This if test structure commands the Arduino to go through a series of steps if the left bumper switch is activated. The code first defines some musical notes to play, and sets the robot in reverse. After a short 1/2 second delay -- using delay(500) -- the robot spins right, waits another 1.5 seconds, then goes forward again.

A separate if test determines when the right bumper switch is activated.

if (irrecv.decode(&results)) {
  switch (results.value) {
    case 0x10:
      Serial.println("1");     // Turn left forward
      turnLeftFwd();
      break;

These lines of code check to see if there's any recent commands sent from the infrared remote control. If there are, the sketch matches the command value received, then operates the robot accordingly.

For example, if the code is hexadecimal 10 (shown as 0x10), then the robot turns left while going forward. As a visual check (and if the robot is attached to your PC via the USB cable), the code also displays in the Serial Monitor window a “1” -- for button 1 on the remote.  Buttons 2 through 9 are likewise matched. Each button makes the robot do something different.

void makeTone(int tones[], int toneDurations[], int length)
...

makeTone is a user-defined function. It sounds one or more tones through the piezo speaker attached to pins 12 and 13. The code is a bit elaborate, and more than can be described here. For a detailed description see the Tone example provided on the arduino.cc Web site.

void forward() {
  servoLeft.write(180);
  servoRight.write(0);
}

The forward function is one of several motion control routines that operate the two servos to move the robot. Each servo is command to a specific position, either 0, 90, or 180:

  • 0 makes the servo turn continuously in one direction
  • 90 makes the servo stop
  • 180 makes the servo turn continuously in the other direction
void hitLeft() {
  if (started)
    pbLeft = HIGH;
}

The hitLeft function is automatically called when the left bumper is activated. The function sets a variable, pbLeft, to HIGH. This variable is checked each time the Arduino goes through the loop function. A separate function, hitRight, is for the right bumper.