The Geek So Far – A Work In Progress

This post is a quick update on the Geek robot build so far. A fair amount of trial and error and a bit of experimentation has consumed a lot of my time in the construction thus far. I believe this build will still take a long time because of the vast amount of tasks that still needs to be completed.

robot

So here is a quick view of the robot so far.

The robot has a total of 14 servos that are allocated as follows:

  • Two micro servos (1.3kg per cm) in the neck in a mini pan tilt plastic mounting.
  • Two servos (one metal gear 20kg per cm and one 18kg per cm) in the robot waist in a pan tilt metal mounting.
  • Each arm has three servos (a 18kg per cm servo in the shoulder and two 1.3kg per cm micro servos for the rest of the arm movement).
  • Each leg consists of two servos (18kg per cm).

arm lower body  foot

The robots’ head contains two cameras, an Arduino 2 mega pixel camera for static images and a Logitech web cam for video (I removed the web cam housing as it
was too bulky).

The robots’ feet are aluminium housings that will contain the batteries that will power the robot. This is to keep the weight at the bottom of the robot, thus helping to balance it. I am still investigating the exact battery configuration to use as I would prefer a rechargeable option.

I used a fair amount of Timiya universal metal joints during the assembly so far and these are very handy in building any robot.

The robot currently has two ultrasonic sensors and one infrared distance sensor. The ultrasonic sensors are mounted on the front of the feet for obstacle detection and the infrared distance sensor is mounted on the front of the robots’ hips and will be used to detect vertical drops.

I plan to mount another ultrasonic sensor and infrared distance sensor on the robots’ back, to allow for the robot to avoid obstacles when it moves backwards.

The robot has a laser diode attached to its one arm, which I intend to use for pointing as well as a point of reference for the webcam.

The next task I will be undertaking will be to start wiring the robot to the Arduino Mega R3 and Raspberry Pi 2 that I intend to use to control the robot. I will post more blog updates as progress on this robot advances.

The Geek So Far – A Work In Progress

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

Pololu Zumo Robot

I recently ordered a Zumo robot shield manufactured by Pololu and found it to be a great little robot.

It comes preassembled and has various integrated sensors and actuators, including a 3-axis accelerometer, a 3-axis magnetometer, a Buzzer, a motor driver, an IR reflective sensor array, amongst others.

It comes with 2 75:1 HP micro metal gear motors, so it has a fair amount of power for such a small robot. The robot is within the 10cm x 10cm size limit of most robot sumo competitions, and with its very low centre of gravity combined with its speed and power it would be a serious competitor.

sideFront

An Arduino Uno R3 acts as the robots’ brain and simply slots onto the top of the robot, exactly like any other shield. All programs are then loaded onto the Arduino Uno as per normal and Pololu provides various example programs, including line following, maze solving and robot sumo programs.

  

The robot has an expansion area through which some pins are exposed that can be used to integrate some additional sensors and actuators.

I am looking forward to customising this robot and seeing how much more I can expand it.

I will write more about what I am doing with this robot in a future post and I will also be posting a video of the robot in action on my Youtube Channel in the near future.

Pololu Zumo Robot

Roaming Robot

Robot4

Today we will take a detailed look at my Roaming Robot.

Part List:

  • Sparkfun Magician Chassis (this includes 2 DC motors)
  • 1 x Capacitors 100uF
  • 4 x Resistors 220 Ohm
  • 1 x Micro Servo
  • Seeed Ultrasonic Sensor
  • Sharp IR Sensor
  • 2 x Long Arm Trigger Switches
  • 1 x LED (ultra bright white)
  • 1 x Photo-resistor
  • 1 x Arduino Uno R3 
  • 1 x Pololu Dual MC33926 Motor Driver Shield

Power supply:

  • 1 x 9V Battery (used to power the 2 DC motors through the motor shield)
  • 4 x AA Batteries in a battery holder (used to power Arduino and PCB\Breadboard)

The Pololu Dual MC33926 Motor Driver Shield plugs into the Arduino female headers and all connectors shown in below diagrams actually plug into the Motor shield and not directly into the Arduino as shown.

Arduino  ArduinoArduino

The first diagram shows the wiring for the LED, photo-resistor, trigger switches, and the servo:

robot part 1_bb

The two switches shown are actually the 2 long arm trigger switches.

switch

The circuit shown above is very straightforward. However note the capacitor across the servo power terminals. This is to prevent a voltage drop in the circuit caused by the servo starting to move, which draws more current to start moving than when it is already moving.

The below diagram shows how the Seeed Ultrasonic and Sharp IR sensors are wired:

