Project in progress
Autonomous Arduino Mega Track Robot

Autonomous Arduino Mega Track Robot © GPL3+

This robot uses 4 Sharp IR sensors to wander around the house and avoid running into things.

  • 3,985 views
  • 1 comment
  • 19 respects

Components and supplies

Apps and online services

About this project

I was looking for a fun weekend project with parts I had around the house. In digging through my junk box, I found a track chassis I bought a while back on Amazon just because it looked cool. I figured I'd use it one day. Apparently, this was the day!

I thought an autonomous robot would be fun to build. I've built a few robots in my day with wheels or legs, but never with tracks. So this was my project!

Next I found an Arduino Mega and an old motor shield, so I was off to the races!

I mounted the Mega and the battery holder that came with the chassis using double-sided tape. Then I snapped on the motor shield. The shield can drive 2 DC motors using a handful of digital pins on the Arduino.

Now that I had a drive system, I needed sensors to keep the robot from running into things. Luckily, I had four Sharp IR sensors with 10-80cm range. I needed some way to position them in four directions and mount them to the robot, so I decided to build a sensor shield. I wired the sensors up on a blank shield board and mounted them using Gorilla Glue.

In order to more easily calibrate and troubleshoot my Arduino code on the sensor board, I added an OLED to display sensor readings and the current heading of the robot.

I also decided to add a mini volt meter to the sensor board so I could monitor the battery voltage. That way I'd know when the 18650 lithium batteries were running low. Here's a top view of the completed robot ready for testing.

I played around with the Arduino code to get reasonable response from the sensors and reaction from the motors. I had some problems on different floor surfaces and with one of the motors apparently turning slightly slower than the other. I made quite a few tweaks to my code before I felt pretty good about the results.

It's still not perfect, but does a pretty good job of avoiding collisions while running around the floor. Here's a video of my "kitchen floor test".

Code

Track_RobotC/C++
Arduino code for Track Robot w/ Arduino Mega 2560, motor shield v3, OLED, and Sharp IR sensors
/*** 
 *  Track Robot w/ Arduino Mega 2560, motor shield v3, OLED, and Sharp IR sensors
 *  1-19-2020
 *  by My Parts Chest
 *  https://mypartschest.com
 *  https://mypartschest.blogspot.com/
*/
#include <SharpIR.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SHARP_MODEL 1080 

//global vars
bool startup = false;
bool firstLoop = false;
bool motorsOn = false;
int stopTimer = 0;
String heading = "Unstarted";

//declar OLED pins
const int SDA_PIN = 20;
const int SDC_PIN = 21;

//Declare pins for motor control
const int dirA = 13;
const int dirB = 12;
const int speedA = 11;
const int speedB = 3;
const int brakeA = 8;
const int brakeB = 9;
const int highSpeed = 255;
const int lowSpeed = 240;

// Analog pins for distance sensors
const byte frontSensorPin = A0;
const byte driverSensorPin = A1;
const byte passengerSensorPin = A2;
const byte rearSensorPin = A3;

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Create an object instance of the SharpDistSensor class
SharpIR frontSensor = SharpIR(frontSensorPin, SHARP_MODEL);
SharpIR driverSensor = SharpIR(driverSensorPin, SHARP_MODEL);
SharpIR passengerSensor = SharpIR(passengerSensorPin, SHARP_MODEL);
SharpIR rearSensor = SharpIR(rearSensorPin, SHARP_MODEL);

void setup() {

  // Setup Channel A & B
  pinMode(dirA, OUTPUT); //Init Motor A (rear-driver's side)
  pinMode(dirB, OUTPUT); //Init Motor B (front-passenger's side)
  pinMode(brakeA, OUTPUT); //Init Brake A
  pinMode(brakeB, OUTPUT); //Init Brake B

  // Init display
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  // Display static text
  display.println("Initializing...");
  display.display(); 
  
  delay(1000);
  startup = false;
  firstLoop = true;
  motorsOn = true;
}

