mikesoniat
Published © GPL3+

Autonomous Arduino Mega Track Robot

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

BeginnerWork in progress4 hours16,790
Autonomous Arduino Mega Track Robot

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
Arduino Motor Shield Rev3
×1
DFRobot Black Gladiator - Tracked Robot Chassis
×1
SHARP GP2Y0A21YK0F
×4
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
0.96" SSD1306 128X64 Yellow & Blue OLED LCD Display with I2C IIC SPI Serial
×1
Capacitor 100 µF
Capacitor 100 µF
×1
Volt Meter, Mini 3-Wire
Volt Meter, Mini 3-Wire
×1
Battery Holder, 18650 x 2
Battery Holder, 18650 x 2
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Track_Robot

C/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(); 
}

Credits

mikesoniat

mikesoniat

6 projects • 19 followers
I've been an electronics hobbyist, hacker, maker for as long as I can remember. My current passions are robotics, AI, and machine learning.

Comments