Table of Contents

Robotic hand

Un model de mana robotica controlata cu o manusa, de la distanta.

Descriere generală

O mana robotica ce poate fi utilizata ca o mana obisnuita, avand control asupra fiecarui deget. Acestea sunt controlate de cate un servomotor si cate un rezistor de tip flex.

Controlul fiecarui deget este realizat prin intermediul citirii unei valori prin fiecare pin (A0, A1, …, A4), reprezentand gradul de indoire a rezistentei. Mai departe, prin pinii digitali de la 2 la 6 sunt controlate servomotarele pentru a misca degetele.

Hardware Design

Piese folosite:

Am folosit potentiometrele drept reprezentare pentru rezistentele de tip flex.

Pentru a facilita utilizarea mainii, am folosit doua module bluetooth HC05 intr-o configuratie Master-Slave. Astfel, modulul Slave trasmite la Master valorile citite de la pinii analogici, iar modulul Master decide daca e cazul sau nu sa activeze un servotor.

Pentru a folosi aceasta configuratie, conectam fiecare modul bluetooth la cate o placuta Arduino UNO, astfel:

  • VCC - 3.3V
  • GND - GND
  • TXD - 10
  • RXD - 11

Mai departe, conectam servomotoarele la pinii 2, 3, 4, 5, 6 de la modulul Master, iar rezistentele la pinii A0, A1, A2, A3, A4 de la modulul Slave.

Software Design

Pentru dezvoltarea software am folosit Arduino IDE, iar ca biblioteci, <Servo.h> si <SoftwareSerial.h>.

Din motive prezentate in sectiunea de mai jos, cea mai buna solutie pentru comandarea servomotoarelor a fost urmatoarea: calculez, pentru fiecare rezistenta, o valoare minima pentru care pot sa fiu sigur ca degetul este indoit. Astfel, pentru toate citirile mai mari decat aceasta, activez servomotorul pentru degetul respectiv.

Singurul dezavantaj la aceasta metoda este faptul ca suntem constransi la indoirea totala a degetelor.

Pentru Master:

#include <SoftwareSerial.h>
#include <Servo.h>
#include <stdint.h>
 
SoftwareSerial mySerial(10, 11);
 
Servo thumb, index, middle, ring, pinky;
Servo fingers[5] = {thumb, index, middle, ring, pinky};
 
int servoPins[5] = {2, 3, 4, 5, 6};
int bent[5] = {0, 0, 0, 0, 0};
int initAngles[5] = {90, 55, 55, 90, 90};
int angles[5] = {180, 180, 180, 90, 90};
 
int flexSensorMidPoints[5] = {900, 550, 550, 500, 500};
 
int flexSensorValue;
int handPin;
int read;
 
void setup() {
  thumb.attach(2);
  index.attach(3);
  middle.attach(4);
  ring.attach(5);
  pinky.attach(6);
 
  for (int i = 0; i < 5; i++) {
    fingers[i].write(initAngles[i]);
  }
 
  Serial.begin(9600);
  mySerial.begin(38400);
 
  delay(1000);
}
 
void loop() {
  read = 0;
  if (mySerial.available() >= 3) {
    read = 1;
    handPin = mySerial.read();
    uint8_t highByte = mySerial.read();
    uint8_t lowByte = mySerial.read();
    flexSensorValue = (highByte << 8) | lowByte;
    Serial.print("From ");
    Serial.print(handPin);
    Serial.print(": ");
    Serial.println(flexSensorValue);
  }
 
 
  if (read == 1) {
    if (flexSensorValue > flexSensorMidPoints[handPin] && bent[handPin] == 0) {
      Serial.print("Bent from ");
      Serial.print(handPin);
      Serial.print(": ");
      Serial.println(flexSensorValue);
      Serial.println("-------------------------");
      fingers[handPin].write(angles[handPin]);
      bent[handPin] = 1;
    } else if (flexSensorValue <= flexSensorMidPoints[handPin] && bent[handPin] == 1) {
      Serial.print("Release from ");
      Serial.print(handPin);
      Serial.print(": ");
      Serial.println(flexSensorValue);
      Serial.println("-------------------------");
      bent[handPin] = 0;
      fingers[handPin].write(initAngles[handPin]);
    }
 
  }
}

