Muscle Check

Aus toolbox_interaktion
Wechseln zu: Navigation, Suche

Idee

Da wir uns alle sehr für Sport interessieren, haben wir uns bei unserem Projekt dafür entschieden mit Muskelsensoren zu arbeiten. Für uns schien hier der Lerneffekt am Größten. Unser ursprünglicher Plan war es, eine Yoga-Anwendung zu erstellen, bei der überprüft wird, ob der Ausführende die Übung richtig durchführt. Allerdings wäre dies zu umfangreich geworden, da wir für mehr Körperpartien Sensoren benötigt hätten. Daher haben wir uns für ein interaktives Armdrücken entschieden, bei dem man erkennen kann, dass nicht zwangsläufig der physikalische Gewinner auch der ist, der seine Muskeln am stärksten angespannt hat.

Realisierungsversuche

Zu Beginn versuchten wir mit einem OpenEEG-Gerät (Olimex EEG-SMT) Signale in den Computer zu bekommen.

OpenEEG Olimex.jpg

MC OpenEEG.png

Aufgrund von fehlenden bzw. zu aktuellen Treibern, war es nur möglich, die EMG-Signale in einen Rechner zu bekommen. Leider war dies der Rechner von Herrn Weiss und die Versuche, die Signale in einen anderen Rechner zu bekommen, scheiterten.

Zudem waren die ursprünglichen Sensoren so störungsanfällig, das wir uns erst einmal eigene Kabel für neuere Sensoren basteln mussten. Hierfür löteten wir die Sensorendstücke an die Kabel.

Sensor geloetet2.jpg Sensoren geloetet.jpg

Da die eingehenden Signale zu starke Ausschläge hatte, schalten wir zwei Widerstände a 50kOhm dazwischen.

MC Widerstand.jpg

Wegen der Treiber-Probleme mit dem EEG-SMT Gerät entschieden wir uns für Arduino und das e-Health Kit, das uns freundlicherweise von der Medizintechnik zur Verfügung gestellt wurde.

Da wir nur ein e-Health Shield zur Verwendung haben, kann unser geplantes Projekt “Armdrücken” leider nicht verwirklicht werden, da nur eine Person angeschlossen werden kann.

Wir entschieden uns für das Messen der Muskelaktivität von zwei Personen. Diese Messung muss nacheinander erfolgen, da eben nur ein Shield zur Verfügung steht.

Hardware

Die e-Health Sensor Kit V2.0 erlaubt Arduino-Nutzer biometrische und medizinische Anwendungen auszuführen, bei denen durch Einsatz von 10 verschiedenen Sensoren Messungen am Körper ausgeführt werden können: Puls, Sauerstoff im Blut (SpO2), Luftstrom (Atmung), Körpertemperatur, Elektrokardiogramm (EKG), Blutzuckermessgerät, galvanische Hautreaktion (GSR - Schwitzen), Blutdruck (Blutdruckmessgerät), Patientenposition (Beschleunigungsmesser) und Muskel-Sensor (EMG).

EHealth-Kit.jpg

In unserem Projekt beschäftigen wir uns allerdings nur mit dem Muskel-Sensor (EMG).

MC EMG Sensoren.jpg

Wir benötigen zum E-Health-Kit noch einen Arduino. MC Arduino Logo.png Eine Arduino-Plattform ist eine aus Software- und Hardware bestehende Physical-Computing-Plattform. Die Hardware besteht aus einem einfachen I/O-Board mit einem Mikrocontroller und analogen und digitalen Ein- und Ausgängen.

MC Arduino.jpg

Aufbau

Der Arduino muss mit dem e-Health Sensor Shield wie folgt verbunden werden:

MC Aufbau Arduino 1.jpg

Das es dann letztendlich so aussieht:

MC Aufbau Arduino 3.jpg

Die EMG Sensoren müssen nun an das e-Health Sensor Shield angeschlossen werden.

EHealth-Kit.jpg

Man beachte, die Anschlüsse. G: Ground (gelber Sensor) E: End (blauer Sensor) M: Mid (magenta Sensor)

MC Sensoren.JPG

Nun müssen die Sensoren noch am Arm angeschlossen werden:

MC Arm.jpg

Aufbau Arduino.png

Realisierung

Um das Projekt in unserem Rahmen zu ermöglichen, haben wir uns für verschiedene Visualisierungen entschieden.

Bei jeder Visualisierung wird ein Code zum Einlesen der Daten aus dem e-Health Shield auf den Arduino geladen. Es ist wichtig, dass die e-Health Library importiert werden muss (eHealth.h).

