Tuesday 8 September 2015

Tamiya Track & Wheel Robot V1

This is for entertainment only but it worked perfectly for me.
I had a Tamiya twin motor and gearbox kit that I wanted to use in a robot but I wasn't sure what type of robot to build until I came across the Tamiya Track & Wheel Set in Kit form, problem solved.
I got it on eBay, actually I got two kits as they looked like an excellent kit and I wasn't wrong, they are an excellent kit that can be configured in a number of ways to suite the design that you might have.

                                        Tamiya Track & Wheel Set


                                The Kit comes with excellent Instructions

The only thing you need to do is work out what setup you want and then put it together, the track comes in different lengths so you can make up the correct length overall and it is very simple to put it together. I wanted the typical tank setup and I even had some track left over so I could have made it longer if I wanted to. 


                        This is the setup I settled on but it will do many more


                               The Twin Motor and Gearbox Kit Mounted

The components are held together by plastic two part rivets and they are the only things I used in this build, I wanted to test them and they seem to be holding well enough at this stage but I'm not totally convinced that they will hold if the robot gets a lot of use by the grand kids so it might get a few screws and nuts to make it kid proof, well okay sort of kid proof.
You can see that the motor has the usual capacitor setup to help protect the motor H Bridge controller and the gearbox is mounted with the two part rivets as well, lets see how they hold. 
The capacitors are 0.1uF and one goes across both motor power leads and then one from each supply lead to the motor case, this is very important if you want the controller to last.

                            The capacitors across the motor power leads




                                           The Arduino UNO Clone

As with most of my Rolling Robots I use an Arduino of one type or another and I used the UNO here because I have a number of DK Electronics Motor Controller Shields that I purchased some time ago as they were so cheap in lots of ten. They use the L293D H Bridge DIL IC's and a SN74HC595N DIL IC interface on the shield and simply plugs into the UNO and makes it very easy to control up to 4 DC motors or 2 stepper motors so it gives you a few options to power your robot. The number of sketches available for this shield are to many to mention but you will have no problem getting one to suite, I will include the sketch I used here.

                           The Arduino UNO with connectors to the front

                                 The Adafruit Motor Controller Clone V1


As you can see in the image above the controller simply plugs into the UNO and the motor and power leads screw into the headers on the shield, it also has connectors for 2 servos and you can add pins for A0 to A5 as required and it also has 5V and 0V connection points as well, in all a very handy shield, it is no longer made by Adafruit but they have a updated version now that has better specs but clones are still available of the first version, check eBay.



                   The Servo Mounting Plate made from PCB Vero Board


                                    I used Cable Ties to mount the Servo


                                  The second Cable Tie to Hold the Servo



The images above show the PCB Vero Board and Cable Ties used to mount the servo to the robot, I used the UNO footprint to cut the board to size and locate the mounting holes and put holes in the board for the main cable tie and used the second smaller cable tie to stop it sliding forward or backward and it works very well.



                      The Ultrasonic Sensor mounted to a Bracket and Servo


                        The Ultrasonic Sensor is held on with Fishing Line



The Images above show the sensor and bracket mounted to the servo, the plastic bracket has small holes that line up with the mounting holes in the sensor PCB and I used fishing line to hold it together. The bracket is screwed to one of the servo horns but you need to cut the excess length of the screws off so they don't foul on the servo. If you look closely at the top image you will notice cutouts in the board to allow the wiring to be connect to the shield pins and the wiring for the motors is under the servo board to keep it safe. I used a battery box that had a switch in it to simplify the construction process and it works very well, I have used this set up before and it keeps things simple.
I was worried about the height of the servo and sensor but it worked beautifully on the first test and avoided obstacles very well so I will keep it as is.


            The Battery Box is mounted on the Motor with Hook & Loop Tape



                           The Switch can be seen on the Front of the Box

If you look at the above images you can just see the Switch on the front right corner of the battery box and this makes the construction of the robot very simple, it also keeps the wiring easier to manage as well.
You can also see the white plastic threaded standoffs that I used to mount the Arduino UNO and shield as well as the servo board to the chassis, the screw and standoff are plastic so they won't interfere with the PCB's circuits and you can get three different lengths of nuts so you can configure the layout to best suite the robot you are building and length of standoff required. You can get these components from Jaycar in Australia. 

                                       The Video of the Maiden Voyage

As you can see the sketch needs a bit more work but on the whole it works reasonably well, the speed and turning to avoid obstacles is good so with a little bit of work you should be able to get the sketch work well with your version of this robot should you decide to build one. The motor shield will work with most DC motors and if you read the information in the sketch you will be able to work out how to wire the robot, very simple actually, anyway here is the sketch in it's basic form, you will need to tweak it to suite your setup, have fun.

Just copy and paste this into your Arduino IDE and away you go, it will need work, this is a text document and the lines have word wrapped to the next line so sort that out first then compile it to make sure you have it working.



#include <AFMotor.h>
#include <Servo.h> 
#include <NewPing.h>

