Let's Make Robots!

Robotic Arm, Arduino controlled

Move his arm
RoboticCode.txt1.24 KB

Hello everybody! (:

Welcome to my -first- project page! This project will focus on the beginning of my robotic arm.

Beginning; About 1 or 2 months ago I got introduced to Arduino by a friend of mine. Soon after I found the LMR website and I've been hooked ever since.

After finding about all the possibility's Arduino has I couldn't decide which way I would go for my first bot. I decided to skip the Start Here robot, no clue why really.

At first I wanted to go with a 2WD bot, then I changed my mind and went for a tracked bot.. but after finding out all the track prices I changed my mind again.. and I set my mind on a Robot Arm :)

My end goal for the arm is quite unknown really. I cant decide between maybe something like an object tracker, or a gripper at the top or even downsize it like 5 times and go with a Rover 5.

At this moment the bot got finished building yesterday, after HOURS of designing, cutting, redesigning etc. Right at this moment I am working on the code so I can control the arm with 3 potmeters.


And now, the arm itself: The arm is about 20-30CM in height. It has 3 servo's to control the arm itself, and 1 servo to make the arm spin around its axle. The arm is made of 5mm Pespex, all glued together with Chloroform. The servo's are DYS S9650. (Oh, funny story, I ordered 4 of them cheap 9g servo's and got these s9650's delivered, they are quite a bit more expensive so thats nice)

Well, tell me what you all think!



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Thank you for all the comments, I am doing my best to read and test everything and I will post back with my results!


One thing you could do,

if (botpos != botval && botpos < botval) {
   botpos = botpos ++;
else if (botpos > botval) {
   botpos = botpos --;

is remove botpos = botpos ++; and replace botservo.write(++botpos); . The same would go for the rest of your xxxpos = and xxxservo.write statements. The ++ or -- before the variable means it would be incremented or decremented before you write it. At the very least chage the botpos = botpos ++; to botpos++;

I will check it out and see if I can figure it out.. Something else, Ismt the if (....!= && .. < ) a bit useless. Because checking if the value is lower will also check if it isnt the same.. Could I judt leave the 'check if not the same' part out? Greetings

if (botpos < botval)
if (botpos > botval)

Your suggestion
will write the previous botpos, and then, it will increment. The number that is written will always be one off from the value that was intended. That is why I wrote ++botpos instead. What I wrote would replace the botpos = botpos ++; botservo.write(botpos); with a single line. Your code could be replaced with botservo.write(botpos); botpos = botpos ++; . The difference being when the variable was incremented. 

thanks bird!

i think you have shown me this once before, but I am forgetful.  forgetful and appreciative...

hehe i'd better check my current code for this error

updated (with the style guide's recommendation of block if statements):

if (botpos < botval) {
} else
if (botpos > botval) {

What purpose is this inc/dec anyhow?

Is the intension that ...
a) ... whenever the pot changes the servo must change too and in the given direction?
b) ... the pot value is the nominal value that the servo has to follow?

To me it's a bit of a puzzle what this inc/dec is all about. What makes sense is that the pot gives the nominal value and the software tries to calculate an actual value for the servo. A classic two-level controller.

See this comment for more information.

I added the code for the arm as RoboticCode.txt, if any of you pro's out there would check it, I'd like to know how my code can be improved!

To improve your code there should be some refactoring target you set to yourself. 

One improvement could be that you respect the DRY principle. Looking at your code it seems that there are three sections. Each section is responsable for one servo. Each section has the same algorithm but applies that to a different servo. So you could extract the algorithm into a function and pass in the data that is distinct / variable. This is one way to remove code duplications.

Further you could remove all delays. Why do you use them? Do you want to make the robotic arm less reactive? If you insist on a slow behavior make one delay at the end of your loop function.

Then understandability/readability comes in when it is about the logic invariants. If you write something like if(midpos != midval && midpos < midval){...} then why don't extract this expression into a function and give the function a proper intention revealing name that reflects, what the arm does or where the arm is. That could result in if(isBelowMidpoint()){...} that makes sense without the need to understand the logic expression behind it.

But there is always room for improvement. So never mind.

This robot arm is nice. Thank you for sharing. And welcome to LMR.

Here is an example of what I ment with this comment. No DRY harms and a bit more intension revealing. To keep the leg data together I used a struct and kept all leg data in an array.

* Sample Code for RMWessels' Robot Arm
* Written by NilsB from LetsMakeRobots.com

#include <Servo.h> 

#define LEG_COUNT 3
#define PAUSE 15

struct Leg {
  int actualValue;
  int nominalValuePin;
  int servoPin;
  Servo servo;

Leg legs[LEG_COUNT];

void setup() 
  init(0,  9, A0);
  init(1, 10, A1);
  init(2, 11, A2);

void loop(){
  for(int index = 0; index < LEG_COUNT; index++){


void adjustLegAngle(int index){
  int nominalValue = readNominalValueAt(legs[index].nominalValuePin);

  if( eq(nominalValue, legs[index].actualValue) ){
    return; // Nothing to do.

  legs[index].actualValue = nominalValue;

boolean eq(int nominalValue, int actualValue){
  return actualValue == nominalValue;

void init(int index, int servoPin, int nominalValuePin){
  legs[index].servoPin = servoPin;
  legs[index].nominalValuePin = nominalValuePin;
  legs[index].actualValue = 0;

int readNominalValueAt(int nominalValuePin){
  return map(
  0, 1023, 0, 179);