Arduino Microcontrollers

Language
English
Simpson College
Computer Science

Chapter 3: Robot Car

This robot car is the first arduino-based project that I worked on. I've worked with other microcontrollers such as RoBoard, Freescale, Parallax, and found them to be more frustrating than fun. The Arduino has changed all that.

In the first evening of working with the Arduino, I was able to get an Arduino board to drive some LEDs within just a few minutes. A little more work, and I had motors and servos working.

3.1 Robot Car 1.0

By the third evening, I combined the VEX robot system with the Arduino and had my first autonomous robot using one ultrasonic sensor for obstacle avoidance:

3.2 Robot Car 2.0

As with any software project, the hardware went through iterations and improvements. I made version 2.0 of my robot, so that I could have more breadboard space. There wasn't enough space to prototype new electronics on the first version. In particular, I wanted to add an LCD display and go from one to two ultrasonic sensors for obstacle avoidance:

The ultrasonic sensors had to be polled separately so they did not confuse each other. A bigger issue was the robot no longer turned well. Steering of the robot was done by changing the speed of the back motors. The wheels didn't actually turn. Before, the front wheel would just skid sideways. now the robot was now heavy enough that the front wheel no longer easily skidded sideways, like it did in version 1.0 of my robot.

3.3 Robot Car 2.1

To solve this problem I ordered a different wheel I ordered that solves this problem, by having small rollers on the wheel allowing it to slide sideways. So here is version 2.1 of my robot:



// include the library code:
#include <LiquidCrystal.h>
#include <Servo.h>


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int leftSensorPin = A1;
const int rightSensorPin = A0;
const int leftSensorTrigger = A2;
const int rightSensorTrigger = A3;

Servo servoLeft;
Servo servoRight;
int my_speed = 0;
int last_turn = 1;

void stop()
{
   servoLeft.write(90); 
   servoRight.write(90); 
   my_speed=0;
}

void forward()
{
   servoLeft.write(90-(my_speed*.01*90)); 
   servoRight.write(90+(my_speed*.01*90)); 

}

void partialLeft()
{
   servoLeft.write(80); 
   servoRight.write(150); 
   my_speed=60;
}

void partialRight()
{
   servoLeft.write(30); 
   servoRight.write(110); 
   my_speed=60;
}
void turnLeft()
{
   servoLeft.write(125); 
   servoRight.write(125); 
   my_speed=30;
}

void turnRight()
{
   servoLeft.write(55); 
   servoRight.write(55); 
   my_speed=30;
}

void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("                ");
  pinMode(leftSensorTrigger, OUTPUT);      
  pinMode(rightSensorTrigger, OUTPUT);      
  digitalWrite(leftSensorTrigger, LOW);
  digitalWrite(rightSensorTrigger, LOW);
  
  servoLeft.attach(6); 
  servoRight.attach(7); 
}

void loop() {

  lcd.setCursor(0, 0);    
  
  digitalWrite(leftSensorTrigger, HIGH);
  delay(70);
  digitalWrite(leftSensorTrigger, LOW);
  delay(50);

  int leftSensorValue = analogRead(leftSensorPin); 
  lcd.print("L:  ");
  lcd.print(leftSensorValue);
  lcd.print("  ");

  digitalWrite(rightSensorTrigger, HIGH);
  delay(70);
  digitalWrite(rightSensorTrigger, LOW);
  delay(50);

  int rightSensorValue = analogRead(rightSensorPin); 
  lcd.print("R: ");
  lcd.print(rightSensorValue);
  lcd.print("  ");

  lcd.setCursor(0, 1);

  if( my_speed <= 60 && leftSensorValue > 70 && rightSensorValue > 70 )
     my_speed += 10;
  else if( my_speed < 100 && leftSensorValue > 130 && rightSensorValue > 130 )
     my_speed += 10;
   
  if( leftSensorValue < 30 || rightSensorValue < 30 ) {
    if( last_turn == 1 )
      turnLeft();
    else
      turnRight();
    //stop();
    lcd.print("Stop           ");
  } else if( rightSensorValue < 70 && rightSensorValue < leftSensorValue ) {
    partialLeft();
    last_turn = 1;
    lcd.print("Left           ");
  } else if( leftSensorValue < 70 ) {
    partialRight();
    last_turn = 2;
    lcd.print("Right          ");
  } else {
    forward();
    lcd.print("Forward: ");
    lcd.print(my_speed);
    if( my_speed <= 30 )
      my_speed = 30;
    lcd.print(" ");
  }

}

3.4 Robot Car 3.0

Next, for version 3.0 of the robot, an electronic compass was added. The mechanics of the rear wheels were also redone.

This video shows the robot using the compass to switch between heading east and west in my driveway:

#include <Wire.h>
#include <LiquidCrystal.h>
#include <Servo.h>

#define address 0x60 //defines address of compass

int goal = 90 ;
int tolerance = 20;
int tolerance2 = 4;

int l_speed = 0;
int r_speed = 0;
int iteration_count = 0;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
Servo servoLeft;
Servo servoRight;


void setup(){
  Wire.begin(); //conects I2C
  lcd.begin(16, 2);
  servoLeft.attach(6); 
  servoRight.attach(7); 
  
}

void forward()
{
   servoLeft.write(90+(l_speed*.01*90)); 
   servoRight.write(90-(r_speed*.01*90)); 

}

void loop(){
   byte highByte;
   byte lowByte;
  
   Wire.beginTransmission(address);      //starts communication with cmps03
   Wire.write(2);                         //Sends the register we wish to read
   Wire.endTransmission();

   Wire.requestFrom(address, 2);        //requests high byte
   while(Wire.available() < 2);         //while there is a byte to receive
   highByte = Wire.read();           //reads the byte as an integer
   lowByte = Wire.read();

   int bearing = ((highByte<<8)+lowByte)/10; 
   lcd.setCursor(0, 1);

   bearing = bearing + 90;

   if (bearing > 360)
     bearing -= 360;
   
   iteration_count++;
   if (iteration_count > 50 ) {
     iteration_count = 0;
     if (goal == 90)
       goal = 270;
     else
       goal= 90;
   }
   lcd.print(bearing);
   lcd.print("  ");
   
   int needed_change = bearing - goal;
   if( needed_change < -180 )
     needed_change += 360;
   if( needed_change > 180 )
     needed_change -= 360;
   
   if( needed_change < -1 * tolerance )
   {
     lcd.print("L  ");
     l_speed = 30;
     r_speed = 0;
   } else if (  needed_change > tolerance) {
     lcd.print("R  ");
     l_speed = 0;
     r_speed = 30;
   } else if( needed_change < -1 * tolerance2 ) {
     lcd.print("L  ");
     l_speed = 50;
     r_speed = 20;
   } else if (  needed_change > tolerance2) {
     lcd.print("R  ");
     l_speed = 20;
     r_speed = 50;
   } else {
     lcd.print("F  ");
     l_speed = 50;
     r_speed = 50;
   }
   forward();

   delay(100);

}