Roaming Robot Update

robot1

My Roaming robot has recently been giving me some problems, specifically regarding the power distribution between the 2 motors (with one wheel sporadicly turning faster than the other). I initially thought that one of the motors might have been damaged so I replaced both, only to have the problem remain. After some testing and replacing both the Pololu Dual MC33926 Motor Driver Shield and the Arduino Uno R3, I determined that the problem lay with the Pololu Motor shield. I am not sure if one of the other sensors or actuators was causing some interference on the shield or if it is simply a design flaw in the shield, but I found it impossible to balance the power of the 2 motors. 

I thus decided to replace the Pololu Dual MC33926 Motor Driver Shield with a Pololu DRV8833 Dual Motor Driver Carrier, and this resolved the problem I was experiencing. 

Here the Pololu Dual MC33926 Motor Driver Shield and the Pololu DRV8833 Dual Motor Driver Carrier can be seen side by side (the  Pololu DRV8833 Dual Motor Driver Carrier being the much smaller of the 2): 

motordrivers

I mounted the Motor driver on a bread board, attached on top of an Adafruit Proto-shield. This has the added benefit of having screw terminals for the Arduino pins, so that the jumper cables can no longer accidentally become dislodged.

Proto      protodriver

To install the new DRV8833 Motor Driver I had to switch some of the pin usage on the Arduino in order to free up some PWM digital pins needed by the motor driver. The new Layout is as follows:

Analog Pins:

  • A0 
  • A1 
  • A2 – Servo 
  • A3
  • A4 – IR Sensor
  • A5 – Photo-resistor

Digital Pins:

  • 0
  • 1
  • 2 – LED
  • 3 – Motor Driver B IN 1
  • 5 – Motor Driver B IN 2
  • 6 – Motor Driver A IN 1
  • 7 – Ultrasonic Sensor
  • 8 – Right Trigger Switch
  • 9 – Motor Driver A IN 2
  • 10 
  • 11 – Left Trigger Switch
  • 12 
  • 13

Here are the updated drawings illustrating the wiring of the different components:

robot 1_bb

robot part 2_bb

robot part 3_bb2


I also replaced some of the wiring to the Ultrasonic sensor as they had become worn due to the “neck movement” of the servo pointing the sensor in different directions.

I also ran the power for the Ultrasonic sensor straight from the Arduino and no longer via the Proto-board, this was simply to give the cables a bit more play for the “neck movement” performed by the servo.

After these changes the little guy is working perfectly again.

I will be posting a video of this robot in action in the near future.

Here is the updated code for the robot:


#include "Servo.h" 

#define IR_PIN A4
#define SERVO_PIN A2
#define PING_PIN 7
#define BUMPER_LEFT_PIN 11
#define BUMPER_RIGHT_PIN 8
#define LDR_PIN A5
#define LED_PIN 2
#define IR_DROP 500 //Distance considered a potential drop
#define MIN_LIGHT 300 //Level of light to turn on LED for light
#define BIN_1  3
#define BIN_2  5
#define AIN_1  6
#define AIN_2  9
#define MAX_PWM_VOLTAGE  150

int IRDist = 0; 
int bpLeft = 0; 
int bpRight = 0; 
int LDRValue = 0;
const int dangerThresh = 16;// (in cm) used for obstacle avoidance
int leftDistance, rightDistance; //distances on either side
Servo panMotor; //'neck' servo 
long duration; //time it takes to recieve PING signal

void setup()
{
  Serial.begin(9600); //used for serial communication for debugging 
  pinMode(BUMPER_LEFT_PIN,INPUT);
  pinMode(BUMPER_RIGHT_PIN,INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BIN_1, OUTPUT);
  pinMode(BIN_2, OUTPUT);
  pinMode(AIN_1, OUTPUT);
  pinMode(AIN_2, OUTPUT);
}

void moveStop()
{
  digitalWrite(BIN_1, LOW);
  digitalWrite(BIN_2, LOW);
  digitalWrite(AIN_1, LOW);
  digitalWrite(AIN_2, LOW);
}