Die Anwendung wird dann in Java mithilfe der Entwicklungsumgebung Processing programmiert. MC Processing.jpg

Die Bibliothek processing.serial.* wird hierfür eingesetzt. Dies ist eine Klasse für das Senden und Empfangen von Daten über das serielle Kommunikationsprotokoll. (https://processing.org/reference/libraries/serial/Serial.html)

Balkenausgabe

Arduino Code

#include <eHealth.h>
void setup() {
  Serial.begin(9600);
}
void loop() { 
  int EMG = eHealth.getEMG();
  Serial.println(EMG);
}

Arduino-Code: Balkendiagramm

Processing Code

import processing.serial.*;
// serial connection
Serial port;
String message = null;
String elements[] = null;
// arduino
int[] sensorValues = new int[6];
// graphs
int distanceX = 190;
int distanceBottom = 40;
int graphWidth = 40;
color graphColor = color(255,0,120);
PFont fontGraph;
 
void setup() {
  // size
  size(400, 400);
  // no strokes
  noStroke();
 
  // print all available serial ports
  println(Serial.list());
  // init connection to arduino
  port = new Serial(this, Serial.list()[0], 9600);
}
 
void draw() {
  // clear background
  background(0);
  // draw bars with values of analog inputs
  for(int i=0; i<1; i++){
    // color
    fill(graphColor);
    // draw bar
    rect(i*distanceX+distanceX,height-distanceBottom,graphWidth,-sensorValues[i]/2);
    // draw text
    text(sensorValues[i], i*distanceX+distanceX, height-distanceBottom+20);
  }
}
 
// serial event
void serialEvent(Serial p){
  // get message till line break (ASCII > 13)
  message = port.readStringUntil(13);
  // just if there is data
  if (message != null) {
    // try catch function because of possible garbage in received data
    try {
      elements = splitTokens(message);
      // loop through sensor values
      for (int i =0; i < elements.length && i < 6; i++ ) {
        sensorValues[i] = int(elements[i]);
      }
    }
    catch (Exception e){
    }
  }
}

Processing-Code: Balkendiagramm

Ausgabe

Die Ausgabe sieht dann wie folgt aus:

MC Balkendiagramm.PNG

Oszilloskop

Arduino Code

//Daten von Arduino an Processing ausgeben
#define ANALOG_IN 0
 
void setup() {
  //unsere Baudrate
  Serial.begin(9600); 
}
 
void loop() {
  //Analoge Daten von e-Health Shield werden gelesen
  int val = analogRead(ANALOG_IN);                                              
  Serial.write( 0xff ); //255  in ASCII    Startsynchronisation                                                  
  Serial.write( (val >> 8) & 0xff ); //Verschiebung um 8 bit nach rechts und Maskierung des niederwertigen Bytes                                     
  Serial.write( val & 0xff );  //logische Undverkn¸pfung der niederwertigen Bytes
}

Arduino-Code: Oszilloskop

Processing Code

import processing.serial.*;
 
Serial port; // Erstellet Seriellen Port
int val; // Daten vom Arduino
int[] values;
float zoom; // Ausschnitt des Arrays der angezeigt wird
 
void setup()
{
size(800, 480);
// initialisiert Seriellen Port mit unserer Baudrate
port = new Serial(this, Serial.list()[0], 9600);
values = new int[width]; //Array so grofl wie Fenster (Ein wert f¸r jeden Pixel)
zoom = 3.0f; // wird Angepasst (n‰her ran, dadurch wirkt es schneller)
smooth(); // antialising
}
 
int getY(int val) {//y Wert unseres Beginnpunkts
  return (int)(height - val / 1023.0f * (height - 1)); //normierung auf einen Wertebereich 0 bis 1
}
 
int getValue() {
int value = -1;
while (port.available() >= 3) {
  if (port.read() == 0xff) {
    value = (port.read() << 8) | (port.read());
    }
  }
  return value;
}
 
void pushValue(int value) {
  for (int i=0; i<width-1; i++)
    values[i] = values[i+1];
    values[width-1] = value;
}
 
void drawLines() {
stroke(255, 0, 160);
int displayWidth = (int) (width / zoom);
int k = values.length - displayWidth;
int x0 = 0;
int y0 = getY(values[k]);
for (int i=1; i<displayWidth; i++) {
  k++;
  int x1 = (int) (i * (width-1) / (displayWidth-1));
  int y1 = getY(values[k]);
  line(x0, y0, x1, y1);
  x0 = x1;
  y0 = y1;
  }
}
 
void drawGrid() {
  stroke(0, 200, 0);
  line(0, height/2, width, height/2);
}
 
void keyReleased() {
  switch (key) {
    case '+':
      zoom *= 2.0f;
      println(zoom);
      if ( (int) (width / zoom) <= 1 )
        zoom /= 2.0f;
        break;
    case '-':
      zoom /= 2.0f;
       if (zoom < 1.0f)
         zoom *= 2.0f;
         break;
  }
}
 
void draw() {
background(255);
drawGrid();
val = getValue();
if (val != -1) {
  pushValue(val);
  }
drawLines();
}

Processing-Code: Oszilloskop

Ausgabe

Bei Ruhe der Muskeln:

MC Oszi beiRuhe.PNG

Bei Anspannung der Muskeln:

MC Oszi beiAnspannung.PNG

Kreisausgabe

Arduino Code

#include <eHealth.h>
void setup() {
  Serial.begin(9600);
}
void loop() { 
  int EMG = eHealth.getEMG(); 
  Serial.println(EMG);
}

Arduino-Code: Kreise

Processing Code

import processing.serial.*;
Serial port; // Erstellet Seriellen Port
int val; // Daten vom Arduino
int[] values;
float zoom; // Ausschnitt des Arrays der angezeigt wird
 
void setup() {
size(800, 480);
// initialisiert Seriellen Port mit unserer Baudrate
port = new Serial(this, Serial.list()[0], 9600);
values = new int[width]; //Array so groß wie Fenster (Ein wert für jeden Pixel)
zoom = 3.0f; // wird Angepasst (näher ran, dadurch wirkt es schneller)
smooth(); // antialising
}
 
int getY(int val) {//y Wert unseres Beginnpunkts
return (int)(height - val / 1023.0f * (height - 1)); //normierung auf einen Wertebereich 0 bis 1
}
 
int getValue() {
int value = -1;
while (port.available() >= 3) {
  if (port.read() == 0xff) {
    value = (port.read() << 8) | (port.read());
    }
  }
  return value;
}
 
void pushValue(int value) {
for (int i=0; i<width-1; i++)
  values[i] = values[i+1];
  values[width-1] = value;
  }
 
void drawLines() {
stroke(255, 0, 160);
int displayWidth = (int) (width / zoom);
int k = values.length - displayWidth;
int x0 = 0;
int y0 = getY(values[k]);
for (int i=1; i<displayWidth; i++) {
  k++;
  int x1 = (int) (i * (width-1) / (displayWidth-1));
  int y1 = getY(values[k]);
  line(x0, y0, x1, y1);
  x0 = x1;
  y0 = y1;
  }
}
 
void drawGrid() {
stroke(0, 200, 0);
line(0, height/2, width, height/2);
}
 
void keyReleased() {
switch (key) {
case '+':
  zoom *= 2.0f;
  println(zoom);
  if ( (int) (width / zoom) <= 1 )
    zoom /= 2.0f;
    break;
case '-':
  zoom /= 2.0f;
  if (zoom < 1.0f)
    zoom *= 2.0f;
    break;
    }
}
 
void draw() {
background(255);
drawGrid();
val = getValue();
if (val != -1) {
  pushValue(val);
  }
drawLines();
}

Processing-Code: Kreise

Ausgabe

Bei Ruhe der Muskeln:

Kreise1.PNG

Bei Anspannung der Muskeln:

Kreise2.PNG

Erfolge und Erlebnisse

Während unserer Arbeit mit den Sensoren, sowohl OpenEEG als auch eHealth-Kit, stellten wir fest, dass diese sehr empfindlich auf Umwelteinflüsse reagieren. Sei dies die “Strahlung” des PCs oder des Arduinos selbst. Wir mussten in unserem Aufbau beachten, dass wir gewisse Abstände einhalten, um auch ein einigermaßen reines Ergebnis zu erhalten.

Nächste Schritte

Als nächstes würden wir den Code umschreiben, sodass wir die Werte von beiden Personen vergleichen könnten. Dies geschieht mit einem Array und dem Vergleichen der Werte nach und nach.

Fazit

Zur Zeit werden Fitness-Apps bzw. Tracking-Armbänder und Wearables immer beliebter. Wir vermuten, dass Sensoren im Allgemeinen, speziell in der nahen Zukunft, eine immer wichtigere Rolle im alltäglichen Leben und auch im Sportbereich spielen werden.