Robot Car Experiments

1 Figure out what digitalWrite values you need to use for the robot to go forward, go backward, turn left, and turn right. Fill in the table on the right with the correct values for future reference.

Depending on how you have connected the motor wires, your values might be different from my examples. Remember that to make a motor turn, one input must be LOW and the other input must be HIGH.
Robot movement Input1 Input2 Input3 Input4
stop        
go forward        
go backward        
turn left        
turn right        
2 Write a function call goForward() and put in the code to make the robot go forward. You might need to replace the values in the digitalWrite commands with those that you obtained from the previous step.
void goForward() {
  digitalWrite(Input1, HIGH);
  digitalWrite(Input2, LOW);
  digitalWrite(Input3, HIGH);
  digitalWrite(Input4, LOW);
}
3 Write a function call stopMotor() and put in the correct code to make the robot stop.
void stopMotor() {
  digitalWrite(Input1, LOW);
  digitalWrite(Input2, LOW);
  digitalWrite(Input3, LOW);
  digitalWrite(Input4, LOW);
}
4 Write a function call goBackward() and put in the correct code for the robot to go backward.
5 Write a function call turnLeft() and put in the correct code for the robot to turn left.
6 Write a function call turnRight() and put in the correct code for the robot to turn right.
7 Write the code to make your robot go forward for one second, then turn left for another second, and then stop just like before but by calling the goForward(), turnLeft(), and stopMotor() functions that you have created.

Also test to make sure that the remaining two functions, goBackward() and turnRight(), are correct.
// connections for motor 1
int Input1 = 6;   // Input 1, must be one of the PWM ~ pins
int Input2 = 5;   // Input 2, must be one of the PWM ~ pins
// connections for motor 2
int Input3 = 9;   // Input 3, must be one of the PWM ~ pins
int Input4 = 10;  // Input 4, must be one of the PWM ~ pins

void stopMotor() {
  digitalWrite(Input1, LOW);
  digitalWrite(Input2, LOW);
  digitalWrite(Input3, LOW);
  digitalWrite(Input4, LOW);
}

void goForward() {
  digitalWrite(Input1, HIGH);
  digitalWrite(Input2, LOW);
  digitalWrite(Input3, HIGH);
  digitalWrite(Input4, LOW);
}

void turnLeft() {
  digitalWrite(Input1, LOW);
  digitalWrite(Input2, HIGH);
  digitalWrite(Input3, HIGH);
  digitalWrite(Input4, LOW);
}

void setup() {
   // controls for motor 1
   pinMode(Input1, OUTPUT);
   pinMode(Input2, OUTPUT);
   // controls for motor 2
   pinMode(Input3, OUTPUT);
   pinMode(Input4, OUTPUT);

  goForward();
  delay(1000);
  turnLeft();
  delay(1000);
  stopMotor();
}

void loop() {
}
8 Add an ultrasonic sensor so that your robot can detect an object in front.

Make the following connections for the sensor (the wires are not shown in the picture):
  • Align the sensor so that the Vcc pin on the sensor is in the same column as the Vcc pin 16 of the L293D chip. The sensor must be facing the front of the robot.
  • Connect the Trig pin to pin 11 on the Arduino.
  • Connect the Echo pin to pin 12 on the Arduino.
  • Connect the GND pin to the blue row on the breadboard.
Ultrasound connections
Make the robot backup and turn around when it detects an object. Here's part of the code that you need.

Notice that the if command tests the distance for greater than 0 and less than 27. We also want to test for greater than 0 because the distance sensor sometimes give erronous negative values.
void loop() {
  int d = distance();     // get the distance to object
  if (d > 0 and d < 27) {  // check for object less than 27
    stopMotor();          // stop, backup, and then turn left
    delay(100);
    goBackward();
    delay(500);
    turnLeft();
    delay(500);
    stopMotor(); 
    delay(100);    
  } else {
    goForward();          // continue to go forward
  }
}
9 In the above code, after backing up, the robot will always turn left. Use the random(0, 2) function to randomly generate a number between 0 and 1 inclusive. This is similar to flipping a coin. If the number is a 0 then turn left, otherwise turn right.
      // randomly generate a number between 0 and 1 inclusive
      if (random(0,2) == 0) {  // test if the number is a 0
         turnLeft();   // turn left if it is a 0
      } else {
         turnRight();  // turn right if it is a 1
      }
