At the Hackaday Prize 2014 they held workshops in robotics too and one of the projects was the MeArm. I was given on of this robot arms to use them in the CoderDojo in Munich later this year.

Here is a short introduction of what I want to teach the kids soon.

MyArm.IO from the Hackaday 2104 Munich

MyArm.IO from the Hackaday 2104 Munich


/*
RobotArm, a test of all four Servos
Copyright 2014 -mat- filid brandy, brandy@klammeraffe.org

modified 16 Nov 2014
*/

#include

// Define the four Servos with their minimum and maximum degrees range to avoid breaking the robotarm
Servo grip;
float minGrip = 60.0;
float maxGrip = 100.0;
int GRIP = 0;

Servo forearm;
float minForearm = 105.0;
float maxForearm = 175.0;
int FOREARM = 1;

Servo turn;
float minTurn = 0.0;
float maxTurn = 180.0;
int TURN = 2;

Servo bicep;
float minBicep = 40.0;
float maxBicep = 175.0;
int BICEP = 3;

// temp variables
float pos = 0.0;

// we move in a 0.0 to 180.0 degree range
float minDegree = 0.0;
float maxDegree = 180.0;

// Setup the hardware
void setup()
{
Serial.begin(9600);
turn.attach(6); // PIN PWM 6
bicep.attach(9); // PIN PWM 9
forearm.attach(10); // PIN PWM 10
grip.attach(5); // PIN PWM 5
}

// This translates our working degree space (0-180) aka left to
// the range the given servo aka right (eg. biceps from 40-175)
// make sure, we do not have values outside the working degree space too
float translate( float value, float leftMin, float leftMax, float rightMin, float rightMax) {
value = ( value < leftMin ) ? leftMin : value;
value = ( value > leftMax ) ? leftMax : value;
float leftSpan = leftMax - leftMin; // eg. 180
float rightSpan = rightMax - rightMin; // eg. 135
float valueScaled = (value - leftMin) / leftSpan; // (value - 0 ) / 180
return rightMin + (valueScaled * rightSpan); // return = 40 + ( valueScaled * 135 )
}

// move a given servo (thisServo) to the given position (pos)
void moveServo(int thisServo, float pos) {
float translated;
switch (thisServo) {
case 2: // TURN
translated = translate(pos,minDegree,maxDegree,minTurn,maxTurn);
if (turn.read() != translated) {
turn.write(translated);
}
break;
case 3: // BICEP
translated = translate(pos,minDegree,maxDegree,minBicep,maxBicep);
if (bicep.read() != translated) {
bicep.write(translated);
}
break;
case 1: // FOREARM
translated = translate(pos,minDegree,maxDegree,minForearm,maxForearm);
if (forearm.read() != translated) {
forearm.write(translated);
}
break;
case 0: // GRIP
translated = translate(pos,minDegree,maxDegree,minGrip,maxGrip);
if (grip.read() != translated) {
grip.write(translated);
}
break;
default: // Default do nothing
break;
}
}

// Shorthand to open the Grip
void openGripper() {
moveServo(GRIP,0.0);
delay(50);
}

// Shorthand to close the Grip
void closeGripper() {
moveServo(GRIP,180.0);
delay(50);
}

// Small gripper animation
void showGripper() {
for (float i=90.0; i<180.0; i+=1.0) {
moveServo(FOREARM,i);
delay(1);
}
delay(300);
for (int i=0; i<5; i++) {
openGripper();
delay(150);
closeGripper();
delay(150);
}
for (float i=180.0; i>90.0; i-=1.0) {
moveServo(FOREARM,i);
delay(1);
}
closeGripper();

delay(300);
}

// Animate the servos
void loop()
{
for(pos = minDegree; pos < = maxDegree; pos+=1) {
moveServo(TURN,pos/2.0+(maxDegree/4.0));
moveServo(BICEP,pos);
moveServo(FOREARM,pos);
delay(5);
if (0 == (int)pos % 30 ) closeGripper();
if (15 == (int)pos % 30 ) openGripper();
if ( (maxDegree/2.0) == pos ) {
showGripper();
delay(50);
closeGripper();
}
}
openGripper();
delay(2000);
closeGripper();
for(pos = maxDegree; pos>=minDegree; pos-=1) {
moveServo(TURN,pos/2.0+(maxDegree/4.0));
moveServo(BICEP,pos);
moveServo(FOREARM,pos);
delay(5);
}
openGripper();
delay(2000);
closeGripper();
}