Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Precieze EMG-gestuurde robotische hand: InMoov-integratie en bouwhandleiding

Onderdelen en benodigdheden

Onderdeel Aantal
uECG-apparaat (voor EMG-metingen) 3
InMoov-hand (open-source 3D-printbare robotische hand) 1
Arduino Nano R3 1
Adafruit PCA9685 16-kanaals PWM-driver 1
nRF24-module (generiek) 1

Over dit project

Ons team heeft een lange geschiedenis met robotische handen. Een tijdlang probeerden we een betrouwbare prosthetische hand te maken, maar voor dit project gebruik ik een goed voorbeeld van een bestaande open-source hand: de InMoov. De handmontage behandel ik niet – die is uitvoerig beschreven op de projectwebsite en is tamelijk complex. Ik focussen hier op de besturing, want dat is volledig nieuw!

Bekijk ook hoe deze technologie zich verder ontwikkelde in het volgende project: 8-kanaals EMG met LEDs.

1. Signaalverwerking

De besturing is gebaseerd op EMG – de elektrische activiteit van spieren. Het EMG-signaal wordt verkregen via drie uECG-apparaten (oorspronkelijk ECG-monitors, maar gebaseerd op een generieke ADC kunnen ze elke biosignaal meten, inclusief EMG). Voor EMG-verwerking heeft de uECG een speciale modus waarin het 32-bin spectrumdata en een "spiervenster"-gemiddelde (gemiddelde spectrale intensiteit tussen 75 en 440 Hz) uitzendt.

Precieze EMG-gestuurde robotische hand: InMoov-integratie en bouwhandleiding

Frequentie op verticale as (0-488 Hz, ~15 Hz stappen), tijd op horizontale as (~10 seconden). Kleurcodeert intensiteit: blauw=laag, groen=medium, geel=hoog, rood=nog hoger.

Voor betrouwbare gebarenerkenning is PC-verwerking van deze afbeeldingen vereist. Maar voor simpele vingeraansturing van de robotische hand is het voldoende om het gemiddelde van de 3 kanalen te gebruiken – de uECG levert dit handig op bepaalde pakketbytes, zodat de Arduino-sketch het kan parsen. Deze waarden zien er veel simpler uit:

Precieze EMG-gestuurde robotische hand: InMoov-integratie en bouwhandleiding

Rood, groen, blauw = ruwe waarden van uECG-apparaten op verschillende spiergroepen bij samenknijpen van duim, ringvinger en middelvinger. Voor het oog duidelijk verschillend, maar we moeten dit vertalen naar "vinger-score" voor servo-besturing.

Het probleem: signalen van spiergroepen zijn "gemengd". In geval 1 en 3 is blauwe intensiteit vergelijkbaar, maar rood en groen verschillen. In geval 2 en 3 zijn groene signalen gelijk, maar blauw en rood verschillen. Om ze te "ontmengen" gebruikte ik een relatief simpele formule:

S0 = V0² / ((V1 × a0 + b0) × (V2 × c0 + d0))

Waarbij S0 = score voor kanaal 0, V0/V1/V2 = ruwe waarden voor kanalen 0/1/2, en a,b,c,d = handmatig afgestelde coëfficiënten (a en c: 0,3-2,0; b en d: 15 en 20 – afstemmen op jouw sensorplaatsing). Dezelfde berekening voor kanalen 1 en 2. Resultaat: bijna perfect gescheiden signalen:

Precieze EMG-gestuurde robotische hand: InMoov-integratie en bouwhandleiding

Deze signalen (ringvinger, middelvinger, duim) zijn nu helder en makkelijk te vertalen naar servobewegingen via drempelwaarden.

2. Schema's

Precieze EMG-gestuurde robotische hand: InMoov-integratie en bouwhandleiding

Het schema is eenvoudig: nRF24-module, PCA9685 (of vergelijkbare I2C PWM-controller), en een sterke 5V-voeding (minimaal 5A voor stabiele bediening van alle servos tegelijk).

Aansluitingen

  • nRF24 pin 1 (GND) → Arduino GND
  • nRF24 pin 2 (Vcc) → Arduino 3,3V
  • nRF24 pin 3 (CE) → Arduino D9
  • nRF24 pin 4 (CSN) → Arduino D8
  • nRF24 pin 5 (SCK) → Arduino D13
  • nRF24 pin 6 (MOSI) → Arduino D11
  • nRF24 pin 7 (MISO) → Arduino D12
  • PCA9685 SDA → Arduino A4
  • PCA9685 SCL → Arduino A5
  • PCA9685 Vcc → Arduino 5V
  • PCA9685 GND → Arduino GND
  • PCA9685 V+ → Sterke 5V-voeding
  • PCA9685 GND → Sterke voeding GND
  • Vingerservos: PCA-kanalen 0-4 (duim=kanaal 0, wijvinger=1, middelvinger=2, ringvinger=3, pink=4)

