Saturday 29 July 2017

The meArm built and working

So I have finalised the build of a meArm robot arm, and I'm quite impressed by it. Here it is about the pick up an object:

IMG 1396
I publish below three pieces of Arduino software I have written to get it going. I tried the so-called "meArm" IK stuff I found on GitHub, but was disappointed in it and found it unusable to get it going, maybe through complete lack of documentation. It claimed to create a cartesian or cylindrical space for giving commands to the meArm in order to make programming easier. But I found this to not help at all.

So I have remained with a concept of determining the minimum and maximum movements of the arm rotation, shoulder and elbow servos and equating them to 0-100% of a possible movement. Now it is possible to write 'movement" sketches describing the required movement in numbers from zero to one hundred.

To do this I first wrote a library of functions listed below,

README

README meArm.h

1 arm positions expressed as 0-100% of travel
  arm 0 = left, 50 = centre, 100 = right
  left 0 = up, 100 = down
  right 0 = in, 100 = out
  grip 0 = open, 100 = closed
  
2 servos attached on PWM pins

  arm(11), left(10), right(9), grip(6)

  and set to start positions
    arm = centre
    left = up
    right = in
    grip = open

2 functions

void armBegin(); // attach servoe & start positions
// move  to pos (0-100%) in ms/step
void armPos(pos, ms);   // arm
void leftPos(pos, ms);  // left
void rightPos(pos, ms); // roght
void gripPos(pos, ms);  // grip
void goPos(a, r, l, g, s); // s = ms/step


LIBRARY meArm.h
// meArm.h
// v 1.0 24-7-17

#include "Servo.h"

Servo arm, left, right, grip;


// arm deg max = max, home = mid point, left = min
#define ARM 11
#define ARMMAX 180
#define ARMHOME 98
#define ARMMIN 0

// right deg min = in, max = out
#define RIGHT 10
#define RIGHTMIN 50
#define RIGHTHOME 90
#define RIGHTMAX 145

// left deg min = in, max = out
#define LEFT 9
#define LEFTMIN 45
#define LEFTHOME 90
#define LEFTMAX 150

// grip close = in, open = out
#define GRIP 6
#define GRIPIN 70
#define GRIPOUT 0


// ============= BEGIN =============
void armBegin() {
  arm.attach(ARM);
  right.attach(RIGHT);
  left.attach(LEFT);
  grip.attach(GRIP);

  // start positions
  arm.write(ARMHOME);
  right.write(RIGHTHOME);
  left.write(LEFTHOME);
  grip.write(GRIPOUT);
}


// ============= ARM MOVEMENTS =============
// ARM steadily move arm to pos 0-100 in ms steps
void armPos(int pos, int ms) {
  int m, r;

  pos = map(pos, 0, 100, ARMMIN, ARMMAX);
  r = arm.read();
  if (pos > r) {
    for (m = r; m != pos; m += 1) {
      arm.write(m);
      delay(ms);
    }
    return;
  }
  else if (pos < r) {
    for (m = r; m != pos; m -= 1) {
      arm.write(m);
      delay(ms);
    }
  }
  return;
}

// LEFT steadily move left to pos in ms steps
void leftPos(int pos, int ms) {
  int m, r;

  pos = map(pos, 0, 100, LEFTMIN, LEFTMAX);
  r = left.read();
  if (pos > r) {
    for (m = r; m != pos; m += 1) {
      left.write(m);
      delay(ms);
    }
    return;
  }
  else if (pos < r) {
    for (m = r; m != pos; m -= 1) {
      left.write(m);
      delay(ms);
    }
  }
  return;
}


// RIGHT steadily move left to pos in ms steps
void rightPos(int pos, int ms) {
  int m, r;

  pos = map(pos, 0, 100, RIGHTMIN, RIGHTMAX);
  r = right.read();
  if (pos > r) {
    for (m = r; m != pos; m += 1) {
      right.write(m);
      delay(ms);
    }
    return;
  }
  else if (pos < r) {
    for (m = r; m != pos; m -= 1) {
      right.write(m);
      delay(ms);
    }
  }
  return;
}

