Introduction: Make Wired Robotic Arm Edge to "Wireless" With DIY Arduino + XBee

About: I am Electronic Visualization Artist. I look at things through the Looking Glasses.


UPDATE: Added Schematic, Top Layer PCB, Bottom Layer PCB, and both Top, Bottom PCB images

When I finished the  "RevIO" - an Arduino Clone that has the different way of exposing pins usage. I decided to go further to the next project. To test my "RevIO" board that it could do the bigger task than just blinking the LED!

I modified the Wired Robotic Arm Edge to Wireless controlled, using my "RevIO" and DIY Three-Motor Driver ICs PCB together with XBee Series 1 module.

This instructables introduces the way I constructed Three-Motor Driver ICs PCB from scratch. Then using it as the "piggy back" on my "RevIO" Board.

To control the Robotic Arm, I designed the GUI (Graphical User Interface) with the Processing on the PC and Arduino sketch for driving the motors.

I also added the 6-pin socket as an alternative to use Bluetooth module (Sparkfun's Bluetooth Modem - Blue SMiRF Silver, or Bluetooth Modem - Blue SMIRF Gold.)

Again I am going to use the same presentation method as Build "The RevIO" (Arduino Clone) My Way,  to build the board using the graphical illustrations, together with the photos of actual build of the board.

Step 1: Build the Robotic Arm Edge

I got the Robotic Arm Edge Kit from TPE Shop in Thailand three months ago, while I was visiting my family in Thailand. But I did not do until I got back to USA a month later. 

This is my very first Robotic Arm I ever encountered with. A week after I got back, I started to constructed the kit. I spend about four hours to build and pause to take pictures for this instructables.

I will not show you how I managed to put the kit together, but here is the collage of how I put the Robotic Arm together from the start to finish!

Step 2: Parts

IC1, IC2, IC3 H-Bridge Motor Driver 1A, SN754410 (Sparkfun #COM-00315)  or L293D (Digikey#497-2936-5-ND)
R1 - 1K Resistor (Radio Shack #271-1321 or Digkey #PPC1.0KW-1CT-ND)
LED1 - 3mm Red LED (Digikey #160-1708-ND)
S1 - Slide DPDT Switch (Digikey #401-2000-ND)
JP1 - 2x6 Male Header Connector, Straight
JP2, JP3 -(2) 14-pin Male header, extra long pin or use shield stacking headers (Adafruit ID#85)
JP4 - 2-pin Male Header Connector, Right Angle
JP5 - 6-pin Female Connector, Right angle
16-pin IC Socket (Radio Shack #276-1998)
Multipurpose PC Board with 417 holes (Radio Shack #276-150)
Wire

The RevIO or any kind of Arduino
Note: In case of using Arduino or others Arduino Clone you needed to make the Motor Control Board to match those Arduino.

Other parts:
2 XBee Modules I got the Series 1 from AdaFruit
2 Xbee Adapter Board from AdaFruit

Alternativel part:
Bluetooth Modem - Blue SMiRF Gold (Sparkfun# WRL-10268)
or Bluetooth Modem - Blue SMiRF Silver (Sparkfun# WRL-10269)

Step 3: Layout & Schematic

As mentioned in the intro. I planned to use this motors driver board as a "piggy back" on the RevIO PCB. So I obtained the same PCB (Radio Shack #276-150) to match my RevIO's exposed pins. I tried to use the plain PCB (Radio Shack #276-149) so I could put the three H-Bridge Motors Drivers in parallel to the width of the PCB, but that did not worked! Because the holes on the width side was one hole short of the RevIO.

Notice that I placed the board by having the two row of individual holes on top and three rows of individual holes on the bottom. So it matches the layout of the RevIO board.

Luckily, I could fit three H-Bridge Motor Drivers IC on the Multipurpose PC Board with 417 holes (Radio Shack #276-150) by put them one after another over the positive and negative rails in the middle of the board.

The other good thing was that there were enough space to put 2x6 male header, for motors control pins and led on the board. So I place them on the top left corner of the board next to the top 14-pin rail. And also there were enough space to put a 6-pin connector as an alternative for Bluetooth breakout board. (Bluetooth Modem - Blue SMiRF Gold (Sparkfun# WRL-10268) or Bluetooth Modem - Blue SMiRF Silver (Sparkfun# WRL-10269)) . So I placed it on the bottom right corner of the PCB.

Step 4: Tools

Solder iron and Soldering Work Station

Solder - Rosin Core (Radio Shack #64-013)
Hookup Wire
Multimeter
Diagonal cutter
Pliers
X-Acto Knife
Wire Stripper
Solder Sucker
etc. (something else that you might want to use.)

Step 5: Lets the Fun Begin...

Places the components on PCB

First component I added to my Motors Controller Board is power connector (JP4).

Second component I added was JP2 - 2x6 Motors and LED connector from Robotic Arm Edge.

Next components added was LED1 - Motor Power Supply indicator LED  and then R1 -  1K resistor.

Then I added S1 -  Motor Power Switch.

And added 6-pin female connector to make a Bluetooth-ready connector. (optional)

Step 6: Wiring the Main Ground

Connected the ground or negative(-) pin of the Power Jack to Switch S1.

Step 7: Motor Drivers

I added first motor driver IC to the board. This motors driver are used to control Grip (M1 - as shown in the Robotic Arm Manual) and wrist (M2) of the Robotic Arm. After that I connected  the ground pins of the H-Bridge IC (pin 4, 5, 12, and 13).

Next, I added second H-Bridge IC. This motors driver are use to control Elbow (M3) and Shoulder(M4). And also connected the ground pins of the H-Bridge IC (pin 4, 5, 12, and 13).

And I added the third H-Bridge IC. This motors driver are use to control only one last motor of the Robotic Arm, Base (M5). Again I connected the ground pins of the H-Bridge IC (pin 4, 5, 12, and 13).

After that I connected all the ground together.

Step 8: Motors Power Supply

Connect the motors power supply to pin 8 of middle H-Bridge ICs.

Connect pin 16, 5V pins, of three H-Bridge ICs together. Then connect the 5V pins on the H-Bridge ICs to Arduino 5V pin.

Step 9: Motor Controller Pins

Connect the motors control pins to Arduino            

Grip (M1)
Motor Pin     Arduino Pin
9                   D10
10                 D9
15                 D5

Motor Pin    2x6 Motors Header Connector            
11                 M1 Bottom Row
14                 M1 Top Row
Add 14-pin female connectors

Wrist (M2)
Motor Pin     Arduino Pin
1                   D11
2                   D8
7                   D12

Motor Pin    2x6 Motors Header Connector             
6                   M2 Top Row
3                   M2 Bottom Row

Elbow (M3)
Motor Pin     Arduino Pin
9                   D6
10                 D7
15                 D14 or A0(As shown on the diagram)

Motor Pin    2x6 Motors Header Connector            
11                 M3 Top Row
14                 M3 Bottom Row

Shoulder (M4)
Motor Pin     Arduino Pin
1                   D14 or A0(As shown on the daigram)
2                   D2
7                   D4

Motor Pin    2x6 Motors Header Connector            
3                   M4 Bottom Row
6                   M4 Top Row

Base (M5)
Motor Pin     Arduino Pin
9                   D3
10                 D16 or A2(As shown on the diagram)
15                 D17 or A3(As shown on the diagram)

Motor Pin    2x6 Motors Header Connector            
11                 M3 Top Row
14                 M3 Bottom Row

LED Light (L)
2x6 Motors Header Connector   Arduino Pin
L Top Row                                     D13
L Bottom Row                               Gnd

Step 10: (Alternative) Bluetooth


I added Bluetooth connector as an alternative. If you want to use Bluetooth instead of Xbee, you have to remove XBee module. And you have to remove Bluetooth out of the socket, when you are upload the sketch to Arduino Board. Since all of these three share the same Serial Comm. port.

One good thing is that Arduino sketch could be share between Bluetooth and XBee, since both are using Serial Comm.

Note that, this bluetooth connector is pins compatible with the Sparkfun's Modem - BlueSMirF GOLD or BlueSMiRF SILVER.
for more infomation and bluetooth tutorial see Sparkfun's Bluetooth Tutorial.

Step 11: Add Power Supply to Arduino

I want to conserve the existing battery power supply, also I want the Arduino to have its own power supply. So I decided to add the 9V battery to the Robot, as close to the Arduino power jack as possible. The most suitable place is at the end of the Robot battery compartment.

Before I installed the 9V battery holder I removed some of the existing parts, the PCB, and its yellow cover. And I no longer needed the existing handheld controller.

I drilled two holes on the battery compartment to fit the holes of the9V battery holder.

I removed the RevIO case, so I could drill two holes to fit the existing holes that used to hold the yellow cover. And made one big round opening for the screw that hold the Robot battery cover.

Step 12: Test the Motors Driver Board

Following sketch is for testing the motors and LED light.

The sketch only test Robot's base motors. To test another motor, add the functions i.e gripUp(), gripDown(), and gripPause(mSecond) to test Robot grip motor, etc...

Note: remove the XBee module (or Bluetooth, if you use Bluetooth) before upload the sketch to Arduino!

// Test Robotic Arm motors and LED light

// Grip (M1) IN and OUT action
int gripEnablePin = 10;
int gripPin1 = 9;
int gripPin2 = 5;

// Wrist (M2) UP and DOWN action
int wristEnablePin = 11;
int wristPin1 = 8;
int wristPin2 = 12;

// Elbow (M3) UP and DOWN action
int elbowEnablePin = 6;
int elbowPin1 = 7;
int elbowPin2 = 15;

// Shoulder (M4) UP and DOWN action
int shoulderEnablePin = 14;
int shoulderPin1 = 2;
int shoulderPin2 = 4;

// Base (M5) RIGHT and LEFT action
int baseEnablePin = 3;
int basePin1 = 16;
int basePin2 = 17;

// LED ON and OFF action
int ledLight = 13;

void setup() {
pinMode(ledLight, OUTPUT);

// grip (M1)
pinMode(gripEnablePin, OUTPUT);
pinMode(gripPin1, OUTPUT);
pinMode(gripPin2, OUTPUT);

// wrist (M2)
pinMode(wristEnablePin, OUTPUT);
pinMode(wristPin1, OUTPUT);
pinMode(wristPin2, OUTPUT);

// elbow (M3)
pinMode(elbowEnablePin, OUTPUT);
pinMode(elbowPin1, OUTPUT);
pinMode(elbowPin2, OUTPUT);

// shoulder (M4)
pinMode(shoulderEnablePin, OUTPUT);
pinMode(shoulderPin1, OUTPUT);
pinMode(shoulderPin2, OUTPUT);

// base (M5)
pinMode(baseEnablePin, OUTPUT);
pinMode(basePin1, OUTPUT);
pinMode(basePin2, OUTPUT);
}

void loop() {
    // turn on/off Robot LED
    digitalWrite(ledLight, HIGH);
    delay(500);
    digitalWrite(ledLight, LOW);
    delay(500);

    // rotate right for 1500 milliseconds
    baseRight();
    delay(1500);

    // pause for 1000 milliseconds
    basePause(1000);

    // rotate left for 1000 milliseconds
    baseLeft();
    delay(1000);

    basePause(1000);

}

void gripIn() {
    digitalWrite(gripEnablePin, HIGH);
    digitalWrite(gripPin1, LOW);
    digitalWrite(gripPin2, HIGH);
}

void gripOut() {
    digitalWrite(gripEnablePin, HIGH);
    digitalWrite(gripPin2, LOW);
    digitalWrite(gripPin1, HIGH);
}

void gripPause(int mSec) {
    digitalWrite(gripEnablePin, LOW);
    digitalWrite(gripPin1, LOW);
    digitalWrite(gripPin2, LOW);

    delay(mSec);
}

void wristUp() {
    digitalWrite(wristEnablePin, HIGH);
    digitalWrite(wristPin1, LOW);
    digitalWrite(wristPin2, HIGH);
}

void wristDown() {
    digitalWrite(wristEnablePin, HIGH);
    digitalWrite(wristPin2, LOW);
    digitalWrite(wristPin1, HIGH);
}

void wristPause(int mSec) {
    digitalWrite(wristEnablePin, LOW);
    digitalWrite(wristPin1, LOW);
    digitalWrite(wristPin2, LOW);

    delay(mSec);
}

void elbowUp() {
    digitalWrite(elbowEnablePin, HIGH);
    digitalWrite(elbowPin1, LOW);
    digitalWrite(elbowPin2, HIGH);
}

void elbowDown() {
    digitalWrite(elbowEnablePin, HIGH);
    digitalWrite(elbowPin2, LOW);
    digitalWrite(elbowPin1, HIGH);
}

void elbowPause(int mSec) {
    digitalWrite(elbowEnablePin, LOW);
    digitalWrite(elbowPin1, LOW);
    digitalWrite(elbowPin2, LOW);

    delay(mSec);
}

void shoulderUp() {
    digitalWrite(shoulderEnablePin, HIGH);
    digitalWrite(shoulderPin1, LOW);
    digitalWrite(shoulderPin2, HIGH);
}

void shoulderDown() {
    digitalWrite(shoulderEnablePin, HIGH);
    digitalWrite(shoulderPin2, LOW);
    digitalWrite(shoulderPin1, HIGH);
}

void shoulderPause(int mSec) {
    digitalWrite(shoulderEnablePin, LOW);
    digitalWrite(shoulderPin1, LOW);
    digitalWrite(shoulderPin2, LOW);

    delay(mSec);
}

void baseRight() {
    digitalWrite(baseEnablePin, HIGH);
    digitalWrite(basePin1, LOW);
    digitalWrite(basePin2, HIGH);
}

void baseLeft() {
    digitalWrite(baseEnablePin, HIGH);
    digitalWrite(basePin2, LOW);
    digitalWrite(basePin1, HIGH);
}

void basePause(int mSec) {
    digitalWrite(baseEnablePin, LOW);
    digitalWrite(basePin1, LOW);
    digitalWrite(basePin2, LOW);

    delay(mSec);
}

Step 13: Configure XBee and Test XBee

In order to cntrol the Robotic Arm with the XBee, we need two XBee Modules, and one FTDI cable. One XBee module will be connected to Arduino without FTDI cable.

The second XBee Module will be connected to PC or Laptop via FTDI cable.

This instructable is intentional for building the motors controller board. It would take up a lot of space and time to explain the installation, configuration, and test the XBee module.

Here are my WIKI XBee tutorials, show how to configure and test XBee module using Hyperterminal, and X-CTU:

Configure XBee using AT Commands.

Configure XBee using X-CTU Software.

My XBee video tutorial.



Following are the list of the links of the great resources to learn all about the XBee.

Tutorials and infomation:

XBee Radios at AdaFruit

Datasheet, specification, and cofiguration app. from Digi

Step 14: Arduino Sketch & Processing Code


Following are the Arduino Sketch and Processing Source Code (both Arduino Sketch and Processing are in the same zip file below) :

If you are using this sketch, please set the Baud Rate of your XBee according to your XBee setup.

void setup() {
  ...
  // change the Baud Rate according to your XBee, I set my XBee to 115200.
  Serial.begin(115200);
  ...

}


//============ Arduino Sketch

// Language: Arduino
// RobotArmControl.pde
//
// by Sam Thongrong Feb 26, 2012
// rev.02
// control commands array:
// {GripOut, GripIn, WristUp, WristDown, ElbowUp, ElbowDown,
// ShoulderUp, shoulderDown, BaseCW, BaseCCW, LightOn, LightOff, Stop};
int controls[13] = { 0x47, 0x67, 0x57, 0x77, 0x45, 0x65,
                   0x53, 0x73, 0x42, 0x62, 0x4c, 0x6c, 0x58 };

// Base
int baseEnablePin = 3;
int basePin1      = 16;
int basePin2      = 17;

// Shoulder
int shoulderEnablePin = 14;
int shoulderPin1      = 2;
int shoulderPin2      = 4;

// Elbow
int elbowEnablePin = 6;
int elbowPin1      = 7;
int elbowPin2      = 15;

// Wrist
int wristEnablePin = 11;
int wristPin1      = 8;
int wristPin2      = 12;

//Grip
int gripEnablePin = 10;
int gripPin1      = 9;
int gripPin2      = 5;

int ledPin = 13;

// set a variable to store the byte sent from the serial port
int incomingByte;

void setup() {
  // set light LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // set the SN754410 pins as outputs:
  pinMode(basePin1, OUTPUT);
  pinMode(basePin2, OUTPUT);
  pinMode(baseEnablePin, OUTPUT);

  pinMode(shoulderPin1, OUTPUT);
  pinMode(shoulderPin2, OUTPUT);
  pinMode(shoulderEnablePin, OUTPUT);

  pinMode(elbowPin1, OUTPUT);
  pinMode(elbowPin2, OUTPUT);
  pinMode(elbowEnablePin, OUTPUT);

  pinMode(wristPin1, OUTPUT);
  pinMode(wristPin2, OUTPUT);
  pinMode(wristEnablePin, OUTPUT);

  pinMode(gripPin1, OUTPUT);
  pinMode(gripPin2, OUTPUT);
  pinMode(gripEnablePin, OUTPUT);

  // start sending data at 115200 baud rate
  // I set my Xbee Baud Rate at 115200 bps,
  // change the Baud Rate according to your XBee
  Serial.begin(115200);
}

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.

    //===== Grip
    // Grip in
    if (incomingByte == controls[0]) {
      gripIn();
    }
    // Grip Out
    if (incomingByte == controls[1]) { 
      gripOut();
    }

    //Wrist
    if (incomingByte == controls[2]) {
    //digitalWrite(wristPin1, LOW);  
    //digitalWrite(wristPin2, HIGH); 
    wristUp();
    }
    if (incomingByte == controls[3]) {   
      wristDown();
    }

    //===== Elbow
    // Elbow Up
    if (incomingByte == controls[4]) {
      elbowUp();
    }
    // Elbow Down
    if (incomingByte == controls[5]) {
      elbowDown();
    }

    //===== Shoulder
    // Shoulder Up
    if (incomingByte == controls[6]) {
      shoulderUp();
    }
    // Shoulder Down
    if (incomingByte == controls[7]) {
      shoulderDown();
    }

    //===== Base
    // Base Right
    if (incomingByte == controls[8]) {
      baseRight(); 
    }
    // Base Left
    if (incomingByte == controls[9]) {
      baseLeft();
    }

    // Light ON
    if (incomingByte == controls[10]) {
      digitalWrite(ledPin, HIGH);
    }
    // Light OFF
    if (incomingByte == controls[11]) {
      digitalWrite(ledPin, LOW);
    }

    // if a O is sent make sure the motors are turned off
    if (incomingByte == controls[12]) {
      allStop();
    }

    delay(100);
  }
}

void gripIn() {
    digitalWrite(gripEnablePin, HIGH);
    digitalWrite(gripPin1, LOW);
    digitalWrite(gripPin2, HIGH);
}

void gripOut() {
    digitalWrite(gripEnablePin, HIGH);
    digitalWrite(gripPin2, LOW);
    digitalWrite(gripPin1, HIGH);
}

void wristUp() {
    digitalWrite(wristEnablePin, HIGH);
    digitalWrite(wristPin1, LOW);
    digitalWrite(wristPin2, HIGH);
}

void wristDown() {
    digitalWrite(wristEnablePin, HIGH);
    digitalWrite(wristPin2, LOW);
    digitalWrite(wristPin1, HIGH);
}

void elbowUp() {
    digitalWrite(elbowEnablePin, HIGH);
    digitalWrite(elbowPin1, LOW);
    digitalWrite(elbowPin2, HIGH);
}

void elbowDown() {
    digitalWrite(elbowEnablePin, HIGH);
    digitalWrite(elbowPin2, LOW);
    digitalWrite(elbowPin1, HIGH);
}

void shoulderUp() {
    digitalWrite(shoulderEnablePin, HIGH);
    digitalWrite(shoulderPin1, LOW);
    digitalWrite(shoulderPin2, HIGH);
}

void shoulderDown() {
    digitalWrite(shoulderEnablePin, HIGH);
    digitalWrite(shoulderPin2, LOW);
    digitalWrite(shoulderPin1, HIGH);
}

void baseRight() {
    digitalWrite(baseEnablePin, HIGH);
    digitalWrite(basePin1, LOW);
    digitalWrite(basePin2, HIGH);
}

void baseLeft() {
    digitalWrite(baseEnablePin, HIGH);
    digitalWrite(basePin2, LOW);
    digitalWrite(basePin1, HIGH);
}

void allStop() {
    digitalWrite(baseEnablePin, LOW);
    digitalWrite(basePin1, LOW);  
    digitalWrite(basePin2, LOW);

    digitalWrite(shoulderEnablePin, LOW);
    digitalWrite(shoulderPin1, LOW);  
    digitalWrite(shoulderPin2, LOW);

    digitalWrite(elbowEnablePin, LOW);
    digitalWrite(elbowPin1, LOW);  
    digitalWrite(elbowPin2, LOW); 

    digitalWrite(wristEnablePin, LOW);
    digitalWrite(wristPin1, LOW);  
    digitalWrite(wristPin2, LOW);

    digitalWrite(gripEnablePin, LOW);
    digitalWrite(gripPin1, LOW);  
    digitalWrite(gripPin2, LOW);
}

//=========== Arduino End



Following is the Processing Source Code. You'ill need the background image file, and all the buttons image files in order to see those control buttons on the screen.

And all the background and buttons are provided ad there are in the folder called data. You will need to have this folder located in the same folder of the Processing code (RobotArmControl.pde)

// Language: Processing
// RobotArmControl.pde

// by Sam Thongrong Feb 26, 2012

// load the serial library for Processing
import processing.serial.*;
// instance of the serial class
Serial port;

// control commands array:
// GripOut, GripIn, WristUp, WristDown, ElbowUp, ElbowDown,
// ShoulderUp, shoulderDown, BaseCW, BaseCCW, LightOn, LightOff, Stop

int[] controls = new int[] {
  0x47, 0x67, 0x57, 0x77, 0x45, 0x65,
  0x53, 0x73, 0x42, 0x62, 0x4c, 0x6c, 0x58 };

// Image button.
// Loading images and using them to create a button.
ImageButtons GripIn;
ImageButtons GripOut;
ImageButtons WristUp;
ImageButtons WristDown;
ImageButtons ElbowUp;
ImageButtons ElbowDown;
ImageButtons ShoulderUp;
ImageButtons ShoulderDown;
ImageButtons BaseCW;
ImageButtons BaseCCW;
ImageButtons LightOn;
ImageButtons LightOff;

ImageButtons Pause;

// background
PImage bg;

// set the font
PFont myFont;

void controlGUI()
{
  bg = loadImage("background.jpg");
  background(bg);

  int buttonSize = 44;

  PImage selected = loadImage("controlSel.png");

  //Grip In
  PImage gripInImage = loadImage("controlIn.png");
  PImage gripInOver = loadImage("controlInOver.png");
  GripIn = new ImageButtons(30, 83, buttonSize, buttonSize,
                               gripInImage, gripInOver, selected);

  //Grip Out
  PImage gripOutImage = loadImage("controlOut.png");
  PImage gripOutOver = loadImage("controlOutOver.png");
  GripOut = new ImageButtons(78, 83, buttonSize, buttonSize,
                               gripOutImage, gripOutOver, selected);

  //Wrist Up
  PImage wristUpImage = loadImage("controlUp.png");
  PImage wristUpOver = loadImage("controlUpOver.png");
  WristUp = new ImageButtons(150, 36, buttonSize, buttonSize,
                               wristUpImage, wristUpOver, selected);

  //Wrist Down
  PImage wristDownImage = loadImage("controlDown.png");
  PImage wristDownOver = loadImage("controlDownOver.png");
  WristDown = new ImageButtons(198, 36, buttonSize, buttonSize,
                               wristDownImage, wristDownOver, selected);

  //Elbow Up
  PImage elbowUpImage = loadImage("controlUp.png");
  PImage elbowUpOver = loadImage("controlUpOver.png");
  ElbowUp = new ImageButtons(258, 83, buttonSize, buttonSize,
                               elbowUpImage, elbowUpOver, selected);

  //Elbow Down
  PImage elbowDownImage = loadImage("controlDown.png");
  PImage elbowDownOver = loadImage("controlDownOver.png");
  ElbowDown = new ImageButtons(306, 83, buttonSize, buttonSize,
                               elbowDownImage, elbowDownOver, selected);

  //Shoulder Up
  PImage shoulderUpImage = loadImage("controlUp.png");
  PImage shoulderUpOver = loadImage("controlUpOver.png");
  ShoulderUp = new ImageButtons(208, 160, buttonSize, buttonSize,
                               shoulderUpImage, shoulderUpOver, selected);

  //Shoulder Down
  PImage shoulderDownImage = loadImage("controlDown.png");
  PImage shoulderDownOver = loadImage("controlDownOver.png");
  ShoulderDown = new ImageButtons(256, 160, buttonSize, buttonSize,
                               shoulderDownImage, shoulderDownOver, selected);

  //Base CW
  PImage baseCWImage = loadImage("controlCW.png");
  PImage baseCWOver = loadImage("controlCWOver.png");
  BaseCW = new ImageButtons(130, 234, buttonSize, buttonSize,
                               baseCWImage, baseCWOver, selected);

  //Base CCW
  PImage baseCCWImage = loadImage("controlCCW.png");
  PImage baseCCWOver = loadImage("controlCCWOver.png");
  BaseCCW = new ImageButtons(178, 234, buttonSize, buttonSize,
                               baseCCWImage, baseCCWOver, selected);
  //Light On
  PImage lightOnImage = loadImage("LightOn.png");
  PImage lightOnOver = loadImage("LightOnOver.png");
  LightOn = new ImageButtons(30, 184, buttonSize, buttonSize,
                               lightOnImage, lightOnOver, selected);

  //Light Off
  PImage lightOffImage = loadImage("LightOff.png");
  PImage lightOffOver = loadImage("LightOffOver.png");
  LightOff = new ImageButtons(78, 184, buttonSize, buttonSize,
                               lightOffImage, lightOffOver, selected);

}

void setup()  {
  // 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());
  // 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 (112500bps)
  //port = new Serial(this, Serial.list()[1], 112500);

  // On Window PC, use "Outgoing" of the bluetooth device
  // This one for XBee
  port = new Serial(this, "COM30", 115200);

  // screen size of the program
  //size(145, 455);
  size(400, 300);
  smooth();

  // test ellipse
  ellipseMode(RADIUS);
  textFont(createFont("Verdana", 14));

  controlGUI();

}

void updateDisplay() {

  GripIn.update();
  GripIn.display();
  GripOut.update();
  GripOut.display();

  WristUp.update();
  WristUp.display();
  WristDown.update();
  WristDown.display();

  ElbowUp.update();
  ElbowUp.display();
  ElbowDown.update();
  ElbowDown.display();

  ShoulderUp.update();
  ShoulderUp.display();
  ShoulderDown.update();
  ShoulderDown.display();

  BaseCW.update();
  BaseCW.display();
  BaseCCW.update();
  BaseCCW.display();

  LightOn.update();
  LightOn.display();
  LightOff.update();
  LightOff.display();
}

//Send Commands
void sendCommands() {

  // Grip
  if(GripIn.pressed) {
      port.write(controls[0]);
      //println("Grip In: " + (char)controls[0]);
  }
  if(GripOut.pressed) {
      port.write(controls[1]);
      //println("Grip Out: " + (char)controls[1]);
  }
  if(mouseX > 30 && mouseX < 129 &&
     mouseY > 51 && mouseY < 79) {
       port.write(controls[12]);
       //println("Grip Stop! " + (char)controls[12]);
  }

  // Wrist
  if(WristUp.pressed) {
      port.write(controls[2]);
      //println("Wrist Up: " + (char)controls[2]);
  }
  if(WristDown.pressed) {
      port.write(controls[3]);
      //println("Wrist Down: " + (char)controls[3]);
  }
  if(mouseX > 148 && mouseX < 248 &&
     mouseY > 5 && mouseY < 33) {
       port.write(controls[12]);
       //println("Wrist Stop! " + (char)controls[12]);
  }

  // Elbow
  if(ElbowUp.pressed) {
      port.write(controls[4]);
      //println("Elbow Up: " + (char)controls[4]);
  }
  if(ElbowDown.pressed) {
      port.write(controls[5]);
      //println("Elbow Down: " + (char)controls[5]);
  }
  if(mouseX > 258 && mouseX < 358 &&
     mouseY > 51 && mouseY < 79) {
       port.write(controls[12]);
       //println("Elbow Stop! " + (char)controls[12]);
  }

  //Shoulder
  if(ShoulderUp.pressed) {
      port.write(controls[6]);
      //println("Shoulder Up: " + (char)controls[6]);
  }  
  if(ShoulderDown.pressed) {
      port.write(controls[7]);
      //println("Shoulder Down: " + (char)controls[7]);
  }
  if(mouseX > 208 && mouseX < 308 &&
     mouseY > 130 && mouseY < 158) {
       port.write(controls[12]);
       //println("Shoulder Stop! " + (char)controls[12]);
  }

  // Base
  if(BaseCW.pressed) {
      port.write(controls[8]);
      //println("Base Rotate CW: " + (char)controls[8]);
  }
  if(BaseCCW.pressed) {
      port.write(controls[9]);
      //println("Base Rotate CCW: " + (char)controls[9]);
  }
  if(mouseX > 130 && mouseX < 230 &&
     mouseY > 202 && mouseY < 230) {
       port.write(controls[12]);
       //println("Base Stop! " + (char)controls[12]);
  }

  // Light
  if(LightOn.pressed) {
      port.write(controls[10]);
      //println("Light On: " + (char)controls[10]);
  }
  if(LightOff.pressed) {
      port.write(controls[11]);
      //println("Light Off: " + (char)controls[11]);
  }
}

void draw()
{
  updateDisplay();

  sendCommands();
}

// Button & ImageButtons Classes
class Button
{
  int x, y;
  int w, h;
  color basecolor, highlightcolor;
  color currentcolor;
  boolean over = false;
  boolean pressed = false;  

  void pressed() {
    if(over && mousePressed) {
      pressed = true;
    } else {
      pressed = false;
    }   
  }

  boolean overRect(int x, int y, int width, int height) {
  if (mouseX >= x && mouseX <= x+width &&
      mouseY >= y && mouseY <= y+height) {
    return true;
  } else {
    return false;
  }
}
}

class ImageButtons extends Button
{
  PImage base;
  PImage roll;
  PImage down;
  PImage currentimage;

  ImageButtons(int ix, int iy, int iw, int ih,
               PImage ibase, PImage iroll, PImage idown)
  {
    x = ix;
    y = iy;
    w = iw;
    h = ih;
    base = ibase;
    roll = iroll;
    down = idown;
    currentimage = base;
  }

  void update()
  {
    over();
    pressed();
    if(pressed) {
      currentimage = down;
    } else if (over){
      currentimage = roll;
    } else {
      currentimage = base;
    }
  }

  void over()
  {
    if( overRect(x, y, w, h) ) {
      over = true;
    } else {
      over = false;
    }
  }

  void display()
  {
    image(currentimage, x, y);
  }
}

// Processing End

To control Robot Arm motor, moves the cursor to the required button and click.
To stop operation just move the cursor to any label. Robot will stop.
In order to operate multiple motors at once, move the cursor to the buttons required, and click those buttons.
But do not drag cursor pass over the labels, that will cause the operation to stop

Enjoy!.

Step 15: Video

Here is the video.

Arduino Challenge

Participated in the
Arduino Challenge