3. EMG-sensorplaatsing

Voor goede metingen is juiste plaatsing van de uECG-apparaten cruciael. Veel opties zijn mogelijk, elk vereist eigen signaalverwerking. Mijn keuze:

Precieze EMG-gestuurde robotische hand: InMoov-integratie en bouwhandleiding

Contra-intuitief: duimspiersignaal is beter zichtbaar aan de tegenovergestelde kant van de onderarm. Alle sensoren dichtbij de elleboog (spieren hebben daar hun grootste volume, maar check precies waar jouw liggen – grote individuele verschillen).

4. Code

Voordat je het hoofdprogramma draait, moet je de unit-ID's van je uECG-apparaten achterhalen (regel 101 uncommenten, apparaten één voor één aanzetten) en invullen in het unit_ids-array (regel 37).

#include <SPI.h>
#include <RF24.h>
#include <RF24_config.h>
#include <nRF24L01.h>
#include <Adafruit_PWMServoDriver.h>
#include <Wire.h>

#define SERVOMIN 150
#define SERVOMAX 600

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
int rf_cen = 9;
int rf_cs = 8;
RF24 rf(rf_cen, rf_cs);

uint8_t pipe_rx[8] = {0x0E, 0xE6, 0x0D, 0xA7, 0, 0, 0, 0};

uint8_t swapbits(uint8_t a) {
  uint8_t v = 0;
  if(a & 0x80) v |= 0x01;
  if(a & 0x40) v |= 0x02;
  if(a & 0x20) v |= 0x04;
  if(a & 0x10) v |= 0x08;
  if(a & 0x08) v |= 0x10;
  if(a & 0x04) v |= 0x20;
  if(a & 0x02) v |= 0x40;
  if(a & 0x01) v |= 0x80;
  return v;
}

long last_servo_upd = 0;
byte in_pack[32];
unsigned long unit_ids[3] = {4294963881, 4294943100, 28358}; // VUL JE EIGEN IDs IN!
int unit_vals[3] = {0, 0, 0};
float tgt_angles[5];
float cur_angles[5];
float angle_open = 30;
float angle_closed = 150;

void setup() {
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  for(int x = 0; x < 8; x++) pipe_rx[x] = swapbits(pipe_rx[x]);
  
  rf.begin();
  rf.setDataRate(RF24_1MBPS);
  rf.setAddressWidth(4);
  rf.setChannel(22);
  rf.setRetries(0, 0);
  rf.setAutoAck(0);
  rf.disableDynamicPayloads();
  rf.setPayloadSize(32);
  rf.openReadingPipe(0, pipe_rx);
  rf.setCRCLength(RF24_CRC_DISABLED);
  rf.disableCRC();
  rf.startListening();
  
  // Let op: uECG moet in "raw data mode" (langdurige knopdruk) staan, standaard is BLE-modus onbruikbaar voor nRF24
  
  Serial.begin(115200);
  pwm.begin();
  pwm.setPWMFreq(60);
  for(int i = 0; i < 5; i++) {
    tgt_angles[i] = angle_open;
    cur_angles[i] = angle_open;
  }
}

void setAngle(int n, float angle) {
  pwm.setPWM(n, 0, SERVOMIN + angle * 0.005556 * (SERVOMAX - SERVOMIN));
}

float angle_speed = 15;
float v0 = 0, v1 = 0, v2 = 0;

