Gesture Controlled Robotic Arm

Gesture Controlled Robotic Arm © GPL3+

Robotic arm mimics human arm movement with MEMS and e-compass based and transmitted thru Bluetooth.

  • 2,992 views
  • 0 comments
  • 2 respects

Components and supplies

Necessary tools and machines

Apps and online services

About this project

Overview

That is my first project on robotics. The idea came from an ST sensortile development tool. This IoT gadget can do a lot but the feature that interests me is reporting its dynamic 3D angles: yaw, pitch and roll. I am trying to use this to control the arm. See the link for the detail.

Step 1

First, the 3D printing file is downloaded from Thingiverse.

In fact, I reduced one DOF simply due to my designed controlled by MEMS sensor. Then some low cost servo motor made in China is all you need from the web. The MG90s I got from the web are very cheap and of good quality.

It is so easy to use the Arduino Nano board and servo library to drive the arm for a simple pick-up movement. It only took me an hour to code the movement for a UART input interface to take commands from serial port which is for the later Bluetooth module to communicate.

Pick and place

Step 2

That was simple. Motion for this is just an array of positions which are the angles of all the servos in the moment. Arduino servo and Serial library are neat and easily implemented. Now the UI is typing commands to the serial monitor in Arduino IDE.

Next step is to add a Sensor User Interface. To get your robot arm to learn from your motion, you have to learn how to do it first. After some calibrations and practice, the result:

The tricky move/motions

The small plastic box (a watch?) is ST SensorTile. It transmits the current yaw, pitch to my BT LE module which in turn sending commands to Arduino Nano to control servos.

Step 3

That means the Bluetooth module needs to be in Client Mode (like your cell phone). SensorTile is in Server mode (your wearable). I am using ST Bluenrg-1 based module which can be Client and Server or both. So my next step is to write an Android app to connect to BT LE Module to incorporate more axis of motion into the arm. Right now the robot arm has 4 servo, in which 3 are shoulder, arm and forearm, and 1 is the gripper. SensorTile can output 3-axis data but while I am holding it in the hand, only 2-axis of data is useful and my robot arm does not have a wrist servo.

Code

s_control.inoC/C++
Takes command in serial port to control servo to move to specified angle position
e.g. fxa45 moves A servo to 45 degree
fxp1 all servo to 45 degree
fxp2 a pick and place demostration
//#define DEBUG_MOVE_STEP
class FRobot {
  public:
    FRobot() {
      
      delay_time = 20;
    }
    void home() {}
    
    int read(int i) {
      return servo[i].read();
    }
    void set_delay(int t) {
      delay_time = t;
    }
    int move_step(int which, int target) {
      int pos;
      pos = servo[which].read();
      #ifdef DEBUG_MOVE_STEP
      Serial.print(which, DEC); Serial.print(" Target"); Serial.print(target,DEC);
      Serial.print("cur pos"); Serial.println(pos,DEC);
      #endif
      if (pos < target)
        servo[which].write(pos + 1);
      else if (pos > target)
        servo[which].write(pos - 1);
      else if (pos == target)
        return 1;
      return 0;
    }
    void motion(unsigned char m[][4], int steps)
    {
      int i, j, ret = 0;;
      for (i = 0; i < steps; i++) {
        Serial.print("motion: ");
        Serial.println(i, DEC);
        do {
          ret = 0;
          for (j = 0; j < 4; j++)  ret += move_step(j, m[i][j]);
          delay(delay_time);
        } while (ret < 4);
      }
      Serial.println("motion end");
    }
    void Execute(int val[])
    {
      int j, ret;
      do {
        ret = 0;
        for (j = 0; j < 4; j++)  ret += move_step(j, val[j]);
        delay(delay_time);
      } while (ret < 4);
      Serial.print("move to "); Serial.print(val[0]); Serial.print(val[1]); Serial.print(val[2]); Serial.println(val[3]);
    }

  public:
    Servo *servo;
    int delay_time;
};

class FRobot_Arm : public FRobot {
  public:
    FRobot_Arm(): FRobot() {
      servo = s;
      
    }
    void attach(int p1, int p2, int p3, int p4){
      servo[0].attach(p1);
      servo[1].attach(p2);
      servo[2].attach(p3);
      servo[3].attach(p4);
    }
    void home(int a, int b, int c, int d) {
      servo[0].write(a);
      servo[1].write(b);
      servo[2].write(c);
      servo[3].write(d);
    }
  private:
    Servo s[4];

};
Arduino nano robot arm servo controlC/C++
It takes commands from serial port and execute servo movement to the angle specified
#include <Servo.h>
#include "FRobot.h"

//UART send 1~9==>20~180 degree

int val, val2, temp;
void Execute(char c, int v1);
void Execute(int v[]);
void motion(unsigned char m[][4], int steps);