// GRIP move open/close in ms steps
void gripPos(int pos, int ms) {
  int m, r;

  pos = map(pos, 0, 100, GRIPOUT, GRIPIN);
  r = grip.read();
  if (pos > r) {
    for (m = r; m != pos; m += 1) {
      grip.write(m);
      delay(ms);
    }
    return;
  }
  else if (pos < r) {
    for (m = r; m != pos; m -= 1) {
      grip.write(m);
      delay(ms);
    }
  }
  return;
}

// ========== GO to POS =======
// go to a position a, r, l, g, ms
void goPos(int a, int r, int l, int g, int s) {
  armPos(a, s);  // position arm, right andleft
  leftPos(l, s);
  rightPos(r, s);
  gripPos(g, s);
}


Note the hidden drawback of this library, the goPos() function always carries out movement in the order arm, left, right, grip servos, which maybe not what you want...

Next I wrote a couple of sketches, the first to allow you to manually set the arm position by three linear potentiometers connected to the Arduino Uno for ARM, SHOULDER and ELBOW servos.

IMG 1397

This allows you to plan, move and record the steps needed for a specific set of movements which are displayed on the Serial Monotor. Here is the sketch,

DEFINE
// Define
// v0.5 20-7-17
// see also library mearm.h
// servo pins
// arm   11
// right 10
// left  9
// grip  6
// movement %0 = in/Left, 100% = out/Right

#include "meArm.h"

void setup() {
  Serial.begin(9600);
  
  armBegin();     // attaches servos, sets start positions, HOME, IN, IN, OPEN
  delay(2000);
}

void loop() {
  int a, r, l, g;

  a = map(analogRead(A0), 0, 1023, 0, 100);
  r = map(analogRead(A1), 0, 1023, 0, 100);
  l = map(analogRead(A2), 0, 1023, 0, 100);

  Serial.print("Arm\t");
  Serial.print(a);
  Serial.print("\tRight\t");
  Serial.print(r);
  Serial.print("\tLeft\t");
  Serial.println(l);

  // random positions - test, grip open
  goPos(a, r, l, 0, 10);


  delay(50);

}


This Define sketch is used to move the arm to any place you want then, movement by movement, write down the Arm, Shoulder, and Elbow "%" values 0-100, and add the grip 0 (open) or 100% (close) command and the speed of each movement in small steps in milliseconds which controls the speed, finally to program a sequence of moves. Remember that the meARm.h library executes the goPos(a, r, l, g, ms) commands in the order ARM-LEFT-RIGHT-GRIP when you are planning and recording moves.

So Finally here is a demo sketch using the functions from the library to make a simple move of picking up an object, swinging across and putting it down, then reversing the move,

MOVE

// move
// v0.5 20-7-17
// see also library mearm.h
// servo pins
// arm   11
// right 10
// left  9
// grip  6
// movement %0 = in/L/open, 100% = out/R/close

#include "meArm.h"

#define SPEED 20

void setup() {
  Serial.begin(9600);

  armBegin();     // attaches servos, sets start positions, HOME, IN, IN, OPEN
  delay(2000);
}

void loop() {

  // routine positions a, r, l, g, ms

  goPos(28, 79, 30, 100, SPEED); // pick up
  goPos(28, 40, 30, 100, SPEED); //  rotate
  goPos(85, 79, 30, 0, SPEED);  // out & drop

  goPos(85, 40, 30, 0, SPEED);   // out
  goPos(50, 40, 30, 0, SPEED);   // home

  delay(2000);                // pause

  goPos(85, 79, 30, 0, SPEED);  // out
  goPos(85, 79, 30, 100, SPEED);  // pickup
  goPos(85, 40, 30, 100, SPEED); // up
  goPos(28, 40, 30, 100, SPEED); //  rotate
  goPos(28, 79, 30, 0, SPEED); // drop

  goPos(28, 40, 30, 0, SPEED);
  goPos(50, 40, 30, 0, SPEED);   // home


  delay(2000);



}

Thursday 20 July 2017

PLAYING with the kids