Pentru Slave:

#include <SoftwareSerial.h>
#include <stdint.h>
 
int flexSensorPins[5] = {A0, A1, A2, A3, A4};
 
SoftwareSerial mySerial(10, 11);
 
void setup() {
  Serial.begin(9600);
  mySerial.begin(38400);
}
 
void loop() {
  for (int i = 0; i < 5; i++) {
    int flexSensorValue = analogRead(flexSensorPins[i]);
    uint8_t highByte = flexSensorValue >> 8;
    uint8_t lowByte = flexSensorValue & 0xFF;
    mySerial.write(i);
    mySerial.write(highByte);
    mySerial.write(lowByte);
    delay(1000);
  }
}

Pentru configurarea HC05

#include <SoftwareSerial.h>
 
SoftwareSerial BTserial(10, 11); // RX || TX
 
void setup() {
  // For enableling AT mode
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
 
  Serial.begin(9600);
  Serial.println("Enter AT command");
  BTserial.begin(38400);
}
 
void loop() {
  if (Serial.available()) {
    BTserial.write(Serial.read());
  }
 
  if (BTserial.available()) {
    Serial.write(BTserial.read());
  }
}

Dupa ce incarcam codul de mai sus pe o placuta Arduino UNO si legam modulul la fel ca la sectiunea Hardware (cu precizarea ca pinul EN/KEY este legat la pinul 9 de pe placuta), trebuie sa dam urmatorele comenzi (daca vrem sa ne asiguram ca am conectat modulul bine, la tastarea comenzii AT, terminalul trebuie sa ne afiseze OK; acest lucru este valabil si pentru comenzile ce urmeaza):

  • Pentru SLAVE:
    • AT+ROLE=0 (Setam modulul drept slave)
    • AT+ADDR? (Adresa pentru bind, este de forma XXXX:XX:XXXXXX, daca nu este afisata asa, inlocuim cu 0 cifrele lipsa)
  • Pentru MASTER:
    • AT+ROLE=1
    • AT+CMODE=0 (Pentru a face bind-ul cu o adresa introdusa manual)
    • AT+BIND=XXXX,XX,XXXXXX (Aici punem adresa modulului SLAVE)

Rezultate Obţinute

Mai jos se poate observa varianta finala a proiectului. Suportul pentru mana este realizat, destul de “primitiv”, din stinghii de lemn intre care am fixat cele 5 servomotoare. In capatul acestora am atasat, folosind un pistol de lipit, mana protetica.

In continuare, in stanga se afla modulul MASTER, la care sunt conectate servomotoarele, iar in dreapta, modulul SLAVE, la care sunt conectate rezistentele de flex.

Ultimul element prezent in imagine este manusa cu ajutorul careia controlam mana. Se poate vedea ca pe fiecare deget este atasat cate un senzor de flex.

Toate acestea sunt conectate la un VCC si GND comun, impreuna cu placutele Arduino UNO care le comandeaza.

Exista un oarecare control asupra mainii, insa din cauza calitatii de fabricatie a rezistentelor si a uzurii, acesta nu este total. Mai exista si alti factori, dar acesta este cel principal.

Concluzii

Cea mai mare problema intampinata este aceea ca valorile citite de la senzori nu sunt exacte (probabil din cauza calitatii de frabricatie sau din cauza ca acestia nu sunt facuti exact pentru genul acesta de aplicatie). Astfel, pentru a obtine cele mai bune rezultate, mana trebuie stransa intr-un pumn. Pe langa acest lucru, o alta problema a fost faptul ca nici citirea intrailor analogice nu este realizata bine. Anume, atunci cand se modifica valoarea citita la un pin (de exemplu, A0), se schimba considerabil si valorile pinilor de langa (A1 si A2). Astfel, chiar daca noi indoim doar un deget, se pot schimba valorile pentru 3 rezistente.

Download

Download arduino files

Download components list

Bibliografie/Resurse