10 Be creative and make your robot do something interesting.
  • Make your robot dance to music.
  • Make your robot move around without hitting things
  • Put flashing lights on your robot
  • ...

Something to watch out for...
  • If the robot keeps reseting and starts executing the program from the beginning, most likely it is because the batteries are getting weak. Change new batteries.
  • Use of the tone command will interfere with the analogWrite command on pins 3 and 11. This means that you cannot use the analogWrite command on pins 3 and 11, and use the tone command at the same time.
  • Use of the Servo motor commands will interfere with the analogWrite command on pins 9 and 10. This means that you cannot use the analogWrite command on pins 9 and 10, and use the Servo commands (even if not at the same time).
Advance coding for your robot...
11 The following are extra advance code that you might want to use for your robot.
In order for your robot to do several things at once such as check the distance, blink a led and sound the buzzer, you cannot use a long delay in the loop routine. For example if you use a one second delay to adjust the flashing rate of a led then during this delay you are not checking for the distance and so the robot might hit the wall. So instead of using the delay command, you will use a counter. When the counter reaches a certain count, you will do whatever you want such as flash the led. If the counter has not reached that count then it continues with doing something else instead of waiting there.

A counter that most people use is the millis() command which counts the number of milliseconds. The code on the right shows an example of using the millis() command to flash a led every 1/2 a second and play a note every second. Notice that the code does not use the delay() command.
int led = 13;
int buzzer = 7;

int NOTE_C4 = 262;
int NOTE_D4 = 294;
int NOTE_E4 = 330;
  
unsigned long ledStartCount = 0;     // to count the elapse time for blinking the led
unsigned long buzzerStartCount = 0;  // to count the elapse time for playing a note

void setup() {
  pinMode(led, OUTPUT);
  pinMode(buzzer, OUTPUT);
}

void loop() {
  // flash the led every 1/2 second
  // millis() is the current count
  // so millis() - ledStartCount gives the difference in the count or the elapse time
  if (millis() - ledStartCount < 250) {  // turn on led for 250 millisecond (count from 0 to 250)
    digitalWrite(led, HIGH);
  } else if (millis() - ledStartCount < 500) { // turn off led for 250 millisecond (count from 250 to 500)
    digitalWrite(led, LOW);    
  } else {
    ledStartCount = millis(); // remember new start count
  }

  // play a note every 1 second
  if (millis() - buzzerStartCount < 1000) {
    tone(buzzer, NOTE_C4);
  } else if (millis() - buzzerStartCount < 2000) {
    tone(buzzer, NOTE_D4);
  } else if (millis() - buzzerStartCount < 3000) {
    tone(buzzer, NOTE_E4);
  } else {
    buzzerStartCount = millis(); // remember new start count
  }
}
12 The code on the right is to flash the red and blue lights and play the siren at the same time. This is part of the police car robot code given in step 13 below.

The flashRedBlue() function will flash two LEDs without affecting the delay in the main loop. It flashes the leds every 200 milliseconds. Note that there is no delay command in this function. The function returns immediately if the time is not up for doing the next flash. This is the most important thing.

You call the flashRedBlue() function in your main loop routine.

The siren() function will generate a police siren without affecting the delay in the main loop. It plays the next note every 10 milliseconds. Note that there is no delay command in this function. The function returns immediately if the time is not up for playing the next note. This is the most important thing.

You call the siren() function in your main loop routine.

To make the siren sound correctly, the timing inside the main loop routine is very important, and this is affected mainly by the call to the distance function. You need to add the number 5000 in the pulseIn command in the distance function as shown next:

int duration = pulseIn(echoPin, HIGH, 5000);