unsigned char home_pos[1][4] = { 45, 45, 45, 45 };
unsigned char hello_dance[6][4] = { {45, 0, 0, 80}, {30, 0, 0, 80},
  {90, 10, 10, 10}, {30, 10, 10, 80},
  {30, 45, 90, 80}, {45, 45, 45, 45}
};
unsigned char pickup_dance[][4] = { {110, 95, 140, 80}, {110, 95, 140, 80}, {110, 95, 140, 30},
  {110, 70, 90, 30}, {180, 70, 90, 30},
  {180, 95, 90, 30}, {180, 95, 150, 30},
  {180, 100, 150, 80}, {180, 70, 90, 80}, {45, 45, 45, 45}
};
FRobot_Arm arm;
void setup()
{
  int i;
  pinMode(13, OUTPUT);
  Serial.begin(9600);//设置波特率为9600
  Serial.println("servo=o_seral_simple ready" ) ;
  arm.attach(10, 9, 8, 7);
  arm.home(45, 45, 45, 45);
  Serial.println("home");
}
int input_cnt = 0;
char command;
const int Servo_Limit[4][2] = { { 0, 180}, {45, 150}, {0, 180}, {10, 80}};
void loop()
{
  int val[4], i;
  char c;
  
  if (!Serial.available())
    return;
 // Serial.print("input cnt "); Serial.println(input_cnt, DEC);
  if (input_cnt > 2) {
    input_cnt = 0;
    val[0] = Serial.parseInt();
    constrain(val[0], Servo_Limit[0][0], Servo_Limit[0][1]);
    if (command == 'x') {
      for (i = 1; i < 4; i++)  {
        val[i] = Serial.parseInt();
        constrain(val[i], Servo_Limit[i][0], Servo_Limit[i][1]);
      }
      arm.Execute(val);
    } else
      Execute(command, val[0]);
    return;
  }
  c = Serial.read();
  input_cnt ++;
  switch (input_cnt) {
    case 1:
      if (c != 'f')  input_cnt = 0;
      break;
    case 2:
      if (c != 'x') input_cnt = 0;
      break;
    case 3:
      command = c;
  //    Serial.print("command = ");
   //   Serial.println(command, DEC);
      break;
  }
}
void Execute(char c, int v1)
{
  char buf[64];
  switch (c) {
    case 'S': case 's':
      sprintf(buf, "A: %d B: %d C: %d D: %d, ",
              arm.read(0), arm.read(1), arm.read(2), arm.read(3));
      Serial.println(buf);
      break;
    case 'b': case 'c': case 'd': case'a':
      sprintf(buf, "move %c to %d", c, v1);
      Serial.println(buf);
      while (!arm.move_step(c - 97, v1));            break; //a ASCII = 97

    case 'T':
    case 't':
      arm.set_delay(v1);
      break;
    case 'p':
      if (v1 == 1) {
        arm.motion(home_pos, 1);
      } else if (v1 == 2) {
        arm.motion(pickup_dance, 10);
      } else if (v1 == 3) arm.motion(hello_dance, 6);
      break;
    case 'L':
      if (v1 > 0)
        digitalWrite(13, HIGH);
      else
        digitalWrite(13, LOW);
      break;
  }

 // Serial.print(c, DEC);
 // Serial.print("  v1="); Serial.println(v1, DEC);
}


//#define DEBUG_MOVE_STEP
class FRobot {
  public:
    FRobot() {
      
      delay_time = 20;
    }
    void home() {}
    
    int read(int i) {
      return servo[i].read();
    }
    void set_delay(int t) {
      delay_time = t;
    }
    int move_step(int which, int target) {
      int pos;
      pos = servo[which].read();
      #ifdef DEBUG_MOVE_STEP
      Serial.print(which, DEC); Serial.print(" Target"); Serial.print(target,DEC);
      Serial.print("cur pos"); Serial.println(pos,DEC);
      #endif
      if (pos < target)
        servo[which].write(pos + 1);
      else if (pos > target)
        servo[which].write(pos - 1);
      else if (pos == target)
        return 1;
      return 0;
    }
    void motion(unsigned char m[][4], int steps)
    {
      int i, j, ret = 0;;
      for (i = 0; i < steps; i++) {
        Serial.print("motion: ");
        Serial.println(i, DEC);
        do {
          ret = 0;
          for (j = 0; j < 4; j++)  ret += move_step(j, m[i][j]);
          delay(delay_time);
        } while (ret < 4);
      }
      Serial.println("motion end");
    }
    void Execute(int val[])
    {
      int j, ret;
      do {
        ret = 0;
        for (j = 0; j < 4; j++)  ret += move_step(j, val[j]);
        delay(delay_time);
      } while (ret < 4);
      Serial.print("move to "); Serial.print(val[0]); Serial.print(val[1]); Serial.print(val[2]); Serial.println(val[3]);
    }

  public:
    Servo *servo;
    int delay_time;
};

class FRobot_Arm : public FRobot {
  public:
    FRobot_Arm(): FRobot() {
      servo = s;
      
    }
    void attach(int p1, int p2, int p3, int p4){
      servo[0].attach(p1);
      servo[1].attach(p2);
      servo[2].attach(p3);
      servo[3].attach(p4);
    }
    void home(int a, int b, int c, int d) {
      servo[0].write(a);
      servo[1].write(b);
      servo[2].write(c);
      servo[3].write(d);
    }
  private:
    Servo s[4];

};

Comments

Author

Teddy99
Teddy99
  • 1 project
  • 0 followers

Additional contributors

  • Sensor fusion sample program running on sensortile tools by ST Sensortile

Published on

August 31, 2017

Members who respect this project

16996498 1423413207709969 2623568762044732287 n

and 1 other

See similar projects
you might like

Similar projects you might like

Gesture Controlled Robotic Arm Using Kinect & Arduino

Project showcase by Avinash Baranitharan and Karthikeyan

  • 8,328 views
  • 0 comments
  • 27 respects

Robotic Arm Controlled by Human Arm

Project showcase by zezarandrade

  • 3,691 views
  • 0 comments
  • 5 respects

Gesture Controlled Trainable Arduino Robot Arm via Bluetooth

Project tutorial by KureBas Robotics

  • 11,632 views
  • 41 comments
  • 99 respects

Android Controlled 6DoF Robotic Arm

Project in progress by Team Mans

  • 11,065 views
  • 0 comments
  • 17 respects

PC Controlled Robotic Arm

Project tutorial by AhmedAzouz

  • 8,454 views
  • 12 comments
  • 67 respects

Nunchuk Controlled Robotic Arm (with Arduino)

Project tutorial by Igor Fonseca Albuquerque

  • 5,134 views
  • 5 comments
  • 40 respects
Add projectSign up / Login