Roboterarm aus dem 3D Drucker

Ein schönes Bauprojekt für einen 3D Drucker ist die eines Roboterarmes. Hier trifft Mechanik auf Elektronik. Auf Thingiverse gibt es den EezyBot. Dieser ist sehr simpel aufgebaut, leicht im Zusammenbau und erfüllt seinen Zweck. Als Demo gibt es noch eine Kugelbahn dazu.

Bauteile:
2x 10er StoppMutter M4
1x 100er Beilagscheiben DIN 125 ZN A 4.3
2x SechsKantMutter DIN934-A2 M3 (10) 888118
1x 100er Beilagscheiben DIN125 ZN A 3,2 814628
1x 100er Linsenzylinderschrauben DIN 7985 839646
10x InnenSechsKant-Zylinderschrauben DIN 912 M3 X 12 827281
5x M3 X 20 InnenSechsKantSchrauben 814156
1x Carbonrundrohr 2,0 X 4,0 X 500mm 275198
1x 6Kaschr DIN 933 ES A2 30mm (100) 1064005
1x 100er ZylinderKopf InnenSechsKant DIN 912 M3 X 10 839669

1x Arduino Uno 191789
1x Arduino Shield Motor Shield R3

3x Servomotoren Adafruit MG995R Conrad 1142
2x Servomotor %VDC TowerPro SG92R 169

Pololu Maestro Servo Controller

3D-Druck Teile:

EBA_01.00.010_basement.STL
EBA_01.00.009_servo_plate.STL (2x)
EBA_01.00.012_R01_claw_support.STL
EBA_01.00.013_R01_right_finger.STL
EBA_01.00.014_R01_left_finger.STL
EBA_01.00.015_drive_gear.STL
EBA_01.00.016_R01_driven_gear.STL
EBA_01.00.006_triangular_link.STL
EBA_01.00.003_link.STL (3x)
EBA_01.00.002_vertical_drive_arm.STL
EBA_01.00.005_horizontal_arm.STL
EBA_01.00.004_forward_drive_arm.STL
EBA_01.00.001.STL
EBA_01.00.017_R01_ramp.STL
EBA_01.00.019_ball.STL

Zusammenbau:

In die EBA_01.00.011_round_plate wird von dem Servo Adafruit MG995R das Servohorn eingelegt. Ich hab diese mit Sekundenkleber festgeklebt, da sie zu oft rausgesprungen ist. Anschliessend wird der Servo festgeschraubt.

Der Srevomotor wird in die Halterung des EBA_01.00.010_basement eingelegt. Leider hat das nicht ganz gut gehalten, so dass ich den Servo dort auch festgeklebt habe. Auf die EBA_01.00.011_round_plate wird die EBA_01.00.001 mit Innensechskantschrauben befestigt.

EBA_01.00.006_triangular_link, EBA_01.00.003_link, EBA_01.00.005_horizontal_arm und EBA_01.00.004_forward_drive_arm werden mit M4 Schrauben, Beilegscheiben und Stoppermutter miteinander verbunden. Das Gelenk von EBA_01.00.004_forward_drive, EBA_01.00.005_horizontal_arm und EBA_01.00.006_triangular_link wird mit dem Karbonrohr und einer innenliegenden M3 Schraube verbunden.

An den EBA_01.00.006_triangular_link wird noch ein zweiter EBA_01.00.003_link befestigt. Weiterhin kommt an den EBA_01.00.005_horizontal_arm auch ein EBA_01.00.003_link befestigt , an dem wiederum der EBA_01.00.002_vertical_drive_arm hängt.

Nun wird der Greifer zusammen gebaut. Das tragende Element dabei ist EBA_01.00.012_R01_claw_support. An diesem werden EBA_01.00.013_R01_right_finger, EBA_01.00.014_R01_left_finger, EBA_01.00.015_drive_gear und EBA_01.00.016_R01_driven_gear befestigt. In EBA_01.00.015_drive_gear wird ein gekürzter Servohorn eingelassen. Alle Teile werden mit Innensechskantschrauben befestigt.

Der Greifer wird an EBA_01.00.005_horizontal_arm und EBA_01.00.003_link befestigt. Die Löcher müssen nach dem 3D Druck alle noch etwas ausgefeilt werden, damit die Gelenke leichtgängig gehen. Auch sollten alle Verbindungen Beilegscheiben haben. Die Stoppmuttern dürfen dabei nicht zu feste angezogen werden.

Der Greifer wird mit dem Servo SG92R bewegt.

