Introduction: Robot Arm From a Desk Lamp (IKEA Tertial Hack)

This project answers to a need I had: a third hand that holds a camera while I perform a test and takes photos/videos (useful when you're stuck at the lab late at night, and suddenly need a photographer).
The downside to a robotic arm was obvious - It needs to be programmed, and it is the last thing you want to do when you need to make a video. So I made it motion capturing device as well...

Motion capturing and playing device - you "teach" the arm what it should do, and it repeats the movement! (no programming or computer needed).



For long time I wanted to transform standard IKEA Tertial lamp (here) into a functional robotic hand, I wanted to make it easy, without any manufactured parts, and to control as many degrees of freedom (DOF) as possible.
After modeling the lamp using my favorite CAD software, I realized the standard servos, placed in the right places can (to some extent) work.


Step 1: Stripping and Modeling IKEA Tertial Lamp

First step is, of course, to get a Tertial lamp, should be quite easy to get here, and remove the power cord (must be cut), dismantle the lampshade (But leave it's connector !) and remove the springs for future use.


3D Parasolid (.x_t): Download

Step 2: Hacking Servos for Analog Feedback

In purpose to get feedback from the servos, they should be capable to give feedback (analog), ready made analog servos can be found at Adafruit, or can be manually made as described here:
( I used cheap MG995 ), after some ruined servos I managed to figure the right steps:
  1. Pick the servo...
  2. USE TAPE (see image) to hold the top (the side near the power output) otherwise the transmission might fall apart
  3. Remove 4 cross bolts from the bottom.
  4. Take the PCB out gently, and position in your soldering stand
  5. Solder wire to the middle connection of the servo's potentiometer
  6. Assemble all back to have an "Analog feedback" servo.
repeat 3 times for all servos needed for the project.

Step 3: Camera Adapter

Connection of the camera to the arm should be easy release and enable full rotation,

Camera to servo steps:
  1. Pick one servo.
  2. Pick some nuts and arms (that come with the servo)
  3. Get a nut to mount the camera (any 3/8" nut will do).
  4. Build an arm that fit your camera,
  5. You're done !
Now, you need to connect the servo to the arm tip:
  1. Pick the arm tip part
  2. Bend the little metal plate to straight line.
  3. Take any small block/profile and mount to the metal plate.
  4. Mount the servo to the same block/profile
  5. You're done !

Step 4: Connecting Motors to the Arm

The arm should be actuated with two servos (the third is used for the camera - see previous step)

Servo 2 (arm end) mounting steps:
  1. Dismantle the triangular plate from the arm tip.
  2. Drill few holes to enable mounting of the servo arm to the plate.
  3. Mount the servo arm to the plate
  4. Assemble the plate back to the arm
  5. REPLACE THE UPPER BOLT, with a bolt the goes directly into the servo center of rotation. (see images)
  6. Tighten the servo body to the bar (I used spacers and zip ties - improvise!
Servo 3 (middle) mounting steps:
  1. Dismantle the trapeze plate from the arm.
  2. Drill few holes to enable mounting of the servo arm to the plate.
  3. Mount the servo arm to the plate
  4. Assemble the plate back to the arm
  5. REPLACE THE UPPER BOLT, with a bolt the goes directly into the servo center of rotation. (see images)
  6. Tighten the servo body to the bar (I used spacers and zip ties - improvise!

Step 5: Wiring and Power Sourcing

Wiring:

Note - since the servos require high current - I used a 7.4V power supply (batteries also will do), otherwise there will be all kind of faults.

SERVOS:
Each servo is connected with 4 wires -
  • Black - ground (Ensure to connect the Arduino ground to the power supply ground)
  • Red - POWER SUPPLY (I used a lab power supply 7.4V - to gain max torque form the motors)
  • Yellow - To the PWM output pin of the Arduino
  • White (my addition) -  to analog input pin of the Arduino
* The three servos are connected to PWM 9,10,11 and analog input A0,A1,A2

Buttons:
There are 2 buttons, connected to pins 7,12 (ground in)

Arduino:
I used Arduino Uno

Fritzing file: Download




Step 6: Software (Arduino Sketch)

The Arduino sketch

The Arduino code has two functions:
  1. Record the analog inputs from the servos potentiometers       (RECORD button)
  2. Operate the servos with the recorded values                               (PLAY         button)
Notes:
  • The recorded values are stored in the EEPROM memory of the Arduino - limits the recording (adding SD card will solve it).
  • The sketch prompts the recorded values and the played values, in real time, to the SERIAL MONITOR, but this is not needed to the working of the sketch.
  • Good tutorial for analog feedback servo can be found here
The Arduino sketch:
Download Arduino sketch

// (http://www.KeerBot.com)
// Example code for recording and playing back servo motion with an analog feedback servo
// 5 Dec2013, using manually hacked servos

#include <Servo.h>
#include <EEPROM.h>

#define CALIB_MAX 512
#define CALIB_MIN 100
#define SAMPLE_DELAY 25 // in ms, 50ms seems good

uint8_t recordButtonPin = 12;
uint8_t playButtonPin = 7;
uint8_t one = 9, two= 10, three=11;
uint8_t OneIn = A0, TwoIn=A1, ThreeIn=A2;
uint8_t ledPin = 13;

Servo myServo1,myServo2,myServo3;

void setup() {
  Serial.begin(9600);
  pinMode(recordButtonPin, INPUT);
  digitalWrite(recordButtonPin, HIGH);
  pinMode(playButtonPin, INPUT);
  digitalWrite(playButtonPin, HIGH);
  pinMode(ledPin, OUTPUT);
  uint16_t addr = 0;
  Serial.println("Servo RecordPlay, 3 Servos version");
  Serial.println("By http://www.KeerBot.com");
}

void loop() {
if (! digitalRead(recordButtonPin)) {
    delay(10);
   // wait for released
    while (! digitalRead(recordButtonPin));
    delay(20);
   // OK released!
    Serial.println("Recording");
    uint16_t addr = 0;
    digitalWrite(ledPin, HIGH);
    pinMode(OneIn, INPUT);
    pinMode(TwoIn, INPUT);
    pinMode(ThreeIn, INPUT);
    while (digitalRead(recordButtonPin)) {

        uint16_t a = analogRead(OneIn);
        uint16_t b = analogRead(TwoIn);
        uint16_t c = analogRead(ThreeIn);

        Serial.print("Read analog: "); Serial.print(a);Serial.print(" , ");Serial.print(b);Serial.print(" , ");Serial.print(c);Serial.print(" , ");
        // one
        if (a < CALIB_MIN) a = CALIB_MIN;
        if (a > CALIB_MAX) a = CALIB_MAX;
        a = map(a, CALIB_MIN, CALIB_MAX, 0, 255);
        // two
        if (b < CALIB_MIN) b = CALIB_MIN;
        if (b > CALIB_MAX) b = CALIB_MAX;
        b = map(b, CALIB_MIN, CALIB_MAX, 0, 255);
        //three
        if (c < CALIB_MIN) c = CALIB_MIN;
        if (c > CALIB_MAX) c = CALIB_MAX;
        c = map(c, CALIB_MIN, CALIB_MAX, 0, 255);

        Serial.print(" -> "); Serial.print(a);Serial.print(" , ");Serial.print(b);Serial.print(" , ");Serial.println(c);
        EEPROM.write(addr, a);
        addr++;
        EEPROM.write(addr, b);
        addr++;
        EEPROM.write(addr, c);
        addr++;
        if (addr == 512) break;
        delay(SAMPLE_DELAY);
    }
    if (addr != 512) EEPROM.write(addr, 255);
    digitalWrite(ledPin, LOW);
    Serial.println("Done");
    delay(250);
}

  if (! digitalRead(playButtonPin)) {
   delay(10);
   // wait for released
   while (! digitalRead(playButtonPin));
   delay(20);
   // OK released!
    Serial.println("Playing");
    uint16_t addr = 0;
    myServo1.attach(one);
    myServo2.attach(two);
    myServo3.attach(three);

    while (digitalRead(playButtonPin)) {
        // One
        uint8_t x = EEPROM.read(addr);
        Serial.print("Read EE: "); Serial.print(x);
        if (x == 255) break;
        x = map(x, 0, 254, 0, 180);
        Serial.print(", "); Serial.print(x);Serial.print(", ");
        myServo1.write(x);
        addr++;
        // Two
        x = EEPROM.read(addr);
        Serial.print(x);Serial.print(", ");
        if (x == 255) break;
        x = map(x, 0, 254, 0, 180);
        Serial.print(" -> "); Serial.print(x);Serial.print(", ");
        myServo2.write(x);
        addr++;
        //Three
        x = EEPROM.read(addr);
        Serial.print(x);
        if (x == 255) break;
        x = map(x, 0, 254, 0, 180);
        Serial.print(", "); Serial.print(x);Serial.println(", ");
        myServo3.write(x);
        delay(SAMPLE_DELAY);
        addr++;

        if (addr == 512) break;
        }
    Serial.println("-");
    Serial.println("Done reading EE");
    myServo1.detach();
    myServo2.detach();
    myServo3.detach();
    delay(250);
}
}






Step 7: Future Developments & Thanks.

Koby C. and HUJI- Power supply
www.Adafruit.com -For the Analog feedback servo Arduino sketch - here
Yaglush - for everything

Build My Lab Contest

Participated in the
Build My Lab Contest

Hardware Hacking

Participated in the
Hardware Hacking