This is an old revision of the document!


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:

  • Arduino UNO
  • Rezistente de tip flex
  • Servomotoare
  • Module bluetooth HC05
  • Fire de conexiune
  • Breadboard

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

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.

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

Exista un oarecare control asupra fiecarui deget, insa din cauza rezistentelor si a uzurii prin folosinta, acesta nu este permanent. Pentru a vedea cele mai bune rezultate, trebuie sa strangem pumnul, asigurandu-ne astfel ca toate rezistentele vor afisa valori peste minimul necesar indoirii.

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

Bibliografie/Resurse

pm/prj2023/gpatru/prostetic_hand.1685354756.txt.gz · Last modified: 2023/05/29 13:05 by filip.secareanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0