Der Arm wird an EBA_01.00.001 über EBA_01.00.004_forward_drive_arm und EBA_01.00.002_vertical_drive_arm befestigt Dabei wird wieder 23mm langes Karbonrohr als Gelenk verwendet. Innen ist eine 23mm lange Innensechskantschraube, bei der der Kopf abgesägt wurde.

Das Karbonrohr muss so eingelegt werden, dass es nicht aus den Enden des Gelenkes herausschaut. An den Seiten werden zwei Servos MG995R mit jeweils einer EBA_01.00.009_servo_plate befestigt. Die Servohörner werden dabei vorher an den Servo angeschraubt

Die Motoren werden mit Innensechskantschrauben befestigt.

Jetzt werden die Motoren mit der Steuerung verbunden. Im ersten Versuch habe ich versucht die Servos mit einem Arduino zu betreiben und einem PC bzw Mobiltelefon über Bluetooth. Dabei spielt der Arduino lediglich das Zwischenstück.

Arduino Hardware und Software:


#include <SoftwareSerial.h>
#include <Servo.h>

#define ASCII_DIFF 48
#define MOVE_DELAY 500

int bluetoothTx = 6;
int bluetoothRx = 7;

int startPosZAxle  = 90;
int startPosYLift  = 100;
int startPosYArm   = 40;
int startPosHand   = 65;
int startPosMarble = 60;
unsigned int showPosCmd = 999;

Servo myservo1, myservo2, myservo3, myservo4, myservo5;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

void setup()
{
  if (Serial) {
    Serial.end();
  }
  Serial.begin(9600);
  while (!Serial) {
    ;
  }

  myservo1.attach(8);
  myservo2.attach(9);
  myservo3.attach(10);
  myservo4.attach(11);
  myservo5.attach(12);

  bluetooth.begin(9600);

  Serial.println("ready");
  bluetooth.println("ready");

  myservo1.write(startPosZAxle);
  delay(MOVE_DELAY);
  myservo2.write(startPosYLift);
  delay(MOVE_DELAY);
  myservo3.write(startPosYArm);
  delay(MOVE_DELAY);
  myservo4.write(startPosHand);
  delay(MOVE_DELAY);
  myservo5.write(startPosMarble);
  delay(MOVE_DELAY);
}

void printPositions() {
  int read1 = myservo1.read();
  Serial.println(read1);
  bluetooth.println(read1);

  int read2 = myservo2.read();
  Serial.println(read2);
  bluetooth.println(read2);

  int read3 = myservo3.read();
  Serial.println(read3);
  bluetooth.println(read3);

  int read4 = myservo4.read();
  Serial.println(read4);
  bluetooth.println(read4);

  int read5 = myservo5.read();
  Serial.println(read5);
  bluetooth.println(read5);
}

void loop()
{
  boolean received = false;
  unsigned int servoNr = 0;
  unsigned int servoPosIn1 = 0;
  unsigned int servoPosIn2 = 0;
  unsigned int servoPosIn3 = 0;

  if ( 4 <= bluetooth.available() ) {
    servoNr     = bluetooth.read() - ASCII_DIFF;
    servoPosIn1 = bluetooth.read() - ASCII_DIFF;
    servoPosIn2 = bluetooth.read() - ASCII_DIFF;
    servoPosIn3 = bluetooth.read() - ASCII_DIFF;
    received = true;
  }
  else if ( 4 <= Serial.available() ) {
    servoNr     = Serial.read() - ASCII_DIFF;
    servoPosIn1 = Serial.read() - ASCII_DIFF;
    servoPosIn2 = Serial.read() - ASCII_DIFF;
    servoPosIn3 = Serial.read() - ASCII_DIFF;
    received = true;
  }
  if ( true == received ) {
    unsigned int servoPos = servoPosIn1 * 100 + servoPosIn2 * 10 + servoPosIn3;
    while ( bluetooth.available() ) {
      bluetooth.read();
    }
    while ( Serial.available() ) {
      Serial.read();
    }

    if ( showPosCmd == servoPos ) {
      printPositions();
    } else {

      bluetooth.print("Servo:");
      bluetooth.print(servoNr);
      bluetooth.print(" Pos:");
      bluetooth.print(servoPos);

      Serial.print("Servo:");
      Serial.print(servoNr);
      Serial.print(" Pos:");
      Serial.print(servoPos);

      if ( 1 == servoNr ) {
        myservo1.write(servoPos);
        bluetooth.println(" On 1");
        Serial.println(" On 1");
      }
      else if ( 2 == servoNr ) {
        myservo2.write(servoPos);
        bluetooth.println(" On 2");
        Serial.println(" On 2");
      }
      else if ( 3 == servoNr ) {
        myservo3.write(servoPos);
        bluetooth.println(" On 3");
        Serial.println(" On 3");
      }
      else if ( 4 == servoNr ) {
        myservo4.write(servoPos);
        bluetooth.println(" On 4");
        Serial.println(" On 4");
      }
      else if ( 5 == servoNr ) {
        myservo5.write(servoPos);
        bluetooth.println(" On 5");
        Serial.println(" On 5");
      }
      else {
        bluetooth.println(" Off");
        Serial.println(" Off");
      }
    }
  }
  delay(MOVE_DELAY);
}

