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.

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.

Thanks alot for your extensive comment! I will go and read all the seperate articles now and see where I can do all of the improvements.

Some thing I cant find anywhere, nor can come op with myself.. 

Since the potmeter isnt 100% accurate (It gives a value between e.g. 130-132 when the potmeter is at 131) this makes the servo jerky and I wanted to get rid of that. 

What I thought up was.. make 2 variables.

int 1 = potmeter value and int 2 makes the current servo value (servo.read()). Then the difference between those has to be atleast 3 in order for the servo to move. I cant find any arduino function to compare, nor could I find some help on the internet.. Any of you all that got a clue? 


Thanks again,




And oh, I added the delays so the arm would move terrible slow so I could see whats going on. In the "final" code I want it to be faster.

It looks like as if you have a map problem. For every potentiometer value there is a given servo position. Where the pot theoretically is a continuous value, the servo position is a discreete value. This is due the gears and their ratio.

So you could use some algorithm to solve the map problem or use: a map. For each pot value look up the servo value from this map and apply the servo value to the servo.

Be aware that some cheap servo start to jerk around 0° and around 180°. So a common practise is to reduce the servo angles to the range [10° to 170°] or more precise depending on the gears.

Thank you for the quick reply.


How would you advice me to do this? Not that I want to be leeching, but I have been looking to solve this problem for hours now.. I dont know what else to try (:

My servo doesn't jerk at 0 or 180 degrees, though I would like to adjust the servo range. could I just do it like this: map(val, 0, 1023, 10, 170)?

More common than using a map is a low-pass-filter. Using this filter the jitter of the potentiometer signal is flattened / corrected. You could also try this solution.

How? Well, you could use a moving average. A simple solution to this is to always take i.e. the last four potentiometer values, sum them up and divide them by four (see image below). Use this calculated nominal value as the actual value for the servo.

One last hint: If you scale a value from 0 to 180 you get 181 steps. So your code tells the servo to go to angle 181°. Be aware that you start from 0 - not 1. Therefore scale the value from 0 to 179... or from 10 to 169.

You could do this: If(int1<=int2+3 || int1>=int2-3){ //move servo here # Just off of the too of my head. Not sure If || is valid for Arduino but that would work in say c# Hope that helps.
Oops that should be && not || Sorry. I'll edit it and fix that. :L

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);

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++;