Archive for the ‘Robot Projects’ Category

Arduino Robot Arm – LarryArm v0.1

Arduino-robot-arm

[ad#Google links]

I have constructed a basic Arduino robot arm using 3 servos that cost me £15 in total plus a couple of hours in time to build and it’s very simple that I think anyone can replicate and build this. I already had the Arduino Duemilanove ATMEGA328, some foamboard, tools and glue. The robot arm has 3 joints and moves in the X and Y dimensions – not the Z (although I will build this in subsequent versions). I’ve included some very basic Arduino robot arm code along with robot arm design / blueprints and measurements for you to download and build (on any material).

So firstly, I had a look around for robot arm kits that could be brought rather than fabricating the parts myself – I found the prices to be extremely prohibitive. I then looked at getting a design fabricated but most of the designs I’ve seen rarely give you or decent assembly instructions. I also looked at servo brackets and constructor sets but again whilst the odd piece is OK trying to get the parts for a robot arm is too expensive.

Where does this leave me, apart from being too poor to afford a robot arm kit? Well I thought how hard can it be to design and build my own robot arm? Surely I can do it for less and if it works I can publish the results and schematics rather than just a video of it working. So follow my below steps.

The first problem of designing your robot arm is how do you mount the servos? Most kits tend to use some kind of bracket that the servo is mounted into, the armature then mounted to this bracket. For a simpleton like me this seems like a lot of effort, my workshop skills not being that great and neither is my patience, I didn’t want to go down this route. After much thought I hit upon a simple idea, rather than build a bracket, how about altering the servo casing its self. They’re made from ABS plastic, they’re cheap and tough enough that drilling a hole to create a mounting peg should be easy, the drawing below shows where I added the bolt at the bottom, although measurements only show the nut the bolt is about 8mm in length – all depends on how thick your material is you’re using for the arm.

As you can see from the photos below, I take the base of the servo off and drill a hole in about the same position as the servo shaft at the top, this then allows me to place the servo directly into the armature using a bolt through the base of the servo so that it can turn freely in the arm without needing a bracket.

Robot Arm Servo Modification

 

Take the servo base off

 

Drill the servo base

 

Modded servo for arm

Arduino Robot Arm Design

 

Once this problem is overcome, the rest is easy. You can use my robot arm design below, click on the image to download the PDF:

Just print this off and stick it to the material that you’re cutting then cut the shapes out, if you’re using something more rigid than foamboard you won’t need the cross supports I added. I’ve also included a measurement of my servo in the diagram and remember to alter the measurements for the thickness of your material if needed (My foamboard was 5mm thick).

[ad#Google Ad in content]

Robot Arm Assembly Instructions

 

Robot arm

 

Robot arm parts

 

Assembling

 

Nearly finished robot arm

And as you can see from above the main arm gets assembled using nothing more than hot glue and my cutting isn’t even that neat. Here are the assembly steps:

1) Download and print my design
2) Glue the printouts to your material you wish to use
3) Cut all parts out
4) In joints B and D you’ll need to make a hole for the servo bolt to sit in – my drawings have this area marked as well as a larger circle for positioning the top of the servo
5) Now we fx the parts together, you’ll need to put the servos into joints A and C first, I used ht glue to fix the servo wheel to the arm, but you can screw it instead for a stronger fixing
6) With joints A and C in place we attach the joints B and D
7) Finally we attach joint A to a base so that we can counter weight the arm

