Experiment: Kontrollier′ die Klaue
Backyard Brains Logo

Neurowissenschaften für jedermann!

+49 176 24386548


items ()

Experiment: Kontrollier′ die Klaue

Mach′ deine erste anthropomorphe Neuroprothese indem du eine Roboterklaue mit deinen Muskelsignalen kontrollierst!

Dauer 2 Stunden
Schwierigkeitsgrad Fortgeschritten

Was lernt man hier?

In diesem Experiment wirst du lernen wie man ′The Claw′ mit Muskelkontraktionen ansteuert. Dadurch kannst du dein Elektromyogramm messen und ′The Claw′ wird sich öffnen und schließen. Je nachdem wie stark du z.B. einen deiner Unterarmmuskeln kontrahierst. Du kannst damit einfach nur spielen oder dir ein eigenes Wissenschaftsexperiment designen. Werde ein Wissenschaftler und lern dabei was über Neuroprothesen!


Hintergrund

übersetzt ins Deutsche, geschrieben von José Enrique López Pérez, Elektroingenieurstudent in Oaxaca, Mexico.

Servomotor

Um Roboter herzustellen benutzen Leute oft Servomotoren. Unter den Elektroingenieuren liebevoll ′Servos′ genannt, sind sie aufgrund ihrer kleinen Größe und ihrem geringen Energieverbrauch extrem nützlich. Mit ihrer Hilfe kann man sowohl kleine Spielzeugautos, aber auch ganze Schiffe oder Flugzeuge steuern. Eine Art von ′Servo′ kann zum Beispiel aus einem DC Motor, einem Geschwindigkeits⁄Kraft−Getriebe und einem kleinen Kontrollschaltkreis zusammengebaut werden.

Was ist der Unterschied zwischen einem Servomotor und einem Schrittmotor (Stepper)?

Inside a Stepper In einem Schrittmotor sind Spulen, die mit einer Serie von Pulsen aufgeladen werden und dadurch den Motor ′schrittweise′ bewegen. Deswegen kommen da auch meistens viele Kabel raus (normalerweise 5 oder 6). Der Servomotor, andererseits, enthält einen DC-Motor und einen Kontrollschaltkreis, der die präzise Ansteuerung mit nur drei Drähten ermöglicht: einer um zu kontrollieren und die anderen beiden für die Power und die Erde.

Wichtige Unterschiede bei Geschwindigkeit, Stärke und Präzision; der ′Servo′ ist vor allem bei highspeed Anwendungen genauer und kräftiger. Der Stepper wird deswegen nicht bei hohen Geschwindigkeit verwendet. Hier verliert er zu sehr an Stärke. Bei geringen Geschwindigkeiten jedoch ist der Stepper genauer und stärker als der ′Servo′, warum er in Roboterarmen weit verbreitet ist.

Die PWM (Pulsweitenmodulation) wird am häufigsten zum Servo-Kontrollieren benutzt. Sie generiert eine Rechteckwelle, die die Plateaudauer bei gleichbleibender Periode erhöht; somit führt die Plateaudauer zur Motorposition. Ein im Kontrollschaltkreis eingebautes Potentiometer misst den Winkel des ′Servos′: Falls der Motor im richtigen Winkel steht, schaltet sich der Motor aus. Der Schaltkreis überprüft das der Servo mögliche Fehlstellungen korrigiert. Der Servo wird die Position des Motors so lange korrigieren, bis er in die richtige Richtung zeigt. Normalerweise dreht sich ein Servo um bis zu 180 Grad, manche erreichen aber auch 210 Grad (es gibt sogar 360 Grad-Servos, die werden meistens benutzt, wenn man einen weite Rotation braucht). Die Gradzahl unterscheidet sich je nach Anwendung und Hersteller. Die Pulsdauer zeigt uns wie groß der Winkel der Rotation ist.