robot part 2_bb

So the Arduino is wired as follows (through the motor driver female headers):

Analog Pins:

  • A0 – this pin is used by the MC33926 Motor shield
  • A1 – this pin is used by the MC33926 Motor shield
  • A2 – Servo 
  • A3
  • A4 – IR Sensor
  • A5 – Photo-resistor

Digital Pins:

  • 0
  • 1
  • 2
  • 3 – LED
  • 4 – this pin is used by the MC33926 Motor shield
  • 5 – Ultrasonic Sensor
  • 6 – Right Trigger Switch
  • 7 – this pin is used by the MC33926 Motor shield
  • 8 – this pin is used by the MC33926 Motor shield
  • 9 – this pin is used by the MC33926 Motor shield
  • 10 – this pin is used by the MC33926 Motor shield
  • 11 – Left Trigger Switch
  • 12 – this pin is used by the MC33926 Motor shield
  • 13

The Arduino VDD (5V) and GND pins are used to power the PCB\Breadboard.

robot4 robot1robot2

The Servo acts as the robots’ neck, it can turn the Ultrasonic Sensor in various directions. The Ultrasonic Sensor is used to detect obstructions, which the robot will then avoid, for obstructions too low for the Ultrasonic Sensor to detect the trigger switches will be pressed and the object can then be avoided. The Photo-resistor is used to detect light level and if it is deemed too dark the LED will turn on. The IR sensor is used to detect drops, so that the robot does not fall down a vertical drop, such as a step.

The two DC motors of the Magician Chassis are connected to the Motor shield, the left motor to the two most left screw terminals on the shield and the right motor to the two most right screw terminals on the shield. The 2 middle screw terminals on the shield are used to power the motors; the 9V battery should be connected to them. (Just note that if one or both of the robots’ motors move in the opposite direction than expected, this can be rectified by switching the 2 motor wires around between the screw terminals they are connected to on the motor shield.)

Here is the code used with the Robot (it is written in C and must be deployed on the Arduino):

#include "DualMC33926MotorShield.h"
#include "Servo.h"

#define IR_PIN A4
#define SERVO_PIN A2
#define PING_PIN 5
#define BUMPER_LEFT_PIN 11
#define BUMPER_RIGHT_PIN 6
#define LDR_PIN A5
#define LED_PIN 3
#define IR_DROP 450 //Distance considered a potential drop
#define MIN_LIGHT 300 //Level of light to turn on LED for light

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

void setup()
{
pinMode(BUMPER_LEFT_PIN,INPUT);
pinMode(BUMPER_RIGHT_PIN,INPUT);
pinMode(LED_PIN, OUTPUT);
}

void moveStop()
{
md.init();
md.setSpeeds(0,0);
}

void moveForward()
{
md.init();
moveStop();
md.setSpeeds(M1Speed,M2Speed);
delay(250);
}

void turnLeft()
{
md.init();
moveStop();
md.setSpeeds(M1Speed,-M2Speed);
delay(250);
}

void turnRight()
{
md.init();
moveStop();
md.setSpeeds(-M1Speed,M2Speed);
delay(250);
}

void moveBack()
{
md.init();
moveStop();
md.setSpeeds(-M1Speed,-M2Speed);
delay(250);
}

int checkDrop()
{
pinMode(IR_PIN,INPUT);
IRDist = analogRead(IR_PIN);
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)
{
//HIT!
return 1;
}
else
{
return 0;
}
}

int checkRightBumper()
{
bpRight = digitalRead(BUMPER_RIGHT_PIN);
if(bpRight == HIGH)
{
//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();
compareDistance();
}
else
if(checkLeftBumper() == 1)
{
moveBack();
compareDistance();
}
else if(checkRightBumper() == 1)
{
moveBack();
compareDistance();
}
else
{
moveStop();
int distanceFwd = ping();

if (distanceFwd>dangerThresh) //if path is clear
{
moveForward();
}
else //if path is blocked
{
moveStop();

panMotor.attach(SERVO_PIN);
panMotor.write(20); //look right

delay(250);

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

delay(600);

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

delay(300);

panMotor.detach();
compareDistance();
}
}
}
Roaming Robot

Boards, Boards Everywhere

Currently there are numerous Arduino and Arduino compatible boards available, this post will do a quick comparison between 3 of these boards (Arduino UNO R3, Arduino Mega R3 and the Beetle which is a shrunk down version of the Arduino Leonardo) and then also a quick comparison between Arduino and Raspberry Pi Board Families.

The below picture illustrates the size difference between the Arduino boards:

