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 DC motors will be activated via the H-bridge L293D and SN754410 chips.
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.
Arduino Robot Arm Code
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); } } }
Robot Arm 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
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 Robot 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.
Hack Robot Arm with Arduino: How to wire up a robot arm to Arduino.
This content is published under the Attribution-Noncommercial-Share Alike 3.0 Unported license.
- Arduino – Modifying a Robot Arm
- Obstacle avoidance Arduino robot – build your own larryBot
- Using Processing to Send Values using the Serial Port to Arduino
- Control a DC motor with Arduino and L293D chip
- larryBot – Arduino robot versions 0.1 to 0.5 lessons learned
- Arduino & Processing – Getting values from SRF05 ultrasound sensor & serial port
- Arduino – Basic Theremin meets Processing!
- Arduino + Processing – Make a Radar Screen – Part 3: Visualising the Data from Sharp Infrared Range Finder
- Arduino + Processing – 3D Sensor Data Visualisation
- Arduino + Processing – Make a Radar Screen to Visualise Sensor Data from SRF-05 – Part 1: Setting up the Circuit and Outputting Values









Sweet, I reckon I’ll be picking one of these up this weekend.
They’re cheap and you can get one with USB and some software from Maplins but I’ve read reviews and apparently its not that great programmatically. Keep checking back and let me know how you get on if you get an arm – I’ve also got a lot more to write up
your projects are amazing!
Thanks for adding to my ego
Awesome project!
I have an arduino and a store nearby is selling one of these >_>
I was thinking about incorporating this into one of my uni projects, is this alright with you? (i was reading the copryright rules etc). I will not be using your coder verbatim but I plan on taking some ideas :3 Credit to you will be given of course!
Go for it.
One thing, I’ve got more work to do on encoding the robot arm movements – you can do a simple counter to measure time taken to move a joint but I’ve found this is very in accurate – I have a solution though but I’ve still to get it working.
hi, first of all, thank you for posting your project online with the coding. i just got my arduino in the mail yesterday and i will be getting my arm next week. i wanted to just copy the code and run it to see, but it says
error: ‘import’ does not name a type In function ‘void setup()’:
In function ‘void draw()’:
At global scope:
sorry if it sounds noobish, iam very new to this. thanks
Hey no problem. I post my code to help others or for others to help me
OK your errors can be a couple of things, please forgive me for asking dumb questions here but the first code is the Arduino code that gets uploaded to the Arduino board. The second code chunk is for a program called Processing that then controls the Arduino board. So can I assume that you’re already doing this?
Secondly I’m using Arduino version 0015 so maybe my code is outdated what version of the Arduino IDE/ program and version of Processing are you using?
If you need help please ask, it takes me ages to find answers sometimes (I’m struggling right now with opamps!).
Cheers,
Larry.
Hi Larry,
Just wanted to drop by and say thanks for writing up this project, great stuff! I have just started playing with Arduino for the first time and had exactly this in mind (cannibalising the kit arm) for a first project.
Ultimately I’d like to try and control it physically with accelerometers, probably by interfacing a Wii nunchuk or the new TI ez430 Chronos developers watch. Could make for a cool wearable controller
Really look forward to your next installment, keep up the good work!
Ryan.
I think I’ve nearly got it sorted to measure the joint movement using some wheel encoders out of an old mouse and if that works out then I might have to look at the Chronos watch
Cool. Just spotted a youtube vid of someone using the watch to control an arm, clever stuff. The watch is pretty neat for only ~£30.
Excellent work, i’m so glad i stumbled across your amazing blog!
I recently did a 2-day Arduino workshop, and i’d love to try and build a robot arm.
Your Arduino projects are brilliant!
Keep up the good work!
Thankyou!
The good thing about Arduino is it gets you started into Electronics very easily. Now I’m getting in the deeper end and considering a course
Thanks Larry, i finally built my own robot arm, all credit goes to you though.
Thank you so much for sharing your instructions and code with us.
I am in awe of your Arduino knowledge
Thank you once again!
You’re very welcome although please improve on my work!
hey larry, thanks for helping me with my earlier doubt. iam just keen to know, are u still gonna work on the inverse kinematics? i think that would be cool. also i had a doubt, will it be easy to use the accelormeter on my ipod touch to control the robot, would i need to develop an iphone app for that? thanks
use iosc
Cool, iosc on the iphone?
thank you guys, i used touchosc and now i can control the robot with my ipod touch. Its pretty cool..
Cool. Definitely cool. I’m going to build an arm from scratch but I hope to get to using something like an iPod or phone to control it.
hi larry…
nice job… i am building my first robotic arm… your work will help me a lot… i have few queries though… first why arent u using a servo motor as arduino have library for it… and what changes should i make in the code if a intend to use a servo motor..
I would love to use servos Rohan! Trouible is the robot arm kit I had uses motors in their own gearboxes and it seemed like less work to stick with the motors.
With servos it would be awesome since you don’t have to worry about encoding the position of each servo – something I’m currently trying to do, which I think Ive figured out.
If you were to use servos, you would have to add the library to Arduino, you wouldn’t need the H-bridge chips just 5 pins, 1 for each servo and the power and gnd connections for each. If you’re using larger servos greater than 5 volts or a 40 mA draw you would need to use a separate power supply and use some transistors -TIP120′s or something.
Code wise not much would be needed to be modified, just for each key press you would rotate a servo using PWM instead – I’ve done some servo work here: http://luckylarry.co.uk/tag/servo/
If anyone knows of a cheap(ish) arm with servos let me know!
hi larry,
can you please suggest me some online tutorial for inverse kinematics… i need to study it from the scratch… i want to build a robotic arm that will orient its joints itself so as to reach the final position…
Hi Rohan,
You will need some servos to do this which Arduino can control very easily. Depending on how many joints you want but start with 2.
To control them you’ll want to use something like Processing.org for which you can use the librarys to control the servo position.
For Inverse Kinematics to work you need to be able to accurately measure the degrees of movement in each joint – hence Servos, although you can can do stepper motors and the rotary encoder route but why bother.
I will write an IK tutorial up that shows how to calculate the angles very easily in Processing – its not a ‘true’ way to do IK but the end result is the same and the trigonmetry is easier to understand. I can also write up a brief traditional tutorial on IK too.
I was looking at getting 5 servos and an arm kit myself to do this so if you find any cheap enough let me know.
Larry.
Looking forward to seeing that Larry
I finished my arm, thanks for your guide. Interfaced it with the accelerometers in the Chronos watch too, works nicely! Will try and get a video up soon.
Ryan.
sweet! look forward to seeing the video. So how does your acceloremeter move the arm – does it just do a different motor depending on the movement?
Yeah, a simple processing sketch requests the acc data via a serial com port (the USB receiver MCU). The watch then sends back 7 bytes of info, whihch includes button presses & XYZ values. Very straightforward.
At the moment I have coded it simply, so that a change in one axis above or below a threshold results in the corresponding motor activation (by passing an ASCII value to the arduino as per your sketch). What would be nice is to code it so that the last acc value is stored and then compared to the current value, so that the motors could respond immediately to movement (rather than having to move your arm all the way down or all the way up to activate the corresponding motor).
I am also playing with RoboRealm (image processing software) at the moment too, eventually Id’d like to bolt a webcam to the arm and have it identify tarkets and track movement. Definitely getting into servo’s there tho!
Hi Larry
I’ve just built my USB version of the robot arm and the supplied software is terrible. I’ll bin it and use your Arduino version instead ASAP.
I’m very interested in your rotary encoder and IK solutions. Any news on your next installment?
Thanks
Fergal
Hi Fergal,
Its awful – basically it does what I was going to try to program but found it to be useless and inaccurate.
I’ve just invested in some tools to modify the arm so I can attach encoders to the motors, also I’m looking at building an arm from scratch using servos instead
just made it
fantastic
thanks
Hi Larry – excellent project. I found the procontrol library and adapted your code to use a PC joystick – I must I’m very impressed with the whole thing. The Arduino is a very nice platform.
Thanks for posting it
Dave
Hi Dave,
My only gripe with the arm is the lack of control, or rather repeated control and precision.
I’m working on building an arm from scratch, for about the same cost, which should make programming it easier (I hope).
Did you have a link to your project?
Cheers,
Larry