void moveForward()
{
  digitalWrite(BIN_1, LOW);
  analogWrite(BIN_2, MAX_PWM_VOLTAGE);
  analogWrite(AIN_1, MAX_PWM_VOLTAGE);
  digitalWrite(AIN_2, LOW);
  delay(300);
}

void turnLeft()
{
  digitalWrite(BIN_1, LOW);
  analogWrite(BIN_2, MAX_PWM_VOLTAGE);
  digitalWrite(AIN_1, LOW);
  analogWrite(AIN_2, MAX_PWM_VOLTAGE);
  delay(300); 
}

void turnRight()
{
  analogWrite(BIN_1, MAX_PWM_VOLTAGE);
  digitalWrite(BIN_2, LOW);
  analogWrite(AIN_1, MAX_PWM_VOLTAGE);
  digitalWrite(AIN_2, LOW);
  delay(300);
}

void moveBack()
{
   analogWrite(BIN_1, MAX_PWM_VOLTAGE);
   digitalWrite(BIN_2, LOW);
   digitalWrite(AIN_1, LOW);
   analogWrite(AIN_2, MAX_PWM_VOLTAGE);
   delay(500); 
}

int checkDrop()
{
  pinMode(IR_PIN,INPUT);
  IRDist = analogRead(IR_PIN);    
  //Serial.println(IRDist);
  if(IRDist < IR_DROP) 
  { 
    return 1; //Drop present (determined with IR distance sensor)
  }
  else
  {
    return 0;
  }
}

void lightDarkness()
{
 LDRValue = analogRead(LDR_PIN);
 if(LDRValue < MIN_LIGHT)
  {
      digitalWrite(LED_PIN,HIGH); //It is dark, turn on the light
  }
  else
  {
    digitalWrite(LED_PIN,LOW);
  }
}

int checkLeftBumper()
{
  bpLeft = digitalRead(BUMPER_LEFT_PIN);
  if(bpLeft == HIGH)
  {  
    //Serial.println("Left Bumper");
    //HIT!
    return 1;
  }
  else
  {
    return 0;
  }
}

int checkRightBumper()
{
   bpRight = digitalRead(BUMPER_RIGHT_PIN);
  if(bpRight == HIGH)
  {
    //Serial.println("Right Bumper");
    //HIT!
    return 1;
  }
  else
  {
    return 0;
  }
}

void compareDistance()
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    turnLeft();
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    turnRight();
  }
   else //if they are equally obstructed
  {
    moveBack();
  }
}

long ping()
{
  // Send Ping pulse
  pinMode(PING_PIN, OUTPUT);
  digitalWrite(PING_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(PING_PIN, HIGH);
  delayMicroseconds(5);
  digitalWrite(PING_PIN, LOW);
  
  //Get duration it takes to receive echo of Ping sent
  pinMode(PING_PIN, INPUT);
  duration = pulseIn(PING_PIN, HIGH);
  
  //Convert duration into distance (cm)
  return duration / 29 / 2;
}

void loop()
{
  
  lightDarkness();
  if(checkDrop() == 1)
  {
    moveBack();
    moveBack();
    moveBack();
    turnRight();
  }
  else
  if(checkLeftBumper() == 1)
  {
    moveBack();
    turnRight();
  } 
  else if(checkRightBumper() == 1)
  {
    moveBack();
    turnLeft();
  } 
  else
  {
  moveStop();
  int distanceFwd = ping();
  //Serial.println(distanceFwd);
  if (distanceFwd>dangerThresh) //if path is clear
  {
   moveForward();
  }
  else //if path is blocked
  {
    moveStop();
    
    panMotor.attach(SERVO_PIN);
    panMotor.write(20); //look right

    delay(400);
    
    rightDistance = ping(); //scan to the right
    panMotor.write(160); //look left

    delay(550);
    
    leftDistance = ping(); //scan to the left
    panMotor.write(90); //look to center

    delay(400);
    
    panMotor.detach();
    compareDistance();
  }
  }
}
Roaming Robot Update

One thought on “Roaming Robot Update

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s