Away, sort of, from radio things I have indulged myself with a robot arm kit, the meArm. But there is a tiny nagging thought at the back of my mind - that is to control a set of these arms by radio, maybe using the ubiquitous 433MHz RX TX modules, and make them dance in harmony, fun eh?

IMG 1374

The meArm sitting on my desk

So far I have done a little bit of Arduino programming to try it out, and written a library file to keep some of the functions in.

CODE "meArm.h"

// mearm.h
// v 0.5 20-7-17

#include "Servo.h"

Servo arm, left, right, grip;


// arm deg max = max, home = mid point, left = min
#define ARMMAX 180
#define ARMHOME 98
#define ARMMIN 0

// right deg min = in, max = out
#define RIGHTMIN 90
#define RIGHTMAX 180

// left deg min = in, max = out
#define LEFTMIN 50
#define LEFTMAX 140

// grip close = in, open = out
#define GRIPIN 65
#define GRIPOUT 10


// ============= BEGIN =============
void armBegin() {
  arm.attach(11);
  right.attach(10);
  left.attach(9);
  grip.attach(6);

  // start positions
  arm.write(ARMHOME);
  right.write(RIGHTMIN);
  left.write(LEFTMIN);
  grip.write(GRIPOUT);
}


// ============= ARM MOVEMENTS =============
// ARM steady move arm to pos 0-100 in ms steps
void armpos(int pos, int ms) {
  int m, r;

  pos = map(pos, 0, 100, ARMMIN, ARMMAX);
  r = arm.read();
  if (pos > r) {
    for (m = r; m != pos; m += 1) {
      arm.write(m);
      delay(ms);
    }
    return;
  }
  else if (pos < r) {
    for (m = r; m != pos; m -= 1) {
      arm.write(m);
      delay(ms);
    }
  }
  return;
}

// LEFT steady move left to pos in ms steps
void leftpos(int pos, int ms) {
  int m, r;

  pos = map(pos, 0, 100, LEFTMIN, LEFTMAX);
  r = arm.read();
  if (pos > r) {
    for (m = r; m != pos; m += 1) {
      left.write(m);
      delay(ms);
    }
    return;
  }
  else if (pos < r) {
    for (m = r; m != pos; m -= 1) {
      left.write(m);
      delay(ms);
    }
  }
  return;
}


// RIGHT steady move left to pos in ms steps
void rightpos(int pos, int ms) {
  int m, r;

  pos = map(pos, 0, 100, RIGHTMIN, RIGHTMAX);
  r = arm.read();
  if (pos > r) {
    for (m = r; m != pos; m += 1) {
      right.write(m);
      delay(ms);
    }
    return;
  }
  else if (pos < r) {
    for (m = r; m != pos; m -= 1) {
      right.write(m);
      delay(ms);
    }
  }
  return;
}

// GRIP move open close in ms steps
void grippos(int pos, int ms) {
  int m, r;

  pos = map(pos, 0, 100, GRIPOUT, GRIPIN);
  r = arm.read();
  if (pos > r) {
    for (m = r; m != pos; m += 1) {
      grip.write(m);
      delay(ms);
    }
    return;
  }
  else if (pos < r) {
    for (m = r; m != pos; m -= 1) {
      grip.write(m);
      delay(ms);
    }
  }
  return;
}

CODE FOR TESTING SERVOS

// move
// v0.5 20-7-17
// viewed from behind, range
// arm mid xx/98/xx
// right 80/xx/140
// left xx/xx/xx

#include "meArm.h"

void setup() {
  armBegin();     // attach servos, goto start positions
  delay(2000);
}

void loop() {
  armpos(80, 50); // move to 80%, 50ms steps%
  delay(5000);
  armpos(20, 50); // move to 60% in 100 ms steps
  delay(5000);

}

Tuesday 4 July 2017

LATEST Sketches and Libraries

4 July 2017. Here's the latest update, downloadable zip file M0IFA SKetches

Screen Shot 2017 07 04 at 09 45 47

Sketches

Screen Shot 2017 07 04 at 09 47 37

Libraries used

Watch out for updates on this blog.