Arduino Board Comparison

Here is a basic breakdown of the specifications of the three boards:

Specification UNO R3 MEGA R3 Beetle
Processor ATmega328P ATmega2560 Atmega32U4
Frequency 16 MHz 16 MHz 16 MHz
Dimensions 68.6 mm × 53.3 mm 101.6 mm × 53.3 mm 20mm X 22mm
Manufacturer Arduino Arduino DFRobot
Flash Memory 32kB 256kB 32kB
SRAM 2kB 8kB 2.5kB
Digital I/O Pins 14 54 3
Analog Pins 6 16 3

The Arduino UNO is a good starting point for anyone interested in beginning some Arduino builds, it is a good all round board for most projects and the only real constraint that I have ever run into with this board is running out of digital I/O and Analog input pins for larger projects.

The Arduino Mega overcomes this problem by offering more than double the pins. From a development and ease of use point of view it is almost identical to the UNO.

The Beetle has the least amount of pins exposed, 6 in total, 3 digital and 3 analog, so this can be a serious constraint on the nature of project it can be used for. On the other hand its tiny size makes it possible to use this board in projects where physical size is a constraint (Such as the Insect bot I posted about in an earlier post).   

Now lets look at the Raspberry Pi (Raspberry Pi 2 B to be precise) in comparison to the Arduino boards. Below are 2 Pictures showing its size in comparison to the Arduino UNO and Mega.

Pi and Mega Pi and Mega

Here is a basic specification breakdown for the Raspberry Pi (Raspberry 2 B):

Specification Raspberry Pi 2 B
Processor Cortex-A7
Frequency 900 MHz quad-core
Dimensions 85.60 mm × 56.5 mm
Manufacturer Raspberry Pi Foundation
Flash Memory MicroSD slot
SDRAM 1GB

So, which should you use? Arduino or Raspberry Pi? The answer is… It depends. Both boards have their strong and weak points. Let us look at some key distinguishing points between the two board families:

  • Price
    • The Arduino boards tend to cost a lot less than Raspberry Pi boards.
  • Memory
    • Raspberry Pi Boards have vastly more memory.
  • Processing Power
    • Raspberry Pi Boards again win this one by a huge margin.
  • Ease of Hardware interfacing
    • Arduino Boards make direct hardware interfaces with sensors and actuators much easier.
  • Online community
    • Both have a strong and thriving online community for help and support.
  • Development
    • Arduino is C only using the free Arduino IDE where as the Raspberry Pi has a variety of development options, including Python, Java, C, C++.

The Arduino makes hardware interfacing with sensors and actuators a great deal easier. However the Raspberry Pi offers vastly more memory and processing power. So which one to use depends very much on your projects’ requirements.

To put it simply there is no right or wrong choice, use what works for you or simply what you want to use.

This does however not mean that you cannot use both on a single project by setting up serial communication between the 2 boards. I am currently busy doing this on a project (see The Geek under the THE KILLER ROBOTICS FAMILY SO FAR! post).

Boards, Boards Everywhere

The Killer Robotics Family So Far!

This Killer Robotics Family currently consists of 2 complete robots and 1 work in progress.

First we have the Autonomous Roaming Robot:

Autonomous Roaming Robot

This robot was built on a Sparkfun Magician Chassis and uses a Arduino Uno R3 with a Pololu MC33926 dual motor controller, a HC-SR04 Ultra Sound Distance Sensor (On a micro servo for neck movement), a Sharp IR distance sensor to detect drops, and 2 trigger switches to detect direct contacts with objects. This robot autonomously roams avoiding objects and drops. I will provide a full breakdown on how this robot was constructed as well as the source code running on the Arduino in a future post.

Secondly we have the Insect bot:

Insectbot

This Robot was based on an Instructable article posted by Lumi3005 (http://www.instructables.com/id/Insect-Bot-mini/). It is based on a Beetle board (basically a shrunk down Arduino Leonardo) with 2 micro servos and a IR distance sensor. This robot walks around avoiding obstacles. I will be posting a review and build step-by-step guide for the DFRobot kit of this robot in the near future.

box

And Lastly we have The Geek:

robot7

This robot is still a work in progress and is by far the most ambitious robot that I have under taken. It utilises 16 Servos, will utilise 3 ultrasound distance sensors and 2 infrared distance sensors, 2 cameras (a Arduino Camera and a Logitech web cam) and will be powered by a combination of an Arduino Mega R3 and a Raspberry Pi 2. Many posts revolving around this robot, such as progress, lessons learnt and build instructions will follow in the future.

The Killer Robotics Family So Far!