Wichtig: Damit ein Servo in der gleichen Stellung bleibt, brauch man einen kontinuierlichen Puls mit der gleichen Dauer. Deswegen wird der Motor sich gegen von außen einwirkende Kräfte wehren. Wenn der Servomotor aufhört Pulse zu senden, oder das Intervall zwischen den Pulsen höher als das erlaubte Maximum ist, dann wird der Servomotor an Kraft verlieren und versuchen seine Position beizubehalten und jede externe Kraft kann ihn bewegen.

Servokontrolle. Ein Servomotor hat traditionell drei Kabel: Strom, Erde und das Signal. Das Stromkabel ist normalerweise rot, und diese Konfiguration ist zu den 5V verbunden. Das Kabel der Erde ist meist schwarz oder braun und muss mit ‚ground (engl. für Erde)‘ verbunden werden. Das Signalkabel ist üblicherweise weiß, gelb, oder orange und muss zum PWM verbunden werden. Um eine Pulsweitenmodulation zu generieren wird oft ein Mikrokontroller benutzt, weil er spezielle Hardware hat um diese Funktion durchzuführen und er vereinfacht den Prozess um das Signal zu erzeugen. Er kann das mit nur ein paar wenigen Zeilen Computercode.

Konfiguration

In diesem Experiment wirst du nur Strom, Erde, und den digital out pin 2 des SpikerShields benutzen um eine PWM Welle zu generieren. Der Strom komm von einer zweiten 9V Batterie (falls du den Strom nur vom Arduino ziehst wird die Amplifizierung deines Muskels instabil durch Spannungsschwankungen des Servos).

Downloads

Nimm unseren (.ino) Claw Sketch und lade ihn auf deinen Arduino

Video