[ad#Google Ad in content]

Robot Arm Arduino Sketch and Circuit

 

Thats it. Now we just plug the servos into the Arduino board and control them with a simple sketch (below). For the circuit I used a breadboard to share the power supply to all the servos and the outside pin (normally white or orange) gets connected to a PWM pin on the Arduino board (9, 10 or 11 in this case)

The control of the servos and the circuit is no more complicated than my other Arduino servo projects

/*
LarryArm v0.1 Arduino Robot Arm test sketch to check servos and arm works.
*/

#include  

Servo shoulder;
Servo elbow;
Servo wrist;
int pos = 0;    

void setup()
{
  shoulder.attach(9);
  elbow.attach(10);
  wrist.attach(11);
} 

void loop()
{
  for(pos = 0; pos < 180; pos += 1)     {                                       shoulder.write(pos);       elbow.write(pos);     wrist.write(pos);     delay(15);            }    for(pos = 180; pos>=1; pos-=1)
  {
    shoulder.write(pos);
    elbow.write(pos);
    wrist.write(pos);
    delay(15);
  }
}

With that loaded in I got the following result, it worked but there were a couple of bugs. Turns out the servos are using more power than my USB port to te Arduino board can provide, so I’ll have to run the servos on a separate power supply. Also turns out that you get what you pay for, I brought the cheapest servos and they struggle to accurately write their position. For anyone wondering what that is on top of the arm its just the heaviest thing I could find near by to counter weight the robot arm.

Enjoy!

Arduino: Controlling the Robot Arm

arduino processing robot arm pt2

So the arm is wired into Arduino as per the previous post, Arduino: Modifying a Robot Arm and hopefully this has worked. In this next part I alter the Arduino sketch slightly and write the first Processing sketch to test control of the arm – video at the bottom.

To control the robot arm we’ll be sending a byte value over the serial port and then reading that in the Arduino code. Depending upon the value sent different motors will be activated.

For the processing sketch I’ve made a few buttons for each motor and also coded the use of the keyboard for another control method. Using either arbitrarily moves the arms motors.

This sketch is the basis for all the further work as well as testing the arm, from this I will move to inverse kinematics as well as programming repeat actions for the arm to perform. Ultimately leading to the arm responding to sensors and other stimuli – eventually! (I have a lot to write up).

For a basic example of working with controlling Arduino using Processing please read my tutorial “Using Processing to Send Values to Arduino” which explains about sending data over the serial port.

The Arduino Sketch
Nothing much has changed from the sketch in the previous post, the main difference is that now you can see we’re reading values from the serial port and acting accordingly. All the logic happens in the Processing code.

/* controls each motor in an Edge Robotic Arm using data sent from 
    a Processing Sketch
    luckylarry.co.uk
 
*/
// set the output pins
// 14-18 are actually analog pins 0-4
int baseMotorEnablePin = 2;
int baseMotorPin1 = 3;                             
int baseMotorPin2 = 4;                           
int shoulderMotorEnablePin = 14;
int shoulderMotorPin1 = 15;                             
int shoulderMotorPin2 = 16; 
int elbowMotorEnablePin = 8;
int elbowMotorPin1 = 9;                             
int elbowMotorPin2 = 10;                           
int wristMotorEnablePin = 5;
int wristMotorPin1 = 6;                             
int wristMotorPin2 = 7; 
int handMotorEnablePin = 11;
int handMotorPin1 = 17;                             
int handMotorPin2 = 18; 
// set a variable to store the byte sent from the serial port
int incomingByte;

void setup() {
  // set the SN754410 pins as outputs:
  pinMode(baseMotorPin1, OUTPUT);
  pinMode(baseMotorPin2, OUTPUT);
  pinMode(baseMotorEnablePin, OUTPUT);
  digitalWrite(baseMotorEnablePin, HIGH);
  pinMode(shoulderMotorPin1, OUTPUT);
  pinMode(shoulderMotorPin2, OUTPUT);
  pinMode(shoulderMotorEnablePin, OUTPUT);
  digitalWrite(shoulderMotorEnablePin, HIGH);
  pinMode(elbowMotorPin1, OUTPUT);
  pinMode(elbowMotorPin2, OUTPUT);
  pinMode(elbowMotorEnablePin, OUTPUT);
  digitalWrite(elbowMotorEnablePin, HIGH);
  pinMode(wristMotorPin1, OUTPUT);
  pinMode(wristMotorPin2, OUTPUT);
  pinMode(wristMotorEnablePin, OUTPUT);
  digitalWrite(wristMotorEnablePin, HIGH);
  pinMode(handMotorPin1, OUTPUT);
  pinMode(handMotorPin2, OUTPUT);
  pinMode(handMotorEnablePin, OUTPUT);
  digitalWrite(handMotorEnablePin, HIGH);
  // start sending data at 9600 baud rate
  Serial.begin(9600);
}

void loop() {
  // check that there's something in the serial buffer
  if (Serial.available() > 0) {
    // read the byte and store it in our variable 
    // the byte sent is actually an ascii value
    incomingByte = Serial.read();
    // note the upper casing of each letter!
    // each letter turns a motor different way.
    if (incomingByte == 'Q') {
    digitalWrite(baseMotorPin1, LOW);   
    digitalWrite(baseMotorPin2, HIGH);  
    } 
    if (incomingByte == 'W') {
    digitalWrite(baseMotorPin1, HIGH);   
    digitalWrite(baseMotorPin2, LOW);  
    }
    if (incomingByte == 'E') {
    digitalWrite(shoulderMotorPin1, LOW);   
    digitalWrite(shoulderMotorPin2, HIGH);  
    } 
    if (incomingByte == 'R') {
    digitalWrite(shoulderMotorPin1, HIGH);   
    digitalWrite(shoulderMotorPin2, LOW);  
    }
    if (incomingByte == 'A') {
    digitalWrite(elbowMotorPin1, LOW);   
    digitalWrite(elbowMotorPin2, HIGH);  
    } 
    if (incomingByte == 'S') {
    digitalWrite(elbowMotorPin1, HIGH);   
    digitalWrite(elbowMotorPin2, LOW);  
    }
    if (incomingByte == 'D') {
    digitalWrite(wristMotorPin1, LOW);   
    digitalWrite(wristMotorPin2, HIGH);  
    } 
    if (incomingByte == 'F') {
    digitalWrite(wristMotorPin1, HIGH);   
    digitalWrite(wristMotorPin2, LOW);  
    }
    if (incomingByte == 'Z') {
    digitalWrite(handMotorPin1, LOW);   
    digitalWrite(handMotorPin2, HIGH);  
    } 
    if (incomingByte == 'X') {
    digitalWrite(handMotorPin1, HIGH);   
    digitalWrite(handMotorPin2, LOW);  
    }
    // if a O is sent make sure the motors are turned off
    if (incomingByte == 'O') {
    digitalWrite(baseMotorPin1, LOW);   
    digitalWrite(baseMotorPin2, LOW);  
    digitalWrite(shoulderMotorPin1, LOW);   
    digitalWrite(shoulderMotorPin2, LOW); 
    digitalWrite(elbowMotorPin1, LOW);   
    digitalWrite(elbowMotorPin2, LOW);  
    digitalWrite(wristMotorPin1, LOW);   
    digitalWrite(wristMotorPin2, LOW); 
    digitalWrite(handMotorPin1, LOW);   
    digitalWrite(handMotorPin2, LOW); 
    }
  }
}

[ad#Google Ad in content]

The Processing Sketch
I’ve drawn some fancy arrows for my buttons in this sketch but otherwise the code is pretty simple – if I press Q or q on the keyboard or if I press an arrow button then send the ascii value of Q (note the uppercase) over the serial port for the Arduino to pick up and turn the motor on. There is nothing here really complicated just a fair few lines of code for the user interface.

/* 
   Processing sketch that send a ascii byte character to Arduino which
   then subsquentally controls a motor
   luckylarry.co.uk
 
*/

// load the serial library for Processing
import processing.serial.*; 
// instance of the serial class
Serial port;
// values to store X, Y for each button
int M1LX, M1RX, M2LX, M2RX, M3LX, M3RX, M4LX, M4RX, M5LX, M5RX;
int M1LY, M1RY, M2LY, M2RY, M3LY, M3RY, M4LY, M4RY, M5LY, M5RY;
// stores the width/height of the box
int boxSize = 64;
// 2 new instances of my arrow class
// also set an array of coordinates for each arrow
arrow myRightArrow;
int[]rightArrowxpoints={30,54,30,30,0,0,30}; 
int[]rightArrowypoints={0,27,54,40,40,15,15};
arrow myLeftArrow;
int[]leftArrowxpoints={0,24,24,54,54,24,24}; 
int[]leftArrowypoints={27,0,15,15,40,40,54};
// set the font
PFont myFont;

void setup()  {
  // screen size of the program
  size(145, 455);
  // set the coordinates of each button box
  // base motor M1LX = Motor 1 Left X  etc..
  M1LX = 5;
  M1LY = 25;
  M1RX = 75;
  M1RY = 25;  
  // shoulder motor
  M2LX = 5;
  M2LY = 115;
  M2RX = 75;
  M2RY = 115;
  // elbow motor
  M3LX = 5;
  M3LY = 205;
  M3RX = 75;
  M3RY = 205;
  // wrist motor
  M4LX = 5;
  M4LY = 295;
  M4RX = 75;
  M4RY = 295;
  // hand motor
  M5LX = 5;
  M5LY = 385;
  M5RX = 75;
  M5RY = 385;
  
  // List all the available serial ports in the output pane. 
  // You will need to choose the port that the Arduino board is 
  // connected to from this list. The first port in the list is 
  // port #0 and the third port in the list is port #2. 
  println(Serial.list()); 
  // set the font to use
  myFont = createFont("verdana", 12);
  textFont(myFont);
  // Open the port that the Arduino board is connected to (in this case #0) 
  // Make sure to open the port at the same speed Arduino is using (9600bps)
  port = new Serial(this, Serial.list()[1], 9600); 
  // create the base arrow
  myRightArrow = new arrow(rightArrowxpoints,rightArrowypoints,7);
  myLeftArrow = new arrow(leftArrowxpoints,leftArrowypoints,7);
}

void draw() 
{ 
  background(0);
  noStroke();
  fill(150);
  // draw each box/ button with a label above each    
  text("Base Motor (Q/W)", 5, 5, 200, 75); 
  text("Shoulder Motor (E/R)", 5, 95, 200, 75);
  text("Elbow Motor (A/S)", 5, 185, 200, 75);
  text("Wrist Motor (D/F)", 5, 275, 200, 75);     
  text("Hand Motor (Z/X)", 5, 365, 200, 75);

  // start looking to see whats pressed and send a value
  // over the serial port
  if(keyPressed) {
    if (key == 'q' || key == 'Q') {
      port.write('Q');
    }
    if (key == 'w' || key == 'W') {
      port.write('W');
    }
    if (key == 'e' || key == 'E') {
      port.write('E');
    }
    if (key == 'r' || key == 'R') {
      port.write('R');
    }
    if (key == 'a' || key == 'A') {
      port.write('A');
    }
    if (key == 's' || key == 'S') {
      port.write('S');
    }
    if (key == 'd' || key == 'D') {
      port.write('D');
    }
    if (key == 'f' || key == 'F') {
      port.write('F');
    }
    if (key == 'z' || key == 'Z') {
      port.write('Z');
    }
    if (key == 'x' || key == 'X') {
      port.write('X');
    }
  } 
  // if no key is pressed check to see if the mouse button is pressed
  else if (mousePressed == true) {
    // check to see if the mouse is inside each box/ button if so send the value
    if (mouseX > M1LX-boxSize && mouseX < M1LX+boxSize && 
      mouseY > M1LY-boxSize && mouseY < M1LY+boxSize) {
        port.write('Q'); 
    } 
    else if(mouseX > M1RX-boxSize && mouseX < M1RX+boxSize && 
      mouseY > M1RY-boxSize && mouseY < M1RY+boxSize) {
        port.write('W'); 
    } 
    else if(mouseX > M2LX-boxSize && mouseX < M2LX+boxSize && 
      mouseY > M2LY-boxSize && mouseY < M2LY+boxSize) {
        port.write('E'); 
    } 
    else if(mouseX > M2RX-boxSize && mouseX < M2RX+boxSize && 
      mouseY > M2RY-boxSize && mouseY < M2RY+boxSize) {
        port.write('R'); 
    } 
    else if(mouseX > M3LX-boxSize && mouseX < M3LX+boxSize && 
      mouseY > M3LY-boxSize && mouseY < M3LY+boxSize) {
        port.write('A');   
    } 
    else if(mouseX > M3RX-boxSize && mouseX < M3RX+boxSize && 
      mouseY > M3RY-boxSize && mouseY < M3RY+boxSize) {
        fill(200);
        port.write('S');     
    }
    else if (mouseX > M4LX-boxSize && mouseX < M4LX+boxSize && 
      mouseY > M4LY-boxSize && mouseY < M4LY+boxSize) {
        port.write('D');     
    } 
    else if(mouseX > M4RX-boxSize && mouseX < M4RX+boxSize && 
      mouseY > M4RY-boxSize && mouseY < M4RY+boxSize) {
        port.write('F');  
    } 
    else if (mouseX > M5LX-boxSize && mouseX < M5LX+boxSize && 
      mouseY > M5LY-boxSize && mouseY < M5LY+boxSize) {
        port.write('Z'); 
    }
    else if(mouseX > M5RX-boxSize && mouseX < M5RX+boxSize && 
      mouseY > M5RY-boxSize && mouseY < M5RY+boxSize) {
        port.write('X');    
    }
    else {
      // if the mouse is pressed but not with in a box make sure nothings moving
      port.write('O');   
    } 
  } else {
    // no key or mouse press then make sure nothings moving.
    port.write('O');   
  } 
  
  // draw the buttons
  myRightArrow.drawArrow(80,30);
  myRightArrow.drawArrow(80,120);
  myRightArrow.drawArrow(80,210);
  myRightArrow.drawArrow(80,300);
  myRightArrow.drawArrow(80,390);
  myLeftArrow.drawArrow(10,30);
  myLeftArrow.drawArrow(10,120);
  myLeftArrow.drawArrow(10,210);
  myLeftArrow.drawArrow(10,300);
  myLeftArrow.drawArrow(10,390);
}

class arrow extends java.awt.Polygon { 
  /* our class is basically an instance of java.awt.Polygons and this class expects and array of X points, Y points and the number of 
     points in our shape. The variable names also have to be direct references to what this class expects, so xpoints, ypoints and npoints are all
     set/defined in the java class.
  */
  public arrow(int[] xpoints,int[] ypoints, int npoints) {
    // super invokes the java.awt.Polygon class
    super(xpoints,ypoints,npoints);
    
  } 
    // supply offsets to draw the arrow, means I don't need to set points for each one
    void drawArrow(int xOffset, int yOffset){
    fill(150);
    rect(xOffset-5, yOffset-5, boxSize, boxSize);
    fill(255);
    beginShape();
    for(int i=0;i

[ad#Google Ad in content]

Does it work?
Hopefully the sketch is working and you can control the arm via your computer. If not then first check that all motors are wired in properly and your batteries are not flat. If you arrow moves the arm the wrong way then you can either switch the motor pins on the circuit or change the Arduino sketch to alter the motors direction.

Calibrating the arm
We need to set start positions for the arm and note the positions and counts in order to later calculate the positions for the next parts of this work. This is where we'll look to more benefits of Arduino and possibly PID (Proportional, Integral, Derivative) control, PWM or someother way to get accurate positions for the motor. The only catch is each motor is in a gearbox so using an encoder or other device to measure motor rotations is not an option. But for now we can control our arm from the computer at least - check out the video below.


Arduino: Modifying a Robot Arm: How to wire up the robot arm to Arduino.

Arduino – Modifying a Robot Arm

Arduino robot arm

Essentially another tutorial involving controlling DC motors. In this post I’m going to first alter a robot arm I had built previously from a beginners kit so that it can be controlled from Arduino. Then I’m going to write a series of posts on different ways to control the robot arm using Processing and other things. You should be able to use all of what I write for work with other toys and motors.

To start with have a look at the robot arm, it’s an ‘Edge Robotic Arm Kit‘:

The kit is a basic construction one and costs about £30 which you can find in most gadget shops and web stores. You assemble a gear box for each motor/ joint in the arm, doesn’t take long to build (about an hour) and is controlled by a set of switches on a control box. The only thing to note here is we’re dealing with motors, not servos or stepper motors just bog standard DC motors. This means calculating positions isn’t going to be straightforward later on. The kit has 5 motors and 4 ‘D’ series batteries to power them and can lift about 100 grammes.

So this version has a controller attached that lets you move each motor by pressing a switch, the electrics are pretty basic and don’t allow much control or further input. I have seen other versions that allow you to plug it in to a computer via USB but you pretty much have the same controls.

In order for us to build our own controls/ interfaces and software we need to modify the arm to allow us to interface our microcontroller – in this case an Arduino board. The best way I think do this, since we want to control a motor going backwards and forward, is to use H-bridge chips – the L293D and SN754410 and wire each motor into a chip and then alter the power circuit to run these chips. Arduino can then digitally control the H-bridge chip to turn the motor on/off and change its direction.

You can see some other work I’ve done with motor DC motor control and I’ll be covering the same info throughout these posts.

Arduino Robot Arm Parts

3 H-bridge chips – I heavily recommend using the sn754410 chip but you can probably get away with the L293 series. Each chip can control 2 motors – 5 motors = 3 chips.
Arduino Deumilanova w/ ATMEGA328
Breadboard/ Prototyping board
Jumper/ Connector wires
Wire cutters/ strippers

Hacking the Robot Arm

I hope you’re not too precious about wanting to use the control unit again, thats the first thing to go! I did look at working with this but it doesn’t give the level of control that I want. Also I’ll be cutting and stripping the wires and removing the control circuit from the arm. The only permanent damage is done to the wires – basically cutting the plugs off of the wires, so you could always get new plugs if you wanted to revert it, although once I’ve shown you what can be done I don’t think you’ll mind.

Step 1
First we need to create our breadboard layout so we can plug in all the wires, we’re going to be using alot of pins on the Arduino, in fact I think I use pretty much all of them. You could reduce this using shift registers but for now its not an issue, although please follow the wiring diagrams as this layout gives the least hassle. Some pins e.g. digital pin 13 will make the motors move when the board is powering up so we want to avoid this.

First of all we need to put our H-Bridge chips on the breadboard. Make sure to put them in the center like illustrated. This means the 2 sides of the chip are isolated – it will not work otherwise!

Next using the above image and the following wiring diagram for the chip connect the ground and power for each chip leaving space for the motors and Arduino pins. Note that the red wires are connecting the rails together so the power will flow around the whole board! These chips will be using the battery power that runs the motors in the arm – the power will be plugged into the board, the Arduino pins are there to switch the chips on/ off etc… I’ve also got a table of outputs I’ve done for each pin on the H-Bridge chip, it’s the same for either the L293 series or SN754410, pin configuration diagram below. The numbers 1-16 also correspond to the numbers on the images of the circuit.

H-Bridge Pin Configuration

1 to pin on Arduino board
2 to pin on Arduino board
3 to motor1 (either + or -) it wont matter as its DC
4 to the gnd (-) rail on the breadboard
5 to the gnd (-) rail on the breadboard
6 to motor1
7 to pin Arduino
8 to power (+) rail.
9 to pin Arduino
10 to pin Arduino
11 to motor2
12 to GND (-) rail
13 to GND (-) rail
14 to motor2
15 to pin Arduino
16 to power (+) rail.

So you should have 3 chips on the board and be ready to add the motors and connections to Arduino.

Step 2
Now the circuit layout is complete we can start stripping down the arm. First remove the control unit and unscrew the panel above the battery pack – this should have all the motors plugged in to it. We’re going to systematically disconnect each motor plug, remove the plug, strip the wires a little bit and wire it on to the breadboard. When stripping the wires, remember to twist the exposed wires to prevent them becoming stranded – or solder pins to the wires.

Here’s the first motor in on the first chip:

Its important to remember which motor you’re plugging in to which chip but it’s not too much of an issue as with the software we’ll be writing later on we can work around this with our code, just so long as each motor is wired into a chip as above. Below is a list of my Arduino pins used.

Shoulder motor
chip 1, pin 1 to Arduino pin 14 (Analog pin o)
chip 1, pin 2 to Arduino pin 15 (Analog pin 1)
chip 1, pin 7 to Arduino pin 16 (Analog pin 2)
Base motor
chip 1, pin 9 to Arduino pin 2
chip 1, pin 10 to Arduino pin 3
chip 1, pin 15 to Arduino pin 4
Elbow motor
chip 2, pin 1 to Arduino pin 8
chip 2, pin 2 to Arduino pin 9
chip 2, pin 7 to Arduino pin 10
Wrist motor
chip 2, pin 9 to Arduino pin 5
chip 2, pin 10 to Arduino pin 6
chip 2, pin 15 to Arduino pin 7
Hand motor
chip 3, pin 9 to Arduino pin 11
chip 3, pin 10 to Arduino pin 17 (Analog pin 3)
chip 4, pin 15 to Arduino pin 18 (Analog pin 4)

You’ll notice that rather than refer to the motors as M1, M2, M3 as the kit does, I’m calling them something more meaningful as I think it makes them easier to identify – you should be able to figure out which motor is which from my description I would hope!

Second motor in:

You can see the battery power has been added. If you have any problems you can always connect one motor at a time and use a quick sketch to test the circuit is working and below is some simple codeto help you do that. For later tutorials this isn’t going to change much.

[ad#Google Ad in content]

int baseMotorEnablePin = 2;
int baseMotorPin1 = 3;
int baseMotorPin2 = 4;
int shoulderMotorEnablePin = 14;
int shoulderMotorPin1 = 15;
int shoulderMotorPin2 = 16;
int elbowMotorEnablePin = 8;
int elbowMotorPin1 = 9;
int elbowMotorPin2 = 10;
int wristMotorEnablePin = 5;
int wristMotorPin1 = 6;
int wristMotorPin2 = 7;
int handMotorEnablePin = 11
int handMotorPin1 = 17;
int handMotorPin2 = 18; 

void setup() {
  // set the motor pins as outputs:
  // set all chips to enabled state
  pinMode(baseMotorPin1, OUTPUT);
  pinMode(baseMotorPin2, OUTPUT);
  pinMode(baseMotorEnablePin, OUTPUT);
  digitalWrite(baseMotorEnablePin, HIGH);
  pinMode(shoulderMotorPin1, OUTPUT);
  pinMode(shoulderMotorPin2, OUTPUT);
  pinMode(shoulderMotorEnablePin, OUTPUT);
  digitalWrite(shoulderMotorEnablePin, HIGH);
  pinMode(elbowMotorPin1, OUTPUT);
  pinMode(elbowMotorPin2, OUTPUT);
  pinMode(elbowMotorEnablePin, OUTPUT);
  digitalWrite(elbowMotorEnablePin, HIGH);
  pinMode(wristMotorPin1, OUTPUT);
  pinMode(wristMotorPin2, OUTPUT);
  pinMode(wristMotorEnablePin, OUTPUT);
  digitalWrite(wristMotorEnablePin, HIGH);

}

void loop() {
    /*
    // SET either one to HIGH to turn the motor on.
    // e.g.
    digitalWrite(baseMotorPin1, LOW);
    digitalWrite(baseMotorPin2, HIGH);
    */
    digitalWrite(baseMotorPin1, LOW);
    digitalWrite(baseMotorPin2, LOW);
    /*
    // more motors here added.
    digitalWrite(shoulderMotorPin1, LOW);
    digitalWrite(shoulderMotorPin2, LOW);
    digitalWrite(elbowMotorPin1, LOW);
    digitalWrite(elbowMotorPin2, LOW);
    digitalWrite(wristMotorPin1, LOW);
    digitalWrite(wristMotorPin2, LOW);
    */

}

[ad#Google Ad in content]
Step 3
So now you should have all the motors wired to chips on the breadboard, now we just add the power to the board and we’re done – this is the power from the robot arm batteries, it can connect on either side of the breadboard as long as its connected to the power rails. Also remember to connect a wire from the GND rail on the breadboard to a GND pin on Arduino – there must be a common ground connection between Arduino and the H-bridge chips for this to work. Lastly Find a way to secure the Arduino and breadboard to the arm to minimise the risk of wires disconnecting, I just used some blu-tak (modelling clay etc..).

And here’s the final thing:

If you want to avoid the breadboard and make a more permanent circuit you should be able ot follow this, just make sure that the pins on each side of the H-Bridge are completely isolated from each other.

Onwards…
So thats it, the arm is ready to go – you can add your own switches and inputs to control this but we’re going  to have some fun writing software to control this arm in the next part to move each motor AND after that we’re going to be looking at using Inverse Kinematics and trigonometry to do some cool controlling of all the motors of the arm and to maybe start program tasks.

Oh, Inverse Kinematics basically means we can program the arm to go after a target moving all the motors in combination to do this – trust me it is very cool!

Arduino – Controlling the Robot Arm with Processing: Using Processing and my laptop to control the arm

Obstacle avoidance Arduino robot – build your own larryBot

larryBotv06

So after 5 previous versions that had various flaws, I now have an Arduino robot that actually works and although basic is very cheap – although there a probably a few more flaws so please point them out to me but this is a good start on how to make your own robot.

In order to catch up, please see my previous posts below, describing the problems that the other 5 versions had, how the h-bridge chip works and using the SRF05 ultrasound distance sensor.

larryBot – Arduino robot versions 0.1 to 0.5 lessons learned
Control a DC motor with Arduino and L293D chip

Arduino SRF05 Distance Sensor

Now that you’re up to speed, lets start by fixing the flaws in the previous version, this was the case that my motors were drawing way too much current and the L293D chip from ST Micro couldn’t output enough current for each motor.

So, I replaced the chip with the snappy named ‘SN754410‘ from Texas Instruments. This has EXACTLY the same 16 pin layout as the L293D chip and all of the same features except that it can output 1.2 amps per channel rather than the now tiny 0.6 amps of the L293D. Pin configuration diagram below is the same for the L293D as it is for the SN754410, I recommend the SN754410 Arduino comination.

L293D Pin layout

Great I’ve now got more current to my motors, but their stall current is still at over 2 amps, I could add a heatsink to the chip and pass more current through it, but instead I got some more efficient motors than the Mabuchi FA-130’s that came with the Tamiya gearbox. These motors are made by Solarbotics and are their RM3 series which fit perfectly, can handle 4 times the voltage but use a fraction of the current – typically at 9v they use just over 1 amp. Perfect.

Having corrected this, larryBot v0.6 was go! I still faced a lack of power to the DC motors – either because my batteries were running low or not able to supply the current. But since my new motors could run up to 12 volts (instead of the puny 3v of the originals) I decided to use a 9v battery to power them instead of my 4 AA’s.

Watching larryBot move is great, even on carpet and with the tank tracks 9 times out of ten he can climb small obstacles or has enough traction to shunt them out the way. Anyway enough waffling – here’s how he’s made…

The Arduino Robot Tracked Chassis

You could use anything you want really – construction sets, your own custom fabricated chassis etc… But since I’m cheap I managed to get a pile of foamboard for my chassis. I can waste and reuse as much of this as I want so its no problem if I make a mistake or want to improve it. Also in theory this leads to rapid prototyping, so when I do decide to fabricate a chassis I know exactly where the best places are for holes, mounts etc…

The robot chassis parts and tools:

Small Phillips/ cross-head screwdriver
Gluegun
Craft knife
Pencil
Ruler
Assorted nuts and bolts – A good set of M series nuts and bolts
Foamboard 5mm thick – 1 A4 sheet is plenty
Tamiya gearbox 70097 – assembled in mode A
Tamiya track and wheel set 70100
Elastic bands (normally dropped by the postie)

Sizing up the robot base

First of all the size of our chassis design is dictated by a few things. The axle length: our tank tracks need about 5mm clearance so the space on the axle is roughly 65mm wide that I can mount on. Next we have the length of the tracks and how many wheels will be used, I kept my track footprint small so my chassis length didn’t need to be much bigger than the gearbox. Which leads on to gearbox positioning – the Tamiya gearbox I have is roughly 75mm in length and the shape of the tracks will dictate where to position the gearbox as the driving wheels are attached to this. The final consideration of course is mounting all the sensors, battery packs, breadboard and the Arduino board.

In my attempts so far I have a base that is just longer than twice the length of the gearbox (175mm) which gives me space at the front for sensors and space at the back for batteries. I then mount a smaller piece of foamboard on top of this that then houses the gearbox and spaces it far enough above the running wheels for the tracks at the bottom – also giving enough tension in the tracks for them not to slip off (unlike larryBot v0.4). From here I can continue to bolt on additional structures to position the breadboard and so on.

So using this knowledge you should be able to size up and cut the foamboard to the dimensions you need – a craft knife will be more than enough to cut this board. To make the holes needed for your screws and bolts just use a small Phillips/ Cross-head screwdriver to bodge a hole through – it won’t take any effort, then you can drive the screws through this guiding hole. If you have washers then use them but the foamboard seems to be able to support all the hardware fine.

Attaching the running wheels and tank tracks

First mark out the position of where you want your wheels, very important as you don’t want them wonky!

larryBotv06-base

To mount the running wheel axles on to the chassis I used a couple of small hexagonal bolts for each side of the axle and then used the glue gun to fix them to the chassis – the best way to do this is to put the bolts on to the axle, use a small amount of glue to hold the bolts in place and then use a shit load of glue over the bolts to secure them properly.

When adding the wheels to the axles, don’t push them all the way on as these axles are slightly shorter than the Tamiya gearbox which will cause you problems with the tracks.

Mounting the Tamiya gearbox, DC motors, sensors, breadboard, Arduino and batteries

To attach the gearbox I just used the screws supplied with the gearbox and bolted this to my smaller piece foamboard. I then in turn bolted this to the main chassis using 4 long bolts and a series of spacers and nuts in between the layers to given the correct spacing and adjustment for my drive wheels.

For the SRF05 distance sensor I just used some blu-tack/ modelling plasticine to hold it in place for now.

The breadboard I mounted above the gearbox, which for this I just fixed it on top of 4 long bolts which then in turn attached the gearbox base. The Arduino board currently then sits on the breadboard held on by the multitude of wires running from it and the power supply cable.

And for the batteries, since I scrapped using the 4xAA’s to power the motor I only had to worry about two 9V batteries, 1 of which was my DC power supply for the board. I fixed them to the chassis just using an elastic band, since I’d want to get to them easily enough.

larryBotv06-finished

Simple Arduino Robot Circuit

The parts list doesn’t differ much from my other tutorials for motors and L293D. But I did find it was troublesome to get the parts from the same supplier, so be aware that you may need to look at multiple suppliers and postage may get expensive.

Robotic parts list

2 x Solarbotics RM3 motors
SN754410 motor driver chip
SRF05 Ultrasonic distance sensor
Arduino Deumilanove w/ ATMEGA328
Breadboard / Prototyping board
Jumper/ Connector wires
2x 220nF multilayer ceramic capacitor (Y5V)
2 x 50V 10uF Capacitor (although I’ve not used them here)
2.1 mm coaxial DC jack
2 x PP3 9Volt battery
PP3 9Volt Connector
9Volt battery holder

larryBotv06-board

You can see that the circuit is pretty simple, nothing actually that fancy, I have the SRF05 using the +5v, GND and digital pins 12 and 13. The SN754410 then uses the digital pins 9 and 10 to control each channel – these can use PWM to do speed control, then there are the switch pins on the h-bridge that go to digital pins 3,4,5 and 6. The spare GND is used to join the GND connection between the motor power and Arduino power supply. Here are the instructions for the 9v battery DC supply. If you want to use the extra 50v 10 uF capacitors then these sit on the power supply for pins 8 and 16 on the SN751140 respectively.

larryBotv06-SN754410-layout

Arduino Robot Code

Nothing much has changed from the larryBot v0.1-0.5 sketch except that I’ve altered the detection distances as I have a much faster response time from the robot.

const int numOfReadings = 10;                   // number of readings to take/ items in the array
int readings[numOfReadings];                    // stores the distance readings in an array
int arrayIndex = 0;                             // arrayIndex of the current item in the array
int total = 0;                                  // stores the cumlative total
int averageDistance = 0;                        // stores the average value

// setup pins and variables for SRF05 sonar device

int echoPin = 12;                               // SRF05 echo pin (digital 2)
int initPin = 13;                               // SRF05 trigger pin (digital 3)
unsigned long pulseTime = 0;                    // stores the pulse in Micro Seconds
unsigned long distance = 0;                     // variable for storing the distance (cm)

int motor1Pin1 = 3;                             // pin 2 on L293D
int motor1Pin2 = 4;                             // pin 7 on L293D
int enable1Pin = 9;                             // pin 1 on L293D
int motor2Pin1 = 5;                             // pin 10 on L293D
int motor2Pin2 = 6;                             // pin  15 on L293D
int enable2Pin = 10;                            // pin 9 on L293D

void setup() {
  // set the motor pins as outputs:
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(enable1Pin, OUTPUT);
  pinMode(motor2Pin1, OUTPUT);
  pinMode(motor2Pin2, OUTPUT);
  pinMode(enable2Pin, OUTPUT);
  // set enablePins high so that motor can turn on:
  digitalWrite(enable1Pin, HIGH);
  digitalWrite(enable2Pin, HIGH);

  pinMode(initPin, OUTPUT);                     // set init pin 3 as output
  pinMode(echoPin, INPUT);                      // set echo pin 2 as input

  // create array loop to iterate over every item in the array

  for (int thisReading = 0; thisReading < numOfReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  digitalWrite(initPin, HIGH);                  // send 10 microsecond pulse
  delayMicroseconds(10);                                // wait 10 microseconds before turning off
  digitalWrite(initPin, LOW);                   // stop sending the pulse
  pulseTime = pulseIn(echoPin, HIGH);           // Look for a return pulse, it should be high as the pulse goes low-high-low
  distance = pulseTime/58;                      // Distance = pulse time / 58 to convert to cm.
  total= total - readings[arrayIndex];          // subtract the last distance
  readings[arrayIndex] = distance;              // add distance reading to array
  total= total + readings[arrayIndex];          // add the reading to the total
  arrayIndex = arrayIndex + 1;                  // go to the next item in the array                                 

  // At the end of the array (10 items) then start again
  if (arrayIndex >= numOfReadings)  {
    arrayIndex = 0;
  }

  averageDistance = total / numOfReadings;      // calculate the average distance
  delay(10);

  // check the average distance and move accordingly

  if (averageDistance <= 10){
    // go backwards
    digitalWrite(motor1Pin1, HIGH);
    digitalWrite(motor1Pin2, LOW);
    digitalWrite(motor2Pin1, HIGH);
    digitalWrite(motor2Pin2, LOW);    

  } 

  if (averageDistance <= 25 && averageDistance > 10) {
    // turn
    digitalWrite(motor1Pin1, HIGH);
    digitalWrite(motor1Pin2, LOW);
    digitalWrite(motor2Pin1, LOW);
    digitalWrite(motor2Pin2, HIGH);
  }
  if (averageDistance > 25)   {
    // go forward
    digitalWrite(motor1Pin1, LOW);
    digitalWrite(motor1Pin2, HIGH);
    digitalWrite(motor2Pin1, LOW);
    digitalWrite(motor2Pin2, HIGH);     

  }
}

[ad#Google Ad in content]

Some problems you may face – if like my you don’ t have a spare 9V battery connector to hand check this connection if nothing is happening – I used blu-tack to hold my wires in place so it’s a bit temperamental.
Check that your motor wires are properly in contact with the motor terminals if you haven’t soldered them again using some blu-tack or tape is handy for getting a good connection.
Motor’s are under strain – your tracks are too tight.
Tracks come away from the wheels – check your tracks are not too loose and that your running wheels are in line with the drive wheels – the Tamiya gearbox is slightly wider than the Tamiya track and wheel set axles.

larryBotv06-frontback

I’ve gotten a fairly cheap robot that avoids obstacles, next plan is to extend it to sense various things – for instance detect motion and move towards it, or a light/ heat source. The robot costs are quite high if you factor in the Arduino board and if you don’t have any of the parts – but this can be broken down and used for many other projects so you’ll get a lot of reuse out of these bits, but I reckon that the total cost is around £70-80 in total, so fairly cheap when compared to other bots. Of course if you don’t want tracks (?) then you can just use wheels instead, Tamiya do also make wheels that will fit the gearbox.

Just in case you have trouble getting parts, here’s a small list of people that can supply the various bits – although none of them will have the full set. Shipping from the states is an option, but check the shipping costs as it may negate the cost savings. Please let me know of other sources, the list is in no particular order.

Sparkfun – USA: motor controller and Tamiya parts
Pololu – USA: Tamiya parts and motors
Techbotics – UK: Tamiya parts – just about cheaper than getting parts from Sparkfun/ Pololu in the USA
Active robots – UK: motors, SRF05 but generally overpriced on everything
Rapid Electronics – UK/EU/USA: most component parts and hardware
Farnell – UK/EU/USA: SN754410 chip and most components but shit for orders if your billing and delivery addresses are separate
Mouser – UK/EU/USA: SN754410 chip and most components
SK Pang – UK: SN754410 chip but dodgy VAT calculations (charges tax on shipping as well) few other parts here.

If you need an Arduino board, I reliably found a seller on ebay from Hong Kong that will sell and ship you aboard for far less than paying for it the UK – downside is it takes about a week to arrive.

larryBot – Arduino robot versions 0.1 to 0.5 lessons learned

larryBotv01

So I’ve decided to build a robot using Arduino to control the sensors. Here’s my progress so far – I am hoping that my mistakes here and over the coming posts will guide people in more detail about what to avoid. Also I won’t provide a parts list until I have a working robot…

The purpose of my early version of larryBot is to create a basic robot that can be controlled with Arduino and that can be made from minimal materials and costs – I aimed with the Arduino included for this cost to be about £60-70 in total depending on what you can scrounge and providing you have the tools and some parts already. Also I wanted to make a robot from scratch rather than hacking together existing things, like modifying a RC car chassis for example. So far all larryBots aim is to do is to avoid obstacles and move around them.

First off I looked at using the L293D chip to control 2 DC motors and this would operate my steering and I would use the SRF05 ultrasound range finder as a proximity sensor. I had no problem with this circuit when I first started until today.

My first consideration was the chassis, now I figure that most people like me have spent the money on the Arduino board, which is worth every penny, and you probably have a few motors and bits with which to do this. However, like me, you looked at chassis and what to build one from to mount all the electronics. Theres the Tamiya erector set (if you can get it in the UK), Meccano, Lego and of course specific robot chassis’s not to mention designing your own and getting it made.

All very expensive (unless you have it already) and requires effort. I am lazy and karma happened to bless me with finding a stash of 5mm thick foamboard for me to use. If you aren’t aware foamboard is used for modelling and mounting work for display – if you need any then get a design agency to come and quote for work at your company and keep their foamboard :)

Anyway, the foamboard is excellent for my uses so far as my robots aren’t massive and their weight is minimal. It also allows me to rapidly prototype a chassis and layout without any costs – you can just push screws and bolts through to mount motors and use a glue gun to join parts. Another bonus is that you only need a craft knife to cut it.

To connect everything I just brought a set of various nuts and bolts to use along with a glue gun and thats it.

My circuit throughout has basically remained the same, I use a 6v power supply to power the L293D and the motors, and a 9V DC power supply to power the Arduino, which controls the L293D and reads the Ultrasound sensor. My changes so far have been on the chassis, motors, movement and gearing. The sketch for these versions has also remained the same which you can see detailed below:

larryBot v0.1-05 Arduino Robot Sketch

const int numOfReadings = 10;                   // number of readings to take/ items in the array
int readings[numOfReadings];                    // stores the distance readings in an array
int arrayIndex = 0;                             // arrayIndex of the current item in the array
int total = 0;                                  // stores the cumlative total
int averageDistance = 0;                        // stores the average value

// setup pins and variables for SRF05 sonar device

int echoPin = 12;                               // SRF05 echo pin (digital 2)
int initPin = 13;                               // SRF05 trigger pin (digital 3)
unsigned long pulseTime = 0;                    // stores the pulse in Micro Seconds
unsigned long distance = 0;                     // variable for storing the distance (cm)

int motor1Pin1 = 3;                             // pin 2 on L293D
int motor1Pin2 = 4;                             // pin 7 on L293D
int enable1Pin = 9;                             // pin 1 on L293D
int motor2Pin1 = 5;                             // pin 10 on L293D
int motor2Pin2 = 6;                             // pin  15 on L293D
int enable2Pin = 10;                            // pin 9 on L293D

void setup() {
  // set the motor pins as outputs:
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(enable1Pin, OUTPUT);
  pinMode(motor2Pin1, OUTPUT);
  pinMode(motor2Pin2, OUTPUT);
  pinMode(enable2Pin, OUTPUT);
  // set enablePins high so that motor can turn on:
  digitalWrite(enable1Pin, HIGH);
  digitalWrite(enable2Pin, HIGH);

  pinMode(initPin, OUTPUT);                     // set init pin 3 as output
  pinMode(echoPin, INPUT);                      // set echo pin 2 as input

  // create array loop to iterate over every item in the array

  for (int thisReading = 0; thisReading < numOfReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  digitalWrite(initPin, HIGH);                  // send 10 microsecond pulse
  delayMicroseconds(10);                                // wait 10 microseconds before turning off
  digitalWrite(initPin, LOW);                   // stop sending the pulse
  pulseTime = pulseIn(echoPin, HIGH);           // Look for a return pulse, it should be high as the pulse goes low-high-low
  distance = pulseTime/58;                      // Distance = pulse time / 58 to convert to cm.
  total= total - readings[arrayIndex];          // subtract the last distance
  readings[arrayIndex] = distance;              // add distance reading to array
  total= total + readings[arrayIndex];          // add the reading to the total
  arrayIndex = arrayIndex + 1;                  // go to the next item in the array                                 

  // At the end of the array (10 items) then start again
  if (arrayIndex >= numOfReadings)  {
    arrayIndex = 0;
  }

  averageDistance = total / numOfReadings;      // calculate the average distance
  delay(10);

  // check the average distance and move accordingly

  if (averageDistance <= 25){
    // go backwards
    digitalWrite(motor1Pin1, HIGH);
    digitalWrite(motor1Pin2, LOW);
    digitalWrite(motor2Pin1, HIGH);
    digitalWrite(motor2Pin2, LOW);    

  } 

  if (averageDistance <= 45 && averageDistance > 25) {
    // turn
    digitalWrite(motor1Pin1, HIGH);
    digitalWrite(motor1Pin2, LOW);
    digitalWrite(motor2Pin1, LOW);
    digitalWrite(motor2Pin2, HIGH);
  }
  if (averageDistance > 45)   {
    // go forward
    digitalWrite(motor1Pin1, LOW);
    digitalWrite(motor1Pin2, HIGH);
    digitalWrite(motor2Pin1, LOW);
    digitalWrite(motor2Pin2, HIGH);     

  }
}

[ad#Google Ad in content]

I’ve gone down the route so far of using differential steering, this means that to turn left 1 motor goes forward while the other goes in reverse. I did look at using a servo to mimic an RC cars steering but this added to complexity which for now I want to avoid.

larryBot v0.1 – 0.2

This version had two rear mounted wheels that turned either way via the L293D motor driver giving me differential steering. I also mounted a single axle at the front with 2 wheels on this. At first this one moved fine on a smooth floor but then I noticed the motor mounted wheels were slipping so I bonded them to the axle using some araldite (strong glue). This was going fine but then I noticed that when used on a different surface larryBot couldn’t turn as effectively.

larryBot v0.3

So I figured that perhaps it was the fact that the steering would be limited by having 2 front wheels, so I removed these and built in a single wheel at the front for the bot to pivot on to aid steering. Saddly this wasn’t happening and larryBot still had problems on carpet. Next I looked at the motors, essentially they were just tranferring power to the wheels via a worm gear. This isn’t really any good to get any decent torque out of the motors, so perhaps a better gear system would help me out here. I also figured that realistically wheels may not be that great for the best transport, so I looked instead at getting some tracks.

larryBot 0.4

To keep costs down I spent a while looking for a small gearbox system and track set. Logically and costwise I arrived at the decision to get a Tamiya gearbox (Tamiya part No. 70097) with motors included and a Tamiya track and wheel set (70100), the total for which including postage was about £25 you can order from the states but there are a few places in the UK that you can order from too.

I created a long wheel base much like a standard tank and mounted everything on to a new chassis cut from foamboard – nothing complicated, just a rectangle with some bolts to hold the gear box on. To add the axles to the chassis, I used some nuts and glued them on to the chassis with the glue gun to create a way to hold the axles in place.

This worked out great – larryBot conquered the carpet! Hooray! But now with the gearbox he was too fast and kept throwing his tracks off the wheels when ever he turned so he never seemed to run for more than a few seconds – no where near as long as the previous versions. Back now to rethink the wheel base and track setup.

larryBot v0.5

So today I made a new chassis, much shorter wheel base and the tracks are much tighter, tested it with the motors wired up to the battery directly and larryBot now turns fine!

I added in the circuit board and larryBot started to run BUT… the motors began to cut out frequently and the L293d chip began to get very hot. Hmmmm…. It turns out that the motors supplied with the Tamiya gear box which are Mabuchi FA-130’s draw up to 2.2A stall current per motor! the L293D chip can only deliver a maximum of 0.6A to the motor which is barely enough to freely run the motor and with tracks on this will run the motor for less than 5 seconds before cutting out

So now it looks like I have 2 choices and I think I will do both – firstly I’ll look at a new motor driver chip which can handle higher current loads and secondly I’m going to replace the gearbox motors with a motor which has a much lower stall current than the huge 2A! This will also have a nice bonus of making my batteries last longer as well as my components – perhaps also allowing me to use just 1 power supply.

Now I need new motors/ control chip

Now I need new motors/ control chip, he