The number 5000 tells the pulseIn command to return a 0 if it doesn't hear the echo within 5000 microseconds.
int red_led = 13;
int blue_led = 1;
int buzzer = 7;

unsigned long ledStartCount = 0;     // to count the elapse time for blinking the led
bool redOn = true;        // a flag to remember whether the red led is currently on or not 

void flashRedBlue() {
  if (millis() - ledStartCount > 200) { // flash leds every 200 milliseconds
    ledStartCount = millis();           // reset start time for next cycle
    digitalWrite(red_led, redOn);
    digitalWrite(blue_led, !redOn);
    redOn = !redOn; // flip value
  }
}

unsigned long buzzerStartCount = 0;  // to count the elapse time for playing a note
int frequency = 650;      // starting siren frequency
bool goingUp = true;      // a flag to remember whether the siren is going up or down

void siren() {
  if (millis() - buzzerStartCount > 10) { // play note every 10 milliseconds
    buzzerStartCount = millis();          // reset start time for next cycle
    tone(buzzer, frequency);
    if (goingUp == true) {
      frequency++;                // increment frequency for going up
      if (frequency == 900) {     // reached the top?
        goingUp = false;          // change direction
      }
    } else {                      // for going down
      frequency--;                // decrement frequency for going down
      if (frequency == 650) {     // reached the bottom?
        goingUp = true; 
      }
    }
  }
}

void setup() {
  pinMode(red_led, OUTPUT);
  pinMode(blue_led, OUTPUT);
  pinMode(buzzer, OUTPUT);
}

void loop() {
//  int d = distance();     // get the distance to object
//  if (d > 0 and d < 27) {  // check for object less than 27
//    stopMotor();          // stop, backup, and then turn left
//    delay(100);
//    goBackward();
//    delay(500);
//    turnLeft();
//    delay(500);
//    stopMotor(); 
//    delay(100);    
//  } else {
//    goForward();          // continue to go forward
//  }
  flashRedBlue();
  siren();
  delay(1);   // one millisecond each time round the loop
}
13 Here's the complete police car robot code with siren and flashing leds. The following table shows all the pin connections that you need to make.

Device Arduino
Motor in1 (pin 2) pin 6
Motor in2 (pin 7) pin 5
Motor in3 (pin 10) pin 9
Motor in4 (pin 15) pin 10
Ultrasonic sensor Trig pin 11
Ultrasonic sensor Echo pin 12
Buzzer pin 7
red LED pin 13
blue LED pin 1

Robot car
14 Here's the complete Ring Around the Rosy robot code. The following table shows all the pin connections that you need to make.

Device Arduino
Motor in1 (pin 2) pin 6
Motor in2 (pin 7) pin 5
Motor in3 (pin 10) pin 9
Motor in4 (pin 15) pin 10
Ultrasonic sensor Trig pin 11
Ultrasonic sensor Echo pin 12
Buzzer pin 7
red LED pin 13
green LED pin 4
white LED pin 3
yellow LED pin 2
blue LED pin 1
15 Here's the complete Robot Dance code. The following table shows all the pin connections that you need to make.

Device Arduino
Motor in1 (pin 2) pin 6
Motor in2 (pin 7) pin 5
Motor in3 (pin 10) pin 9
Motor in4 (pin 15) pin 10
Ultrasonic sensor Trig pin 11
Ultrasonic sensor Echo pin 12
Buzzer pin 7
red LED pin 13
green LED pin 4
white LED pin 3
yellow LED pin 2
blue LED pin 1
16 Here's the complete Advance Robot Car Demo code. The following table shows all the pin connections that you need to make.

Device Arduino
Motor in1 (pin 2) pin 6
Motor in2 (pin 7) pin 5
Motor in3 (pin 10) pin 9
Motor in4 (pin 15) pin 10
Ultrasonic sensor Trig pin 11
Ultrasonic sensor Echo pin 12
Buzzer pin 7
red LED pin 13
green LED pin 4
white LED pin 3
yellow LED pin 2
blue LED pin 1