#define TRIG_PIN A4 // Pin A4 on the Motor Drive Shield soldered to the ultrasonic sensor
#define ECHO_PIN A5 // Pin A5 on the Motor Drive Shield soldered to the ultrasonic sensor
#define MAX_DISTANCE 200 // sets maximum useable sensor measuring distance to 200cm
#define MAX_SPEED 240 // sets speed of DC traction motors to 180/256 or about 50% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 15 // this sets offset to allow for differences between the two DC traction motors ****** from 20
#define COLL_DIST 60 // sets distance at which robot stops and reverses to 10cm
#define TURN_DIST COLL_DIST+10 // sets distance at which robot veers away from object (not reverse) to 20cm (10+10)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); // sets up sensor library to use the correct pins to measure distance.

AF_DCMotor motor1(1, MOTOR12_2KHZ); // create motor #1 using M1 output on Motor Drive Shield, set to 1kHz PWM frequency
AF_DCMotor motor2(2, MOTOR12_2KHZ); // create motor #2, using M2 output, set to 1kHz PWM frequency
AF_DCMotor motor3(3, MOTOR12_2KHZ);
AF_DCMotor motor4(4, MOTOR12_2KHZ);
Servo myservo;  // create servo object to control a servo 

int leftDistance, rightDistance; //distances on either side
int curDist = 0;
String motorSet = "";
int speedSet = 0;

//-------------------------------------------- SETUP LOOP ----------------------------------------------------------------------------
void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 (SERVO_2 on the Motor Drive Shield to the servo object 
  myservo.write(90); // tells the servo to position at 90-degrees ie. facing forward.
  delay(750); // delay for one seconds
 }
//------------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------MAIN LOOP ------------------------------------------------------------------------------
void loop() {
  myservo.write(90);  // move eyes forward
  delay(90);
  curDist = readPing();   // read distance
  if (curDist < COLL_DIST) {changePath();}  // if forward is blocked change direction
  moveForward();  // move forward for 1/2 second
  delay(350);
 }
//-------------------------------------------------------------------------------------------------------------------------------------

void changePath() {
  moveStop();   // stop forward movement
  myservo.write(36);  // check distance to the right
    delay(500);
    rightDistance = readPing(); //set right distance
    delay(500);
    myservo.write(144);  // check distace to the left
    delay(700);
    leftDistance = readPing(); //set left distance
    delay(500);
    myservo.write(90); //return to center
    delay(100);
    compareDistance();
  }

  
void compareDistance()   // find the longest distance
{
  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
  {
    turnAround();
  }
}


//-------------------------------------------------------------------------------------------------------------------------------------

int readPing() { // read the ultrasonic sensor distance
  delay(50);   
  unsigned int uS = sonar.ping();
  int cm = uS/US_ROUNDTRIP_CM;
  return cm;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveStop() {motor1.run(RELEASE); motor2.run(RELEASE); motor3.run(RELEASE); motor4.run(RELEASE); }  // stop the motors.
//-------------------------------------------------------------------------------------------------------------------------------------
void moveForward() {
    motorSet = "FORWARD";
    motor1.run(FORWARD);      // turn it on going forward
    motor2.run(FORWARD);      // turn it on going forward
    motor3.run(FORWARD);
    motor4.run(FORWARD);
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet+MAX_SPEED_OFFSET);
    delay(5);
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveBackward() {
    motorSet = "BACKWARD";
    motor1.run(BACKWARD);      // turn it on going forward
    motor2.run(BACKWARD);     // turn it on going forward
    motor3.run(BACKWARD);
    motor4.run(BACKWARD);
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet+MAX_SPEED_OFFSET);
    delay(5);
  }
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnRight() {
  motorSet = "RIGHT";
  motor1.run(FORWARD);      // turn motor 1 forward
  motor2.run(BACKWARD);     // turn motor 2 backward
  motor3.run(BACKWARD);
  motor4.run(FORWARD);
  delay(300); // run motors this way for 400ms
  motorSet = "FORWARD";
  motor1.run(FORWARD);      // set both motors back to forward
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnLeft() {
  motorSet = "LEFT";
  motor1.run(BACKWARD);     // turn motor 1 backward
  motor2.run(FORWARD);      // turn motor 2 forward
  motor3.run(FORWARD);
  motor4.run(BACKWARD);
  delay(600); // run motors this way for 400ms
  motorSet = "FORWARD";
  motor1.run(FORWARD);      // turn it on going forward
  motor2.run(FORWARD);      // turn it on going forward
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnAround() {
  motorSet = "RIGHT";
  motor1.run(FORWARD);      // turn motor 1 forward
  motor2.run(BACKWARD);     // turn motor 2 backward
  motor3.run(BACKWARD);
  motor4.run(FORWARD);
  delay(600); // run motors this way for 800ms
  motorSet = "FORWARD";
  motor1.run(FORWARD);      // set both motors back to forward
  motor2.run(FORWARD); 
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

Have Fun,
Cheers, Terry VK2FDGN