Leider hat die Programmierung aller Servos im Parallelbetrieb gleichzeitg nicht funktioniert. Sie zuckten herum, auch wenn kein Befehl kam. Ein Servomoter ist im Prinzip ein normaler Motor, der an der Welle ein Potentiometer zur Messung des Winkels hat. Die Steuerimpulse kommen dabei in der Regel in einem 20ms langen Signal (50 Herz). Die länge des High Impulses am Anfang des 20ms Signals bestimmt dabei die Position (500ms lang entspricht 0°, 2500ms lang entspricht 180°). Der Rest des Signals ist Low. Eine Regellogik steuert dabei die Positionserreichung anhand des Widerstandswertes vom Potntiometerwertes. Wahrscheinlich kommen die bei der Servo Ansteuerung die Signale durcheinander, wenn mehrere Servos angesteuert werden.

Trotzdem hab ich mich dann für eine andere Lösung entschieden und mir einen speziellen Servo Motor Controller besorgt.

Der Pololu Maestro Regler kann bis zu sechs Servos steuern. Die Servos benötigen eine eigene Stromversorgung mit 5V. Dabei hab ich ein 2A Netzteil verwendet.

An einem Windows PC wird ein spezieller Treiber installiert und der Motorcontroller kann über einen COM Port angesteuert werden. Es gibt eine spezielle Bibliothek für Python, die die Ansteuerung vereinfacht.

Wichtig unter Windows ist dabei im Pololu Maestro Control Centre auf USB Dual Port zu stellen. Für die Demonstration mit der Kugelbahn hab ich folgendes Python Skript geschrieben.

import time
import maestro
servo = maestro.Controller("COM5")

servo.setAccel(0,4)      
servo.setSpeed(0,10)    

servo.setAccel(1,4)      
servo.setSpeed(1,10)    

servo.setAccel(2,4)    
servo.setSpeed(2,10)  

servo.setAccel(3,4)  
servo.setSpeed(3,10)

servo.setAccel(4,0) 
servo.setSpeed(4,0)  

#save arm
servo.setTarget(1,6940)
servo.setTarget(2,5180)
servo.setTarget(0,6000)
servo.setTarget(3,7000)
#close door
servo.setTarget(4,3968)
time.sleep(5)
i = 0

while i < 100:
#start 
    servo.setTarget(0,6227)  
    servo.setTarget(1,5380)  
    servo.setTarget(2,6101)  
    servo.setTarget(2,7177)  
    time.sleep(3)
    servo.setTarget(4,7000) 
    time.sleep(2)
    servo.setTarget(3,4535)  
    time.sleep(5)
    servo.setTarget(2,6101)
    time.sleep(2)
    servo.setTarget(0,6227)
    time.sleep(2)
    servo.setTarget(1,8000)
    time.sleep(2)
    servo.setTarget(0,4813)
    time.sleep(2)
    servo.setTarget(2,6786)
    time.sleep(2)
    servo.setTarget(4,3948)
    time.sleep(2)
    servo.setTarget(3,7000)
    time.sleep(2)
    servo.setTarget(1,6940)
    servo.setTarget(2,5180)
    servo.setTarget(0,6000)
    servo.setTarget(3,7000)
    time.sleep(2)
    i += 1
	
servo.close()

Links:
https://www.thingiverse.com/thing:1015238
https://github.com/sky4walk/RoboterArm
https://www.conrad.de/de/arduino-shield-motor-shield-r3-65189-passend-fuer-arduino-boards-arduino-arduino-uno-323477.html
https://www.conrad.de/de/motor-micro-servo-sg92r-adafruit-169-1516595.html
https://www.conrad.de/de/toolcraft-223409-sicherungsmuttern-m4-din-985-stahl-verzinkt-10-st-223409.html
https://www.conrad.de/de/toolcraft-814652-unterlegscheiben-innen-durchmesser-43-mm-m4-din-125-stahl-verzinkt-100-st-814652.html
http://appinventor.mit.edu/
https://de.wikipedia.org/wiki/Servo

 

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.