Ablauf

  1. Deine Roboterklaue hat ein Servomotorkabel, das aus drei Drähten besteht. Steck diesen in dein Muscle SpikerShield. Das Kabel hat einen schwarzen, einen roten und einen gelben Draht. Der gelbe Draht ist der Kontrolldraht, der rote der Strom (9V), und schwarz ist die Erde.
  2. Stöpsel das Servomotorkabel in den Dreierpin von deinem Muscle SpikerShield. Die Ausrichtung ist hier wichtig! Die gelbe Seite zeigt in Richtung Boardinnenseite. Gelb nach innen!
  3. Deine Claw sehnt sich nach Strom und braucht seine eigene Stromzufuhr. Verbinde beide 9V Batterien mit ihren Anschlussbuchsen auf dem Muscle SpikerShield Board und dem Arduino.
  4. Befestige drei Elektrodensticker auf deinem Arm. Zwei auf deinem Unterarm und einen auf deinem Handrücken.
  5. Nimm das orangene Elektrodenkabel, verbinde die zwei roten Alligatorclips mit den Elektrodenstickern auf deinem Unterarm und den schwarzen Alligator auf deinem Handrücken. Das orangene Kabel kommt jetzt in die orangene Buchse (Klinkenstecker).
  6. Verbinde jetzt die zusätzliche Batterie mit ihrer Anschlussbuchse so wie du es auf dem Bild unten sehen kannst. Die Anschlussbuchse befindet sich an dem blauen Arduino Board um dem System noch mehr Power zu geben.
  7. Jetzt kontrahier deinen Arm! Du solltest sehen können wie die Klaue sich auch bewegt. Du kannst den weißen Knopf drücken um zwischen hohen und geringen Schwellenwertmodi auszuwählen und den roten Knopf um zwischen den Voreinstellungen der ′Claw′ zu wechseln. Das heißt: Wie fest muss ich anspannen und ist die Klaue zuerst geschlossen oder geöffnet?

    Code Beschreibung: Dieser Code macht deinen Arduino, mit Hilfe des Muscle SpikerShield, zu einem Elektromyogrammdetektor. Das heißt: Deine Unterarmkontraktionen werden in Pulsweitenmodulationspulse umgewandelt, die deinen Servomotor ansteuern und dadurch bewegen. Die Pulse verändern sich je nach Muskelaktivität: wenn du deine Hand fester zudrückst, schließt sich ′The Claw′ weiter. Wenn du die in diesem Programm beinhaltete Bibliothek benutzt , kannst du die Servomotoren bereits ansteuern. Unten aufgeführt kannst du ihn dir aber anschauen und downloaden, wenn du auf den link klickst. Entweder hier oder durch den oben angeführten link. Unten siehst du den Code, wenn du ihn lieber runterladen willst klick einfach hier.

    The Code

    /*
    * --------------------------------------------------------------------------------------
    * Code monitors amplitude of EMG envelope, displays EMG strength on LED bar and controls
    * robotic gripper by controlling servo motor.
    * --------------------------------------------------------------------------------------
    */
    
    #include <Servo.h>
    #define GRIPPER_STATE_BUTTON_PIN 4          //pin for button that switches defult state
                                                //of the gripper (opened/closed)
    #define SERVO_PIN 2                         //pin for servo motor
    #define SENSITIVITY_BUTTON_PIN 7            //pin for button that selects sesitivity
    #define NUM_LED 6                           //number of LEDs in LED bar
    #define GRIPPER_MINIMUM_STEP 5              //5 degree dead zone (used to avoid
                                                //aiming oscilation)
    #define OPEN_MODE 1                         //default gripper state is opened
    #define CLOSED_MODE 2                       //default gripper state is closed
    #define MINIMUM_SERVO_UPDATE_TIME 100       //update servo position every 100ms
    
    Servo Gripper;                              //servo for gripper
    byte ledPins[] = {8, 9, 10, 11, 12, 13};    //pins for LEDs in LED bar
    
    //EMG saturation values (when EMG reaches this value
    //the gripper will be fully opened/closed)
    int sensitivities[] = {200, 350, 520, 680, 840, 1000};
    int lastSensitivitiesIndex = 2;             //set initial sensitivity index
    
    int emgSaturationValue = 0;                 //selected sensitivity/EMG saturation value
    int analogReadings;                         //measured value for EMG
    byte ledbarHeight = 0;                      //temporary variable for led bar height
    
    unsigned long oldTime = 0;                  //timestamp of last servo angle update (ms)
    int oldDegrees = 0;                         //old value of angle for servo
    int newDegree;                              //new value of angle for servo
    
    unsigned long debouncerTimer = 0;           //timer for button debouncer
    int gripperStateButtonValue = 0;            //variable that stores state of button
    int userReleasedButton = 1;                 //flag that is used to avoid multiple
                                                //button events when user holds button
    
    int currentFunctionality = OPEN_MODE;       //current default position of claw
    
    
    
    //-----------------------------------------------------------------------------------
    //   Setup servo, inputs and outputs
    // ----------------------------------------------------------------------------------
    void setup(){
    	//init servo
    	Gripper.attach(SERVO_PIN);
    
    	//init button pins to input
    	pinMode(GRIPPER_STATE_BUTTON_PIN, INPUT);
    	pinMode(SENSITIVITY_BUTTON_PIN, INPUT);
    
    	//initialize all LED pins to output
    	for(int i = 0; i < NUM_LED; i++){
    		pinMode(ledPins[i], OUTPUT);
    	}
    
    	//get current sensitivity
    	emgSaturationValue = sensitivities[lastSensitivitiesIndex];
    }
    
    
    
    //-----------------------------------------------------------------------------------
    //   Main loop
    //
    //   - Checks state of sesitivity button
    //   - Checks state of default-gripper-state button
    //   - Measure EMG
    //   - Shows EMG strength on LED bar
    //   - Sets angle of servo based on EMG strength and current mode (open/closed)
    // ----------------------------------------------------------------------------------
    void loop()
    {
    
    	//-----------------------  Switch sensitivity ------------------------------------
    
    	//check if button is pressed (HIGH)
    	if (digitalRead(SENSITIVITY_BUTTON_PIN))
    	{
    		//turn off all the LEDs in LED bar
    		for(int j = 0; j < NUM_LED; j++)
    		{
    			digitalWrite(ledPins[j], LOW);
    		}
    
    		//increment sensitivity index
    		lastSensitivitiesIndex++;
    		if(lastSensitivitiesIndex==NUM_LED)
    		{
    			lastSensitivitiesIndex = 0;
    		}
    
    		//get current sensitivity value
    		emgSaturationValue = sensitivities[lastSensitivitiesIndex];
    
    		//light up LED at lastSensitivitiesIndex position for visual feedback
    		digitalWrite(ledPins[lastSensitivitiesIndex], HIGH);
    
    		//wait user to release button
    		while (digitalRead(SENSITIVITY_BUTTON_PIN))
    		{
    			delay(10);
    		}
    		//whait a bit more so that LED light feedback is always visible
    		delay(100);
    	}
    
    
    	//----------------------------  Switch gripper default position open/close ---------
    
    	//check if enough time has passed for button contact to settle down
    	if((millis() - debouncerTimer) > 50)
    	{
    		gripperStateButtonValue = digitalRead(GRIPPER_STATE_BUTTON_PIN);
    		//if button is pressed
    		if(gripperStateButtonValue == HIGH)
    		{
    			//if last time we checked button was not pressed
    			if(userReleasedButton)
    			{
    				debouncerTimer = millis();
    				//block button events untill user releases it
    				userReleasedButton = 0;
    
    				//toggle operation mode
    				if(currentFunctionality == OPEN_MODE)
    				{
    					currentFunctionality = CLOSED_MODE;
    				}
    				else
    				{
    					currentFunctionality = OPEN_MODE;
    				}
    			}
    		 }
    		 else
    		 {
    			userReleasedButton = 1;
    		 }
    	}
    
    
    	//-----------------------------  Measure EMG ---------------------------------------
    
    	analogReadings = analogRead(A0);//read EMG value from analog input A0
    
    
    	//---------------------- Show EMG strength on LED ----------------------------------
    
    	//turn OFF all LEDs on LED bar
    	for(int j = 0; j < NUM_LED; j++)
    	{
    		digitalWrite(ledPins[j], LOW);
    	}
    
    	//calculate what LEDs should be turned ON on the LED bar
    	analogReadings= constrain(analogReadings, 30, emgSaturationValue);
    	ledbarHeight = map(analogReadings, 30, emgSaturationValue, 0, NUM_LED);
    
    	//turn ON LEDs on the LED bar
    	for(int k = 0; k < ledbarHeight; k++)
    	{
    		digitalWrite(ledPins[k], HIGH);
    	}
    
    
    	//-------------------- Drive Claw according to EMG strength -----------------------
    
    	//set new angle if enough time passed
    	if (millis() - oldTime > MINIMUM_SERVO_UPDATE_TIME)
    	{
    		//calculate new angle for servo
    		if(currentFunctionality == OPEN_MODE)
    		{
    			analogReadings = constrain(analogReadings, 40, emgSaturationValue);
    			newDegree = map(analogReadings, 40 ,emgSaturationValue, 190, 105);
    		}
    		else
    		{
    			analogReadings = constrain(analogReadings, 120, emgSaturationValue);
    			newDegree = map(analogReadings, 120 ,emgSaturationValue, 105, 190);
    		}
    
    		//check if we are in servo dead zone
    		if(abs(newDegree-oldDegrees) > GRIPPER_MINIMUM_STEP)
    		{
    			 //set new servo angle
    			 Gripper.write(newDegree);
    		}
    		oldTime = millis();
    		oldDegrees = newDegree;
    	}
    }
    
        

    Mit dieser neuen Erfahrung kannst du jetzt deine eigenen Erfindungen machen. Schreib uns einfach was du machst an info@backyardbrains.de und wir können Freunde werden!

    Wissenschaftswettbewerbideen

    • Mach′ eine Versuchsreihe von Reaktionszeitexperimenten, die mit deinem eigenen Körper und ′The Claw′ gemacht werden können. Wie unterscheiden sich die Zeiten? Hängen sie vom sensorischen Stimulus ab auf den du reagierst?
    • Mach′ eine Studie und verbinde Leute, die sportlicher sind als andere mit ′The Claw′. Was macht das für einen Unterschied? Kann die eine Testgruppe ′The Claw′ länger geschlossen halten als die andere?
    • Was für Geräte könnte man zu diesem hinzufügen? Was könnten die Limitationen sein?