void loop() {
  if(rf.available()) {
    rf.read(in_pack, 32);
    byte u1 = in_pack[3], u2 = in_pack[4], u3 = in_pack[5], u4 = in_pack[6];
    unsigned long id = (u1<<24) | (u2<<16) | (u3<<8) | u4;
    
    if(in_pack[7] != 32) id = 0; // Verkeerd pakkettype: EMG-modus vereist byte=32
    int val = in_pack[10];
    if(val != in_pack[11]) id = 0; // Waarde gedupliceerd voor ruisbestendigheid (geen CRC)
    
    for(int n = 0; n < 3; n++)
      if(id == unit_ids[n])
        unit_vals[n] = val;
  }
  
  long ms = millis();
  if(ms - last_servo_upd > 20) {
    last_servo_upd = ms;
    
    // Servo's soepel bewegen naar doelhoek
    for(int n = 0; n < 5; n++) {
      if(cur_angles[n] < tgt_angles[n] - angle_speed/2) cur_angles[n] += angle_speed;
      if(cur_angles[n] > tgt_angles[n] + angle_speed/2) cur_angles[n] -= angle_speed;
    }
    for(int n = 0; n < 5; n++) setAngle(n, cur_angles[n]);
    
    // Exponentieel gemiddelde: voorkomt dat piekjes vingerafstand beïnvloeden
    v0 = v0*0.7 + 0.3*(float)unit_vals[0];
    v1 = v1*0.7 + 0.3*(float)unit_vals[1];
    v2 = v2*0.7 + 0.3*(float)unit_vals[2];
    
    // Scores berekenen uit ruwe waarden
    float scor0 = 4.0*v0*v0/((v1*0.3 + 20)*(v2*1.3 + 15));
    float scor1 = 4.0*v1*v1/((v0*2.0 + 20)*(v2*2.0 + 20));
    float scor2 = 4.0*v2*v2/((v0*1.2 + 20)*(v1*0.5 + 15));
    
    // Debug output
    Serial.print(scor0); Serial.print(' ');
    Serial.print(scor1); Serial.print(' ');
    Serial.println(scor2);
    
    // Drempelwaarden voor vingeraansturing (3 spiergroepen → 5 vingers)
    if(scor2 < 0.5) tgt_angles[0] = angle_open;      // Duim open
    if(scor2 > 1.0) tgt_angles[0] = angle_closed;    // Duim dicht
    
    if(scor1 < 0.5) {                                // Wij + middelvinger open
      tgt_angles[1] = angle_open;
      tgt_angles[2] = angle_open;
    }
    if(scor1 > 1.0) {                                // Wij + middelvinger dicht
      tgt_angles[1] = angle_closed;
      tgt_angles[2] = angle_closed;
    }
    
    if(scor0 < 0.5) {                                // Ring + pink open
      tgt_angles[3] = angle_open;
      tgt_angles[4] = angle_open;
    }
    if(scor0 > 1.0) {                                // Ring + pink dicht
      tgt_angles[3] = angle_closed;
      tgt_angles[4] = angle_closed;
    }
  }
}

5. Resultaten

Na ongeveer 2 uur experimenteren bereikte ik redelijk betrouwbare werking (video toont typisch geval). Het werkt niet perfect en met deze verwerking herkent het alleen open/dichte vingers (en niet elk van de 5 apart – het detecteert 3 spiergroepen: duim, wij+middelvinger samen, ring+pink samen). Maar de "AI" die het signaal analyseert is hier 3 regels code en gebruikt één waarde per kanaal. Veel meer is mogelijk door 32-bin spectraalbeelden op PC/smartphone te analyseren. Deze versie gebruikt 3 uECG-apparaten (3 EMG-kanalen). Met meer kanalen zouden complexe patronen herkenbaar moeten zijn – dat is juist de bedoeling: een startpunt bieden voor geïnteresseerden. Handbesturing is zeker niet de enigste toepassing voor zo'n systeem.

Code

  • emg_hand_control2.ino (volledige code hierboven)

Schema's

Fritzing-bestand: nrf24_hand_control_5jcEeCP8a3.fzz

Productieproces

  1. Anticonceptiepil: Geschiedenis, Voordelen, Risico's en Productie
  2. LM35-gebaseerd temperatuurregelsysteem met AT89S52 microcontroller
  3. DIY Automatische Treinbesturing met Arduino – Eenvoudig, Betrouwbaar en Aanpasbaar
  4. Universele Android-afstandsbediening bouwen met Arduino, 1Sheeld en IR-besturing
  5. Externe IoT-besturing van een zelfgebouwde robotarm
  6. Bestuur een Arduino-rover naadloos met Firmata en een Xbox One-controller
  7. Studenten bouwen geavanceerd B&R-aangedreven robotisch vuilnissorteringssysteem
  8. AI-gedreven Fotonische Chips Vormgeven Breedbandlicht Voor Slimme Optica
  9. Robotautomatisering Stroomlijnen met 3DG's Geavanceerde Robot Simulatie Software
  10. Trinamic & Maxim Integrated publiceren referentie-ontwerp om end-of-arm-tooling-ontwikkeling in industriële robotica te versnellen
  11. Bouw een Draadloos IR-Sensor-Gestuurd Robotvoertuig