void loop() {

  //local vars  
  int frontDistance;
  int driverDistance;
  int passengerDistance;
  int rearDistance;
  
  // Get distance from sensors
  frontDistance = frontSensor.distance();
  driverDistance = driverSensor.distance();
  passengerDistance = passengerSensor.distance();
  rearDistance = rearSensor.distance();

  //update OLED
  updateDisplay(frontDistance, driverDistance, passengerDistance, rearDistance, heading);

  if (startup)
  {      
    if (frontSensor.distance() > 30)
    {
      firstLoop = false;
      heading = "Forward";

      //forward B (front motor)
      move("B", "FWD", highSpeed);            
      //forward A (rear motor)
      move("A", "FWD", lowSpeed); //rear motor is running a little faster than the front motor; so slow it down

      delay(100);
      stopTimer = 0;
    }
    else //less than 30cm; something is in the way
    {
      if (heading == "Forward" && !firstLoop) //make sure this isn't at startup and I'm not already turning
      {
        fullStop(100); //stop during testing to read sensors

        //back up if too close to something
        if (frontSensor.distance() < 10)
        {
          //forward B (front motor)
          move("B", "REV", highSpeed);                
          //forward A (rear motor)
          move("A", "REV", lowSpeed); 
          delay(100);          
        }
                  
        if (passengerSensor.distance() > driverSensor.distance()) //what has more distance, left or right?
        {
          heading = "Turning Right";
          int lastFront = frontSensor.distance();
          
          while (driverSensor.distance() != lastFront)
          {
            updateDisplay(frontDistance, driverDistance, passengerDistance, rearDistance, heading);
            turnRight(500);
            if (frontSensor.distance() > 30)
            {
              break;      
            }         
          }
        }
        else
        {
          heading = "Turning Left";
          int lastFront = frontSensor.distance();
          
          while (passengerSensor.distance() != lastFront)
          {
            updateDisplay(frontDistance, driverDistance, passengerDistance, rearDistance, heading);
            turnLeft(500);
            if (frontSensor.distance() > 30)
            {
              break;      
            }              
          }
        }                      
      }
      else
      {
        stopTimer++;
        if (stopTimer > 100)
        {
          heading = "Stopped";
          fullStop(100);
          //display stopped
          updateDisplay(frontDistance, driverDistance, passengerDistance, rearDistance, "Stopped!");
          exit(0);
        }        
      }
    }
  }
  else //loop forever until I put my hand in front of the forward sensor
  {
    if (frontDistance < 11)
      {
        delay(1000);
        startup = true;
    }
    else
    {
      delay(20);
    }
  }
}

void fullStop(int duration)
{
    move("A", "FWD", 0);
    move("B", "FWD", 0);   
    delay(duration);
}

void turnRight(int duration)
{
    move("A", "FWD", highSpeed);
    move("B", "REV", highSpeed);
    delay(duration);
}

void turnLeft(int duration)
{
    move("A", "REV", highSpeed);
    move("B", "FWD", highSpeed);
    delay(duration);
}

void move(String channel, String direction, int speed )
{
  int motor = dirA;
  int pwm = speedA;
  int brake = brakeA;
  bool highLow = HIGH;

  if (motorsOn)
  {
    if (direction == "REV")
      highLow = LOW;
      
    if (channel == "B")
    {
      motor = dirB;
      pwm = speedB;
      brake = brakeB;
      //reverse directions for motor B
      highLow = !highLow;
    }
  
    if (speed == 0) //brake
    {
      digitalWrite(brake, HIGH);
    }
    else
    {
      digitalWrite(motor, highLow);
      digitalWrite(brake, LOW);
      analogWrite(pwm, speed);
    }    
  }
}

void updateDisplay(int fd, int dd, int pd, int rd, String hd)
{
  //write to OLED
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("Sensor Readings");
  display.setCursor(0, 5);
  display.print("...............");  
  
  // Display sensor readings
  display.setCursor(0, 16);
  display.print("Front: ");
  display.setCursor(45, 16);
  display.print(fd);
  display.print(" cm");
  
  display.setCursor(0, 26);  
  display.print("Left: ");
  display.setCursor(45, 26);  
  display.print(dd);
  display.print(" cm");
  
  display.setCursor(0, 36);  
  display.print("Right: ");
  display.setCursor(45, 36);  
  display.print(pd);
  display.print(" cm");  
  
  display.setCursor(0, 46);  
  display.print("Rear: ");
  display.setCursor(45, 46);  
  display.print(rd);
  display.print(" cm");  

  display.setCursor(0, 56);  
  display.print("Moving: ");
  display.setCursor(45, 56);  
  display.print(hd);  
  
  display.display(); 
}

Comments

Similar projects you might like

Amazing 6WD Off-Road Robot | Arduino RC Robot

Project tutorial by Jithin Sanal

  • 10,000 views
  • 0 comments
  • 54 respects

JQR Quadruped Autonomous Robot ** UPDATE 25/NOVEMBER/2019 **

Project in progress by aldoz

  • 21,023 views
  • 52 comments
  • 161 respects

Line Follower Robot

Project tutorial by Shubham Shinganapure

  • 8,371 views
  • 3 comments
  • 19 respects

Simple Line Follower Robot

Project tutorial by Harsh Dethe

  • 4,382 views
  • 0 comments
  • 10 respects

Scriba Robot - A Printing Robot

Project in progress by RobinB

  • 2,665 views
  • 0 comments
  • 8 respects

Autonomous High Altitude Glider

Project in progress by Abdullah Tarik Agcayazi and kemfic

  • 21,259 views
  • 10 comments
  • 71 respects
Add projectSign up / Login