Auf dieser Seite können zusätzliche Materialien der Dokumentation des Themas „Konzeption und Herstellung einer elektronischen Hand- und Unterarmprothese, die durch 3D-Druckverfahren hergestellt und drahtlos mit einem externen Handschuh mit Fingerbeugungssensoren gesteuert wird auf Basis des ESP32 Mikrocontrollers“ heruntergeladen oder eingesehen werden.
Bilder Galerie
Quellenverzeichnis der Dokumentation:
- https://www.amazon.de/gp/bestsellers/digital-text/611274031/ref=zg_bs (Stand: 7.4.2021)
- https://www.youtube.com/watch?v=fY-TsxkxYwA (Stand: 7.4.2021)
- http://inmoov.fr/ (Stand 10.8.2020)
- https://de.wikipedia.org/wiki/Arduino_(Plattform) (Stand 7.4.2021)
- Von Clic17 – Eigenes Werk, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=34226017 (Stand 7.4.2021)
- https://de.wikipedia.org/wiki/InMoov (Stand 10.8.2020)
- Eigenes Werk nach CC BY-SA 4.0 von Philipp Lemke vom 15.10.2018
- http://inmoov.fr/project/ (Stand 7.4.2021)
- https://creativecommons.org/licenses/by-nc/3.0/deed.de (Stand 7.4.2021)
- https://www.amazon.de/3D-Druck-Handbuch-f%C3%BCr-junge-Einsteiger-ebook/dp/B08848681V (Stand 8.4.2021)
- „3D-Druck Handbuch für junge Einsteiger: 3D-Druck mit Ultimaker Cura für SchülerInnen und LehrerInnen“ von Philipp Lemke von 2020 [10]
- https://www.az-delivery.de/products/az-delivery-servo-mg995?variant=12236815138912 (Stand 10.4.2021)
- Battery Shield, Modell digital nachgebaut und gerendert. Software Fusion360
- https://www.amazon.de/gp/product/B0822Q4VS4 (Stand 10.4.2021)
- VTC6 Akkus, Modell digital nachgebaut und gerendert. Software Fusion360
- https://www.amazon.de/gp/product/B087R9XXM8 (Stand 10.4.2021)
- Datenblatt: https://cdn.shopify.com/s/files/1/1509/1638/files/ESP-32_DevKit_C_V4_Datenblatt_AZ-Delivery_Vertriebs_GmbH_24ec770f-c65e-4bd3-92c9-cd64b4d070b8.pdf?v=1615364587 (Stand 10.4.2021)
- https://www.az-delivery.de/products/esp-32-dev-kit-c-v4 (Stand 10.4.2021)
- https://www.amazon.de/gp/product/B085WJCRX8 (Stand 10.4.2021)
- https://www.amazon.de/gp/product/B0754MNQPN (Stand 10.4.2021)
- https://www.amazon.de/gp/product/B07HVND5DL (Stand 10.10.2020)
- https://de.wikipedia.org/wiki/Kohlenstofffaser (Stand 10.4.2021)
- https://www.amazon.de/gp/product/B086RVJ36S (Stand 10.4.2021)
- Eigenes Werk nach CC BY-SA 4.0 von Philipp Lemke vom 10.04.2021
- https://www.sparkfun.com/products/8606 (Stand 10.4.2021)
- https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/FLEXSENSORREVA1.pdf (Stand 10.4.2021)
- https://heltec.org/project/wifi-kit-32/ (Stand 11.4.2021)
- https://www.amazon.de/gp/product/B076P8GRWV (Stand 11.4.2021)
- Datenblatt http://resource.heltec.cn/download/WiFi_Kit_32/WIFI_Kit_32_pinoutDiagram_V2.pdf (Stand 11.4.2021)
- https://www.amazon.de/gp/product/B07YWLCTLK (Stand 14.4.2021)
- https://www.amazon.de/gp/product/B087LTZW61 (Stand 14.4.2021)
- https://www.amazon.de/gp/product/B07MC4G4S8 (Stand 14.4.2021)
- https://www.amazon.de/gp/product/B07NDBPYBR (Stand 14.4.2021)
- https://www.amazon.de/gp/product/B07BHRGJLJ (Stand 14.4.2021)
- https://www.amazon.de/gp/product/B083DC38TZ (Stand 14.4.2021)
- https://www.amazon.de/gp/product/B07TT69PPV (Stand 14.4.2021)
- https://de.wikipedia.org/wiki/CAD (Stand 14.4.2021)
- https://grabcad.com/library/lm2596-dc-to-dc-buck-converter-module-1 (Stand 14.4.2021)
- https://fritzing.org/ (Stand 14.4.2021)
- https://www.amazon.de/Artillery-Sidewinder-Neuestes-vormontiert-300x300x400mm/dp/B089NFVBGG (Stand 14.4.2021)
- https://www.amazon.de/dp/B07X37DT9M (Stand 15.4.2021)
- https://www.arduino.cc/en/software (Stand 15.4.2021)
Programmierung des Handschuhs:
//ESP32 MAC-Adresse Prothese: 3C:61:05:3F:B9:B8
//ESP32 MAC-Adresse Handschuh: C4:4F:33:76:E6:8D
//Bibliotheken werden hinzugefügt
#include "Arduino.h"
#include "heltec.h"
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
//ESP32 MAC-Adresse Prothese: 3C:61:05:3F:B9:B8
uint8_t broadcastAddress[] = {0x3C, 0x61, 0x05, 0x3F, 0xB9, 0xB8};
//Pins für die Beugungssensoren werden definiert
const int F1_Pin = 36; //Daumen
const int F2_Pin = 37; //Zeigefinger
const int F3_Pin = 38; //Mittelfinger
const int F4_Pin = 39; //Ringfinger
const int F5_Pin = 34; //kleiner Finger
// 5-Dimensionales Array um später konvertierte Daten zu speichern
int converted_flex[5];
// Variable, um abzuspeichern, ob das Senden erfolgreich war
String success;
//Struktur für zu sendende Daten (Muss gleich mit Empfänger sein)
typedef struct struct_message {
int send_F1;
int send_F2;
int send_F3;
int send_F4;
int send_F5;
} struct_message;
// Erstellt ein struct_message Objekt, um ausgehende Daten zu //speichern
struct_message datatosend;
// Callback-Funktion, wenn Daten gesendet werden
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.println();
if (status ==0){
success = "Delivery Success :)";
}
else{
success = "Delivery Fail :(";
}
}
void setup() {
//Serial Monitor wird gestartet (Nur für Debugging)
Serial.begin(115200);
//WiFi wird im Modus WIFI_STA gestartet
WiFi.mode(WIFI_STA);
//Display wird initialisiert
Heltec.begin(true /*DisplayEnable Enable*/, false /*LoRa Disable*/, true /*Serial Enable*/);
Heltec.display->setContrast(255);
Heltec.display->clear();
Heltec.display->drawString(0, 0, "Handschuh gestartet \n Verbindung wird \n hergestellt.");
Heltec.display->display();
//ESP-NOW wird initialisiert
if (esp_now_init() != ESP_OK) {
Heltec.display->drawString(0, 0, "Die Verbindung mit \n der Prothese konnte \n nicht hergestellt \n werden!");
Heltec.display->display();
return;
}
//Registrierung einer Callback-Funktion, die aufgerufen wird, wenn Daten gesendet werden
esp_now_register_send_cb(OnDataSent);
//Peer wird registiert
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
//Peer wird hinzugefügt
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
Heltec.display->drawString(0, 0, "Handschuh initialisiert \n und
Verbindung \n hergestellt.");
Heltec.display->display();
//Pins für Beugungssensoren werden initialisiert
pinMode(F1_Pin, INPUT);
pinMode(F2_Pin, INPUT);
pinMode(F3_Pin, INPUT);
pinMode(F4_Pin, INPUT);
pinMode(F5_Pin, INPUT);
}
void loop() {
Heltec.display->clear();
//Daten der Beugungssensoren werden gelesen und in flex_read_NUMMER gespeichert
int flex_read_1 = analogRead(F1_Pin);
int flex_read_2 = analogRead(F2_Pin);
int flex_read_3 = analogRead(F3_Pin);
int flex_read_4 = analogRead(F4_Pin);
int flex_read_5 = analogRead(F5_Pin);
//Rohdaten des Bewegungssensors werden in grobe Werte von 0 bis 100 umgewandelt
converted_flex[0] = 100 - ((flex_read_1 - 1050) / 5.5);
converted_flex[1] = 100 - ((flex_read_2 - 1000) / 6);
converted_flex[2] = 100 - ((flex_read_3 - 800) / 8.5);
converted_flex[3] = 100 - ((flex_read_4 - 1100) / 6.5);
converted_flex[4] = 100 - ((flex_read_5 - 800) / 9);
//Da Werte unter 0 und über 100 enstehen können, werden sie bereinigt
for (int i=0; i <= 5; i++){
if(converted_flex[i] < 0){
converted_flex[i] = 0;
}
if(converted_flex[i] > 100){
converted_flex[i] = 100;
}
}
//Zu sendende Daten werden in datatosend verpackt
datatosend.send_F1 = converted_flex[0];
datatosend.send_F2 = converted_flex[1];
datatosend.send_F3 = converted_flex[2];
datatosend.send_F4 = converted_flex[3];
datatosend.send_F5 = converted_flex[4];
//Sende Daten
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)
&datatosend, sizeof(datatosend));
//Für Debugging
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
//Ausgabe der Werte am Display
Heltec.display->drawString(0, 0, "Daumen: " +
String(converted_flex[0])+ "%\n" + "Zeigefinger: " +
String(converted_flex[1])+ "%\n" + "Mittelfinger: " +
String(converted_flex[2])+ "%\n" +"Ringfinger: " +
String(converted_flex[3])+ "%\n" +"kleiner Finger: " +
String(converted_flex[4])+ "%");
Heltec.display->display();
//Daten werden im Intervall von 50 ms gelesen, umgewandelt und gesendet. Das Display wird somit auch jeden 50ms aktualisiert.
delay(50);
}
Programmierung der Prothese
//ESP32 MAC-Adresse Prothese (Empfänger): 3C:61:05:3F:B9:B8
//ESP32 MAC-Adresse Handschuh (Sender): C4:4F:33:76:E6:8D
//Einfügen der Bibliotheken
#include <esp_now.h>
#include <WiFi.h>
#include <ESP32Servo.h>
#include <Wire.h>
//Erstellen von Servo Objekten. Servo1 für den Daumen usw.
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
//minimale und maximale Pulsweitenlänge der Servos //(Datenblatt)
int minUs = 500;
int maxUs = 2500;
//Pins der Servos werden festgelegt
int servo1Pin = 12;
int servo2Pin = 14;
int servo3Pin = 27;
int servo4Pin = 25;
int servo5Pin = 26;
//ESP32 wird in pwm Zustand versetzt
// PWM (Pulsweitenmodulation) wird für die Ansteuerung der // Servomotoren benötigt.
ESP32PWM pwm;
//ESP32 MAC-Adresse Handschuh: C4:4F:33:76:E6:8D
uint8_t broadcastAddress[] = {0xC4, 0x4F, 0x33, 0x76, 0xE6, 0x8D};
// 5-Dimensionales Array um einkommende Daten zu Speichern
int converted_flex[5];
//Struktur für einkommende Daten (Muss gleich mit Sender sein)
typedef struct struct_message {
int send_F1;
int send_F2;
int send_F3;
int send_F4;
int send_F5;
} struct_message;
// Erstellt ein struct_message Objekt um einkommende Daten zu speichern
struct_message incomingReadings;
// Callback-Funktion wenn Daten empfangen werden
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
//Eingehende Daten warden mit prozentual mit den Werten der // Servos im geöffneten Zustand verrechnet und im converted_flex Array gespeichert
converted_flex[0] = incomingReadings.send_F1*0.6;
converted_flex[1] = incomingReadings.send_F2*0.9;
converted_flex[2] = incomingReadings.send_F3*0.9;
converted_flex[3] = incomingReadings.send_F4*1.0;
converted_flex[4] = incomingReadings.send_F5*0.8;
}
void setup() {
//Array auf Ausgangsposition 0 stellen
converted_flex[0] = 0;
converted_flex[1] = 0;
converted_flex[2] = 0;
converted_flex[3] = 0;
converted_flex[4] = 0;
//Alle Timer werden zugewiesen, um bestmögliche
// Synchronisation zu gewährleisten
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
//Frequenz des Servos wird definiert (50hz)
servo1.setPeriodHertz(50);
servo2.setPeriodHertz(50);
servo3.setPeriodHertz(50);
servo4.setPeriodHertz(50);
servo5.setPeriodHertz(50);
//Servos werden eingebunden
servo1.attach(servo1Pin, minUs, maxUs);
servo2.attach(servo2Pin, minUs, maxUs);
servo3.attach(servo3Pin, minUs, maxUs);
servo4.attach(servo4Pin, minUs, maxUs);
servo5.attach(servo5Pin, minUs, maxUs);
//Serial Monitor wird gestartet (Nur für Debugging)
Serial.begin(115200);
//WiFi wird im Modus WIFI_STA gestartet
WiFi.mode(WIFI_STA);
//ESP-NOW wird initialisiert
if (esp_now_init() != ESP_OK) {
Serial.println("Fehler beim initialisieren von ESP-NOW");
return;
}
//Peer wird registiert
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
//Peer wird hinzugefügt
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
//Registrierung einer Callback-Funktion, die aufgerufen wird wenn Daten empfangen werden
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
//Ausführen der Methode updatefingers()
updatefingers();
//Daten werden im Intervall von 50 ms empfangen und die Servos werden auf den neuen Wert aktualisiert.
delay(50);
}
void updatefingers(){
//Servos werden auf den übertragenen Wert gesetzt
servo1.write(converted_flex[0]);
servo2.write(converted_flex[1]);
servo3.write(converted_flex[2]);
servo4.write(converted_flex[3]);
servo5.write(converted_flex[4]);
//Servowerte warden in über die serielle Schnittstelle an den Computer übertragen (Für Debugging)
Serial.println("Daumen: " + String(converted_flex[0])+ "%\n" + "Zeigefinger: " + String(converted_flex[1])+ "%\n" + "Mittelfinger: " + String(converted_flex[2])+ "%\n" +"Ringfinger: " + String(converted_flex[3])+ "%\n" +"kleiner Finger: " + String(converted_flex[4])+ "%");
Serial.println();
}
Achtung: Zeilennummern im Code entsprechen nicht den Zeilennummern des Codes in der Dokumentation. Der Code ist jedoch identisch.