Team Dreamers

From Hackteria Wiki
Jump to: navigation, search

Team

Team Dreamers

Teammitglieder


Das Team Dreamers setzt sich aus den Mitgliedern Eric Balmer, Patrick Bütler und Philipp Wyrsch zusammen. Wir gründeten unser Team im Rahmen der Blockwoche DIY - Medizintechnik HS2023. Durch unsere gemeinsamen Interessen und die unterschiedlichen Erfahrungen, oder noch zu machenden Erfahrungen, fördern wir ein optimales Lernklima. Die Inspiration für die Versuche und die Projekte erfolgte gegenseitig und wir konnten diese gemeinsam weiter entwickeln. Sie ist eine mögliche Investorin in zukünftige Projekte. Oder auch nicht.

Einleitung

Kurzbeschrieb MedTech DIY

Herzlich willkommen auf der offiziellen Webseite des Teams Dreamers. Das Projektteam Dreamers entstand während der Blockwoche Medizintechnik DIY, die vom 12. bis 17. Februar 2024 im FabLab der Hochschule Luzern Technik & Architektur stattfand. Das Hauptziel dieser Blockwoche war es, Studierenden die Verbindung zwischen Technik und Medizin näherzubringen, indem sie selbst Prototypen für medizinische Geräte entwarfen und testeten. Während der Veranstaltung gaben die Leiter der Blockwoche regelmässig Inputs, um den Teams bei der Annäherung an ihre Ziele zu unterstützen. Diese Inputs behandelten verschiedene Themen, darunter das Löten, die Anwendung von Arduino und die Funktionsweise von 3D-Druckern und Lasercuttern. Am Ende der Woche präsentierten die Teams ihre Prototypen in einer Abschlusspräsentation vor den anderen Gruppen.

Location & Zeitplan

FabLab ist eine Abkürzung für Fabrication Laboratory und repräsentiert eine offene Werkstatt. Das Hauptziel eines FabLabs ist es, Privatpersonen den Zugang zu Produktionsmitteln und modernen industriellen Fertigungsverfahren für die Herstellung von Einzelstücken zu ermöglichen. Es handelt sich um eine Art Prototyping-Werkstatt, die in verschiedenen Ländern weltweit vertreten ist. Das FabLab Luzern war das Pionier-FabLab in der Schweiz, und mittlerweile gibt es auch solche Einrichtungen in Städten wie Zürich, Bern, Basel und anderen. Zu den typischen Geräten in einem FabLab zählen 3D-Drucker, Laser-Cutter und CNC-Maschinen.

Location fablab.jpg

WeekgridMedTech2023 1 1.jpg

Inputs

Einführung DIY

DIY steht für "Do It Yourself" und bedeutet "Selbermachen". Es bezieht sich auf die eigenständige Erstellung, Reparatur oder Verbesserung von Dingen ohne professionelle Hilfe. DIY-Projekte umfassen handwerkliche Arbeiten, Heimwerken, kreative Projekte und mehr. Der Trend hat durch Online-Plattformen und soziale Medien an Beliebtheit gewonnen, da Menschen ihre Ideen und Anleitungen teilen. DIY fördert Eigeninitiative, Kreativität und die Entwicklung persönlicher Fähigkeiten.

Wiki Nutzung

Wir lernten die Hackteria Seite kennen, welche auf der Software MediaWiki basiert und erstellten unser Login. Während des Inputs erwarben wir Kenntnisse im Umgang mit MediaWiki. Hierzu gehörten das Erstellen von Titeln, das Einbinden von Verlinkungen, das Hinzufügen von Bildern sowie das Erstellen von Seiten.


Einführung Arduino

Arduino ist eine Elektronikplattform mit offenem Quellcode, die auf benutzerfreundlicher Hardware und Software basiert. Sie wurde für Künstler, Designer, Hobbyisten und jeden entwickelt, der sich für die Erstellung interaktiver Objekte oder Umgebungen interessiert.

Im Zentrum von Arduino steht ein physisches programmierbares Schaltkreis-Board, oft als Mikrocontroller bezeichnet, sowie eine Software, die als Integrated Development Environment (IDE) auf Ihrem Computer läuft. Diese Software dient zum Schreiben und Hochladen von Computercode auf die physische Platine.

Die Zugänglichkeit ist eines der Hauptmerkmale, die Arduino so beliebt gemacht haben. Die Einstiegshürden für das Erlernen der Grundlagen sind niedrig, und eine große Gemeinschaft von Menschen ist bereit, ihr Wissen und ihre Ideen zu teilen. Außerdem ist die Arduino-Hardware flexibel und relativ kostengünstig, was es möglich macht, Projekte mit einer Vielzahl von Sensoren und Aktoren zu realisieren.

Die Programmiersprache von Arduino basiert auf einer vereinfachten Version von C/C++, was das Erlernen der Grundlagen des Programmierens relativ einfach macht. Ein weiterer Vorteil der Arduino-Plattform sind die zahlreichen verfügbaren Erweiterungsboards, sogenannte Shields, die das Anbinden zusätzlicher Hardware wie Motoren, GPS-Empfänger, Ethernet-Ports und mehr ermöglichen, ohne dass umfangreiche Elektronikkenntnisse erforderlich sind.

Ob Sie eine automatische Bewässerungsanlage für Ihre Pflanzen, einen persönlichen Wettermonitor, eine interaktive Kunstinstallation oder einen Prototypen für ein neues Produkt erstellen möchten, Arduino bietet eine zugängliche und vielseitige Plattform, um Ihre Ideen zum Leben zu erwecken.

File:Leitfaden-für-das-Arbeiten-mit-dem-Arduino.pdf

3D Drucken

Ultimaker 3

Der 3D-Druck, auch bekannt unter den Bezeichnungen Additive Fertigung, Additive Manufacturing, Generative Fertigung oder Rapid Technologien, ist eine umfassende Bezeichnung für alle Fertigungsverfahren, bei denen Material Schicht für Schicht aufgetragen und so dreidimensionale Gegenstände erzeugt werden. Dabei erfolgt der schichtweise Aufbau computergesteuert aus einem oder mehreren flüssigen oder festen Werkstoffen nach vorgegebenen Maßen und Formen. Beim Aufbau finden physikalische oder chemische Härtungs- oder Schmelzprozesse statt. Typische Werkstoffe für das 3D-Drucken sind Kunststoffe, Kunstharze, Keramiken und Metalle.


3D-Drucker werden in der Industrie, im Modellbau und der Forschung eingesetzt zur schnellen und kostengünstigen Fertigung von Modellen, Mustern, Prototypen, Werkzeugen und Endprodukten. Daneben gibt es Anwendungen im Heim- und Unterhaltungsbereich sowie in der Kunst.


Auch wir haben in dieser Woche den 3D-Drucker verwendet um kostengünstig und schnell Prototypen zu bauen. Da wir bereits gute Grundkenntnisse im 3D-Druck hatten und die Unterstützung durchs FabLab gross war, hatten wir wenig Probleme unserer Prototypen herzustellen. Das einzige was uns Probleme bereitet hat, war die Masshaltigkeit der gedruckten teile. Da jeder Drucker etwas andere Eigenschaften hat, mussten wir uns zuerst mit den Druckern vertraut machen. Um sicher zu gehen das man die gedruckten Teile ohne Nachbearbeitung verwenden kann, sollte man einen Millimeter vom exakten Mass Zugabe lassen.

https://fablab-luzern.ch/wp-content/uploads/2020/03/CURA-Anleitung-A4-2_0.pdf

LaserCutter

Laser-Cutter

Mit Hilfe des Lasercuters haben wir das Gehäuse unseres Infusionsalligators aus MDF-Platten gelasert. Dies funktionierte sehr gut und ohne weiteren Komplikationen. Mit dem Laser-Cutter AKJ-6090 von Acctek, welcher im FabLab steht, kann man Flächen von 900x600 mm bearbeiten. Der 100 Watt Laser kann diverse Materialien Gravieren und ausschneiden. Die Materialien reichen von Plexiglas über Kunststoffe und Holz bis hin zu Karton, Leder oder Textilstoffe. Es kann Acrylglas bis zu einer Dicke von ca. 8 mm und Holz bis zu einer Dicke von 6 mm geschnitten werden. Aluminium kann graviert werden, jedoch nicht geschnitten.

https://fablab-luzern.ch/wp-content/uploads/2020/02/LASER-Anleitung-A4-2_0.pdf

Skill-Share Sessions

In Skill-Share Sessions bringen die Teilnehmer oft ihre eigenen Expertisen ein und können gleichzeitig von den Erfahrungen anderer profitieren. Der Fokus liegt darauf, Wissen und Kompetenzen innerhalb einer Gemeinschaft zu verbreiten und den Teilnehmern die Möglichkeit zu geben, voneinander zu lernen.

Beschreibungen

Neurobio

Das Team Coconut Cowboys gab uns eine Erklärung darüber, wie die Neurobiologie als ein Bereich der Biologie fungiert, der sich auf die Struktur und Funktion des Nervensystems konzentriert. Dabei wurde uns verdeutlicht, dass die Erforschung von Neuronen, Synapsen und anderen neurologischen Elementen dazu dient, die Grundlagen von Verhalten, Denken und mentalen Prozessen zu verstehen.

Seilbrücken bauen

In unserer Skill-Share-Session widmeten wir uns dem Thema Seilbrückenbau. Das Errichten von Seilbrücken ist eine beliebte Aktivität in Pfadfinder- & Jubla-Gruppen. In dieser kreativen Übung werden die Personen dazu ermutigt, Teamarbeit und praktische Fähigkeiten zu entwickeln, indem sie gemeinsam Seilbrücken konstruieren. Dabei verwenden sie Knotentechniken, Seile und gegebenenfalls andere Materialien, um sichere Überquerungsmöglichkeiten zu schaffen. Für eine Seilbrücke muss man folgende Knoten beherrschen: für das eine Ende den Wickelknoten ODER den Maurerknoten und für das andere Ende den Spanner UND den Schifferknoten.

Seilbrücke.jpg

Jassen

Jassen ist ein populäres Kartenspiel in der Schweiz, das mit einem speziellen 36-Karten-Set gespielt wird. Ziel des Spiels ist es, durch geschicktes Ausspielen der Karten Punkte zu sammeln, wobei Trumpf und verschiedene Farbstiche eine entscheidende Rolle spielen. Das Team Bastler erklärte uns die wichtigsten Regeln des Spiels und wir übten während des Spielens verschiedene Strategien umzusetzen.

Reflektionen

Die Skill-Share-Session war äußerst spannend, da sie ungewöhnliche Inhalte wie das Bauen von Seilbrücken behandelte. Die Tatsache, dass die Session von Schüler zu Schüler stattfand, verlieh dem Erfahrungsaustausch eine besondere Dynamik. Aufgrund der praktischen Ansätzen und den kreativen Herangehensweisen waren die Sessions besonders interessant.

Hack 0

1 LED blinken

Dieses Programm ist vorgefertigt und ein Beispiel von Arduino selbst. Dieser Versuch ist der Beginn der Versuchsreihe mit den LEDs. Es soll ein LED für eine Sekunde leuchten und dann für eine weitere Sekunde nicht leuchten.

Probleme

Anfänglich wurde mit einem rotem LED experimentiert. Trotz Programmierung, dass das LED eine Sekunde leuchten, eine Sekunde nicht leuchten und so weiter sollte, hat die Leucht-Diode nur geblinkt bei jedem Input vom Programm. Also beim Einschalten einmal geblinkt und wieder beim Ausschalten hat es wieder einmal geblinkt. Vermutungen lagen nahe, dass das LED beschädigt sein könnte. Durch das Ersetzen des LEDs durch ein Neues funktionierte der Code einwandfrei.

CODE


/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                      // wait for a second
}

2 LED leuchten

20240212 160159.gif

Mit dieser Konfiguration wechselt das Programm vom einen LED zum Anderen. So ist abwechslungsweise immer ein LED am leuchten.

CODE


void setup() {
   pinMode(3, OUTPUT); // LED an Pin 3 
   pinMode(4, OUTPUT); // LED an Pin 4 
}

void loop() {
   digitalWrite(4, HIGH);
   digitalWrite(3, LOW);
   delay(1000);  
   digitalWrite(3, HIGH);
   digitalWrite(4, LOW);
   delay(1000);

}

8 LED leuchten

EigthLED.gif

Wie im GIF ersichtlich kann man mit dem Potentiometer die Helligkeit der LEDs steuern. Mögliche Erweiterung wäre, die Schnelligkeit der LED-Wechsel mit einem weiteren Potentiometer zu steuern. Dies erscheint aber als aufwendig, für nur diese Funktion.

CODE


void setup() {
   pinMode(1, OUTPUT); // LED an Pin 1 
   pinMode(2, OUTPUT); // LED an Pin 2
   pinMode(3, OUTPUT); // LED an Pin 3 
   pinMode(4, OUTPUT); // LED an Pin 4
   pinMode(5, OUTPUT); // LED an Pin 5 
   pinMode(5, OUTPUT); // LED an Pin 6
   pinMode(6, OUTPUT); // LED an Pin 7 
   pinMode(7, OUTPUT); // LED an Pin 8

}

void loop() {
   digitalWrite(1, HIGH);
   digitalWrite(8, LOW);
   delay(100);  
   digitalWrite(2, HIGH);
   digitalWrite(1, LOW);
   delay(100);
   digitalWrite(3, HIGH);
   digitalWrite(2, LOW);
   delay(100);
   digitalWrite(4, HIGH);
   digitalWrite(3, LOW);
   delay(100);
   digitalWrite(5, HIGH);
   digitalWrite(4, LOW);
   delay(100);
   digitalWrite(6, HIGH);
   digitalWrite(5, LOW);
   delay(100);
   digitalWrite(7, HIGH);
   digitalWrite(6, LOW);
   delay(100);
   digitalWrite(8, HIGH);
   digitalWrite(7, LOW);
   delay(100);
}

Arduino Übung 04 - Ultraschallsensor

File:Leitfaden-für-das-Arbeiten-mit-dem-Arduino.pdf

Aufgabe

Erstelle ein Sketch für einen Arduino UNO, um ein Distanzsensor eines Autos auszulesen und eine Warnung auszugeben. Der Ultraschallsensor soll ausgelesen und die erhaltene Distanz soll in Zentimeter im Serial Monitor ausgegeben werden. Benutze dafür die folgenden Zuordnungen:

Zuordnungen.png

Projekt Hilfestellung:

1. Welche Komponenten wirst du brauchen?

  • Arduino Uno
  • Ultraschall Sensor HC-SR04
  • Breadboard
  • viele Kabel
  • (Code)

2. Wie sind diese Komponenten miteinander verbunden? & 3. Wie könnte eine solche Schaltung aussehen?

Ultraschallsensor-HC-SR04

SupersonicSchema.png

4. Welche Variablen und Konstanten könnten nützlich sein?

  • Zuteilung Trigger und Echo
  • Baudrate
  • Intial Dauer & Abstand
  • Zeit für Messung, Ton

CODE

int trigger = 2; //Trigger auf Pin 2
int echo = 3; //Echo auf Pin 3
long dauer = 0; //Zeit des Echos
long entfernung = 0; //Entfernung in cm

void setup() {
  Serial.begin (9600); //Serielle kommunikation starten, damit man sich später die Werte am serial monitor ansehen kann.
  pinMode(trigger, OUTPUT); // Ausgang um ein Signal zu senden
  pinMode(echo, INPUT); // Eingang damit wir Echo empfangen können
}

void loop() {
  digitalWrite(trigger, LOW); //Hier nimmt man die Spannung für kurze Zeit vom Trigger-Pin, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
  delay(5); //Dauer: 5 Millisekunden
  digitalWrite(trigger, HIGH); //Jetzt sendet man eine Ultraschallwelle los.
  delay(10); //Dieser „Ton“ erklingt für 10 Millisekunden.
  digitalWrite(trigger, LOW);//Dann wird der „Ton“ abgeschaltet.
  dauer = pulseIn(echo, HIGH); //Mit dem Befehl „pulseIn“ zählt der Mikrokontroller die Zeit in Mikrosekunden, bis der kein Schall mehr zum Ultraschallsensor zurückkehrt.
  entfernung = (dauer/2) * 0.03432; //Nun berechnet man die Entfernung in Zentimetern. Man teilt zunächst die Zeit durch zwei (Weil man ja nur eine Strecke berechnen möchte und nicht die Strecke hin- und zurück). Den Wert multipliziert man mit der Schallgeschwindigkeit in der Einheit Zentimeter/Mikrosekunde und erhält dann den Wert in Zentimetern.
  if (entfernung >= 10 || entfernung <= 2) //Wenn die gemessene Entfernung über 10cm oder unter 2cm liegt,…
  {
    Serial.println("Kein Messwert"); //dann soll der serial monitor ausgeben „Kein Messwert“, weil Messwerte in diesen Bereichen falsch oder ungenau sind.
  }
  else if (entfernung >= 2 && entfernung <=5) //Wenn die gemessene Entfernung über 2cm und unter 5cm liegt,...
  {
    Serial.println("Achtung Stopp"); //dann soll der Serial Monitor "Schtung Stopp" ausgeben
  }
  else //  Ansonsten…
  {
    Serial.print("Okey: "); //Der Srrial Monitor gibt "Okey: " aus
    Serial.print(entfernung); //…soll der Wert der Entfernung an den serial monitor hier ausgegeben werden.
    Serial.println(" cm"); // Hinter dem Wert der Entfernung soll auch am Serial Monitor die Einheit "cm" angegeben werden.
  }
  delay(1000); //Das delay von einer Sekunde sorgt in ca. jeder neuen Sekunde für einen neuen Messwert.
}

Hilfestellung

https://github.com/CoderDojoPotsdam/DistanceAlarm

Arduino Hack - LED mit Potentiometer

Das LED leuchtet

Vorgehen:

- LED mit GND & Digital PIN verbinden

- Potentiometer mit GND & 5V & A1 verbinden

Schema lasthack.png



CODE

const int LED = 9; //Output für LED
const int Potentiometer = A1; //Inputmessung
int Widerstand = 0; //Wert für AnalogRead
int Helligkeit = 0; //Wert für AnalogWrite

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(LED, OUTPUT);
pinMode(Potentiometer, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
int Widerstand = analogRead(Potentiometer); //Der Input kann Werte von 0 bis 1023 annehmen
int Helligkeit = Widerstand/4; //Der Output kann nur Werte von 0 bis 255 annehmen
analogWrite(LED, Helligkeit); //Das LED wird angesteueret mit dem Helligkeitswert (0-255)
Serial.println(Helligkeit); //Gibt die Helligkeit (0 bis 255) aus
delay(10);
}

Arduino Hack Servomotor

Arduino-servo-fritzing-schaltung.jpg

CODE

#include <Servo.h>

Servo myservo; // erstellt ein Servo-Objekt, um einen Servomotor zu steuern

int potpin = A2; // Analog Pin, an dem das Potentiometer angeschlossen ist
int val; // Variable um den Wert des Analogen Pin zwischenzuspeichern

void setup() {
  myservo.attach(9); // verknüpft den Servomotor an Pin 9 mit dem Servo-Objekt
}

void loop() {
  val = analogRead(potpin); // liest das Potentiometer aus (Wert zwischen 0 und 1023)
  val = map(val, 0, 1023, 0, 180); // rechnet den Wert in den Wertebereich des Servomotors (zwischen 0 und180)
  myservo.write(val); // überträgt die Zielposition an den Servomotors
  delay(15); // lässt dem Servomotor Zeit, die Zielposition zu erreichen
}

Hilfreiche Anleitung: https://starthardware.org/servo/

Arduino Hack LEDs mit Geschwindigkeit

LEDS Geschwindigkeit Schaltplan.jpg


https://youtu.be/gKijhUBz4Hw

code:

int Widerstand = 0;
int Geschwindigkeit = 0;
const int Potentiometer = A1;
int Pinein = 1;
int Pinaus = 8;

void setup() {
   pinMode(1, OUTPUT); // LED an Pin 1 
   pinMode(2, OUTPUT); // LED an Pin 2
   pinMode(3, OUTPUT); // LED an Pin 3 
   pinMode(4, OUTPUT); // LED an Pin 4
   pinMode(5, OUTPUT); // LED an Pin 5 
   pinMode(5, OUTPUT); // LED an Pin 6
   pinMode(6, OUTPUT); // LED an Pin 7 
   pinMode(7, OUTPUT); // LED an Pin 8

}

void loop() {
   int Widerstand = analogRead(Potentiometer);
   int Geschwindigkeit = Widerstand;
   digitalWrite(Pinein, HIGH);
   digitalWrite(Pinaus, LOW);
   delay(Geschwindigkeit); 
   if (Pinein < 8)
      {
        Pinein += 1;
      }
    else 
      {
        Pinein = 1;
      }
   if (Pinaus < 8)
      {
        Pinaus += 1;
      }
    else
      {
        Pinaus = 1;
      }

}

Hack 1

Messung und Visualisierung von Muskelsignalen (EMG) mit dem BioAmp EXG

Was ist Elektromyographie (EMG)?

Die Elektromyografie ist eine Technik zur Messung der Muskelreaktion oder der elektrischen Aktivität als Reaktion auf die Stimulation des Muskels durch einen Nerv. Wir können diese elektrische Aktivität nutzen, um neuromuskuläre Anomalien zu erkennen oder Lösungen für verrückte reale Probleme zu finden, wie z. B. die Herstellung künstlicher Gliedmaßen für Amputierte.

EmgArm.png

Über BioAmp EXG:

BioAmp EXG ist ein einzigartiger Chip in Pillengröße, der Biopotentialsignale von Ihrem Körper in Publikationsqualität aufzeichnen kann, sei es vom Herzen (EKG), vom Gehirn (EEG), von den Augen (EOG) oder von den Muskeln (EMG).

Die gesamte BioAmp-Sensorserie von Upside Down Labs ist so konzipiert, dass Sie die Grundlagen des Instrumentenverstärkers, der aktiven Bandpassfilterung, des Lötens, der Programmierung, der Neurowissenschaften, der HCI und der BCI erlernen, um nur einige Konzepte zu nennen.
Versuch

Hardware

  • 1 x BioAmp EXG Pill
  • 1 x BioAmp Cable
  • 3 x Gel Electrodes
  • 3 x Jumper Cables
  • 1 x Arduino Uno

Software

  • Arduino IDE
  • BYB Spike Recorder

Probleme

Der Recorder gab Werte aus. Anfänglich mit einer Delay von etwa 3 Sekunden. Es stellte sich heraus, dass der Computer schuld war. Durch Neustarten des Computers zeigte der Recorder zeitnaher die Werte. Weiter konnte man nicht feststellen, warum es so heftige Anstrengungen des Probanden brauchte, damit es signifikante Ergebnisse gab.


Schema















CODE

// EMG Filter - BioAmp EXG Pill
// https://github.com/upsidedownlabs/BioAmp-EXG-Pill

// Upside Down Labs invests time and resources providing this open source code,
// please support Upside Down Labs and open-source hardware by purchasing
// products from Upside Down Labs!

// Copyright (c) 2021 Upside Down Labs - contact@upsidedownlabs.tech

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#define SAMPLE_RATE 500
#define BAUD_RATE 115200
#define INPUT_PIN A0


void setup() {
	// Serial connection begin
	Serial.begin(BAUD_RATE);
}

void loop() {
	// Calculate elapsed time
	static unsigned long past = 0;
	unsigned long present = micros();
	unsigned long interval = present - past;
	past = present;

	// Run timer
	static long timer = 0;
	timer -= interval;

	// Sample
	if(timer < 0){
		timer += 1000000 / SAMPLE_RATE;
		float sensor_value = analogRead(INPUT_PIN);
		float signal = EMGFilter(sensor_value);
		Serial.println(signal);
	}
}

// Band-Pass Butterworth IIR digital filter, generated using filter_gen.py.
// Sampling rate: 500.0 Hz, frequency: [74.5, 149.5] Hz.
// Filter is order 4, implemented as second-order sections (biquads).
// Reference: 
// https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.butter.html
// https://courses.ideate.cmu.edu/16-223/f2020/Arduino/FilterDemos/filter_gen.py
float EMGFilter(float input)
{
  float output = input;
  {
    static float z1, z2; // filter section state
    float x = output - 0.05159732*z1 - 0.36347401*z2;
    output = 0.01856301*x + 0.03712602*z1 + 0.01856301*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - -0.53945795*z1 - 0.39764934*z2;
    output = 1.00000000*x + -2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - 0.47319594*z1 - 0.70744137*z2;
    output = 1.00000000*x + 2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - -1.00211112*z1 - 0.74520226*z2;
    output = 1.00000000*x + -2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  return output;
}

Visualisierung von Muskelsignalen (EMG) mit LED-Reihe

EMG mit LED gekoppelt

Hardware

  • 1 x BioAmp EXG Pill
  • 1 x BioAmp Cable
  • 3 x Gel Electrodes
  • 3 x Jumper Cables
  • 1 x Arduino Uno
  • 8 x LED
  • 2 x Breadboard
  • 1 x wooden case

LEDS Neuro.jpg EmgArm.png

Software

  • Arduino IDE
  • BYB Spike Recorder

Probleme

- Die Box aus Holz ist zu klein beziehungsweise zu wenig hoch dimensioniert. Resultiert darin, dass Alle Kabel abgeknickt werden mussten. Zudem hatten zwar zwei Breadboards, aber nicht das Arduino Platz.

- Die Schwellenwerte bei den IF-Schlaufen muss ausgetestet werden und kann je nach Platzierung der Elektroden variieren.

- Die Schwellenwerte für die LEDs sind bei einer neuen Versorgungsspannung nicht mehr ideal und müssen neu kalibriert werden.

CODE

// EMG Filter - BioAmp EXG Pill
// https://github.com/upsidedownlabs/BioAmp-EXG-Pill

// Upside Down Labs invests time and resources providing this open source code,
// please support Upside Down Labs and open-source hardware by purchasing
// products from Upside Down Labs!

// Copyright (c) 2021 Upside Down Labs - contact@upsidedownlabs.tech

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#define SAMPLE_RATE 500
#define BAUD_RATE 115200
#define INPUT_PIN A0
const int LED2 = 2;
const int LED3 = 3;
const int LED4 = 4;
const int LED5 = 5;
const int LED6 = 6;
const int LED7 = 7;
const int LED8 = 8;
const int LED9 = 9;


void setup() {
	// Serial connection begin
	Serial.begin(BAUD_RATE);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(LED6, OUTPUT);
  pinMode(LED7, OUTPUT);
  pinMode(LED8, OUTPUT);
  pinMode(LED9, OUTPUT);
}

void loop() {
	// Calculate elapsed time
	static unsigned long past = 0;
	unsigned long present = micros();
	unsigned long interval = present - past;
	past = present;

	// Run timer
	static long timer = 0;
	timer -= interval;

	// Sample
	if(timer < 0){
		timer += 1000000 / SAMPLE_RATE;
		float sensor_value = analogRead(INPUT_PIN);
		float signal = EMGFilter(sensor_value);
		Serial.println(signal);
    if (signal < 5 || signal > -5) //Bei keiner Bewegung ist das Signal nahe bei Null
    {
      digitalWrite(LED2, LOW);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, LOW);
      digitalWrite(LED5, LOW);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      }
    if (signal < -5 || signal > 5) //Leichte Bewegung, ein LED eingeschalten
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, LOW);
      digitalWrite(LED5, LOW);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      }
    if (signal < -15 || signal > 15)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, LOW);
      digitalWrite(LED5, LOW);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      }
    if (signal < -30 || signal > 30)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, LOW);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      }
    if (signal < -50 || signal > 50)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      }
    if (signal < -80 || signal > 80)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, HIGH);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      }
    if (signal < -150 || signal > 150)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, HIGH);
      digitalWrite(LED7, HIGH);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      }
    if (signal < -200 || signal > 200)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, HIGH);
      digitalWrite(LED7, HIGH);
      digitalWrite(LED8, HIGH);
      digitalWrite(LED9, LOW);
      }
    if (signal < -300 || signal > 300)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, HIGH);
      digitalWrite(LED7, HIGH);
      digitalWrite(LED8, HIGH);
      digitalWrite(LED9, HIGH);
      }
	}
}

// Band-Pass Butterworth IIR digital filter, generated using filter_gen.py.
// Sampling rate: 500.0 Hz, frequency: [74.5, 149.5] Hz.
// Filter is order 4, implemented as second-order sections (biquads).
// Reference: 
// https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.butter.html
// https://courses.ideate.cmu.edu/16-223/f2020/Arduino/FilterDemos/filter_gen.py
float EMGFilter(float input)
{
  float output = input;
  {
    static float z1, z2; // filter section state
    float x = output - 0.05159732*z1 - 0.36347401*z2;
    output = 0.01856301*x + 0.03712602*z1 + 0.01856301*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - -0.53945795*z1 - 0.39764934*z2;
    output = 1.00000000*x + -2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - 0.47319594*z1 - 0.70744137*z2;
    output = 1.00000000*x + 2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - -1.00211112*z1 - 0.74520226*z2;
    output = 1.00000000*x + -2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  return output;
}


alternative Code durch das Programm Cursor (KI) gekürzt



#define SAMPLE_RATE 500
#define BAUD_RATE 115200
#define INPUT_PIN A0
const int LEDs[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Use an array to manage LEDs for scalability and easier control

void setup() {
	Serial.begin(BAUD_RATE);
	for (int i = 0; i < sizeof(LEDs)/sizeof(LEDs[0]); ++i) {
		pinMode(LEDs[i], OUTPUT); // Initialize all LED pins in a loop
	}
}

void loop() {
	static unsigned long past = 0;
	unsigned long present = micros();
	unsigned long interval = present - past;
	past = present;

	static long timer = 0;
	timer -= interval;

	if(timer < 0){
		timer += 1000000 / SAMPLE_RATE;
		float sensor_value = analogRead(INPUT_PIN);
		float signal = EMGFilter(sensor_value);
		Serial.println(signal);

		// Simplify LED control logic
		int signalLevels[] = {-300, -200, -150, -80, -50, -30, -15, -5}; // Define signal thresholds
		for (int i = 0; i < sizeof(signalLevels)/sizeof(signalLevels[0]); ++i) {
			digitalWrite(LEDs[i], (signal < signalLevels[i] || signal > -signalLevels[i]) ? HIGH : LOW);
		}
	}
}

float EMGFilter(float input) {
  // Filter implementation remains unchanged as it's specific to the signal processing task
  // and likely optimized for its purpose already.
  ...
}

Hack 2

Mittels Armbetätigung ein Auto zum Fahren bringen + Anzeige wie stark die Belastung ist

Hardware

Das Gefährt inklusive Ansteuerung konnten wir von einer vorherigen DIY-MedTech-Gruppe übernehmen. So konnten wir unsere LED-Reihe und Potentiometer selbst anpassen und einbauen. Wir entwickelten unseren Hack 1 weiter, so dass die Kabel besser verstaut sind, zusätzlich noch ein Fahrzeug angesteuert werden kann und mit dem Potentiometer die Signalstärke reguliert werden kann. Wenn die Hand Locker ist und kein LED aufleuchtet fährt das Fahrzeug rückwärts. Sobald man den Arm anspannt, wird der Power mit den LEDs angezeigt und das Fahrzeug fährt vorwärts.

Autofahren mit Anhänger mittels EMG
Resultat


Software

Schema
  • Arduino IDE
  • BYB Spike Recorder

Probleme

  • Wenn der Arduino vom Computer aus gespeist wird funktioniert das Programm. Anders verhält sich das Programm bei direkter Speisung über ein Ladegerät oder ein Batterie-Pack. Bei dieser Konfiguration funktioniert gar nichts. Auch ein Austauschen durch ein neuer Arduino (neuere Generation) verändert nichts. Weiter verhalf das Miteinbeziehen der Betreuer nichts. Ergo wird die Demo mit dem Computer passieren.
  • Die LEDs wollten wir nicht auf einem Steckbrett belassen, da dies zu viel Raum beansprucht. So wurden die acht LEDs an Kabel verlötet und mit Schmelzklebstoff isoliert.
  • Skalierung je nach Mensch und Anschluss ist unterschiedlich: die Lösung dazu ist ein eingebauter Potentiometer, mit dem man den Max.-Meter regeln kann.
  • Die Kontakte für die Ansteuerung der LEDs waren zeitweise locker. Lösung war frische Verkabelung. Jedoch stellte sich heraus, dass die originalen Kontakte nach der <Reparatur> wieder funktionierten. Unterschied konnten wir keinen feststellen.

CODE


// EMG Filter - BioAmp EXG Pill
// https://github.com/upsidedownlabs/BioAmp-EXG-Pill

// Upside Down Labs invests time and resources providing this open source code,
// please support Upside Down Labs and open-source hardware by purchasing
// products from Upside Down Labs!

// Copyright (c) 2021 Upside Down Labs - contact@upsidedownlabs.tech

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#define SAMPLE_RATE 500
#define BAUD_RATE 115200
#define INPUT_PIN A0
const int LED2 = 2;
const int LED3 = 3;
const int LED4 = 4;
const int LED5 = 5;
const int LED6 = 6;
const int LED7 = 7;
const int LED8 = 8;
const int LED9 = 9;
const int GSM1 = 10;
const int in1 = 11;
const int in2 = 12;
int maxwert = 40;
const int Pot = A1;


void setup() {
	// Serial connection begin
	Serial.begin(BAUD_RATE);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(LED6, OUTPUT);
  pinMode(LED7, OUTPUT);
  pinMode(LED8, OUTPUT);
  pinMode(LED9, OUTPUT);
  pinMode(GSM1, OUTPUT);    
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(Pot, OUTPUT);
}

void loop() {
	// Calculate elapsed time
	static unsigned long past = 0;
	unsigned long present = micros();
	unsigned long interval = present - past;
	past = present;

	// Run timer
	static long timer = 0;
	timer -= interval;

	// Sample
	if(timer < 0){
		timer += 1000000 / SAMPLE_RATE;
		float sensor_value = analogRead(INPUT_PIN);
		float signal = EMGFilter(sensor_value);
		Serial.println(signal);
    maxwert = analogRead(Pot);
    //Serial.print("Maxwert");
    //Serial.println(maxwert);
    if (signal < maxwert/8 || signal > -maxwert/8) //Zwischen diesen Werten sind alle LEDs aus und der Motor läuft rückwärts
    {
      digitalWrite(LED2, LOW);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, LOW);
      digitalWrite(LED5, LOW);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      digitalWrite(in1, LOW);  
      digitalWrite(in2, HIGH);  // Motor 1 beginnt zu rotieren (rückwärts)
      analogWrite(GSM1, 150);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren 
      }
    if (signal < -maxwert/8 || signal > maxwert/8)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, LOW);
      digitalWrite(LED5, LOW);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      digitalWrite(in1, LOW);  
      digitalWrite(in2, LOW); // Motor reagiert nicht
      analogWrite(GSM1, 150);  
      }
    if (signal < -maxwert*2/8 || signal > maxwert*2/8)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, LOW);
      digitalWrite(LED5, LOW);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      digitalWrite(in1, HIGH);  // Motor 1 beginnt zu rotieren (vorwärts)
      digitalWrite(in2, LOW);
      analogWrite(GSM1, 150);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren 
      }
    if (signal < -maxwert*3/8 || signal > maxwert*3/8)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, LOW);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      digitalWrite(in1, HIGH);  // Motor 1 beginnt zu rotieren
      digitalWrite(in2, LOW);
      analogWrite(GSM1, 200);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren 
      }
    if (signal < -maxwert*4/8 || signal > maxwert*4/8)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, LOW);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      digitalWrite(in1, HIGH);  // Motor 1 beginnt zu rotieren
      digitalWrite(in2, LOW);
      analogWrite(GSM1, 200);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren 
      }
    if (signal < -maxwert*5/8 || signal > maxwert*5/8)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, HIGH);
      digitalWrite(LED7, LOW);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      digitalWrite(in1, HIGH);  // Motor 1 beginnt zu rotieren
      digitalWrite(in2, LOW);
      analogWrite(GSM1, 200);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren 
      }
    if (signal < -maxwert*6/8 || signal > maxwert*6/8)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, HIGH);
      digitalWrite(LED7, HIGH);
      digitalWrite(LED8, LOW);
      digitalWrite(LED9, LOW);
      digitalWrite(in1, HIGH);  // Motor 1 beginnt zu rotieren
      digitalWrite(in2, LOW);
      analogWrite(GSM1, 255);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren 
      }
    if (signal < -maxwert*7/8 || signal > maxwert*7/8)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, HIGH);
      digitalWrite(LED7, HIGH);
      digitalWrite(LED8, HIGH);
      digitalWrite(LED9, LOW);
      digitalWrite(in1, HIGH);  // Motor 1 beginnt zu rotieren
      digitalWrite(in2, LOW);
      analogWrite(GSM1, 255);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren 
      }
    if (signal < -maxwert || signal > maxwert)
    {
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, HIGH);
      digitalWrite(LED5, HIGH);
      digitalWrite(LED6, HIGH);
      digitalWrite(LED7, HIGH);
      digitalWrite(LED8, HIGH);
      digitalWrite(LED9, HIGH);
      digitalWrite(in1, HIGH);  // Motor 1 beginnt zu rotieren
      digitalWrite(in2, LOW);
      analogWrite(GSM1, 255);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren 
      }
	}
}

// Band-Pass Butterworth IIR digital filter, generated using filter_gen.py.
// Sampling rate: 500.0 Hz, frequency: [74.5, 149.5] Hz.
// Filter is order 4, implemented as second-order sections (biquads).
// Reference: 
// https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.butter.html
// https://courses.ideate.cmu.edu/16-223/f2020/Arduino/FilterDemos/filter_gen.py
float EMGFilter(float input)
{
  float output = input;
  {
    static float z1, z2; // filter section state
    float x = output - 0.05159732*z1 - 0.36347401*z2;
    output = 0.01856301*x + 0.03712602*z1 + 0.01856301*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - -0.53945795*z1 - 0.39764934*z2;
    output = 1.00000000*x + -2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - 0.47319594*z1 - 0.70744137*z2;
    output = 1.00000000*x + 2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - -1.00211112*z1 - 0.74520226*z2;
    output = 1.00000000*x + -2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  return output;
}

Reflektion Medtech DIY

Eric

  • Arduino Programmieren: Ich hatte vor dieser Woche noch keine Kenntnisse im Programmieren von Arduinos und auch diese noch nie gebraucht. Jedoch konnte ich in dieser Woche mithilfe der Arduino-Einführung viel ausprobieren und lernen.
  • Laser-Cutter: Den Laser-Cutter hatte ich vor dieser Woche noch nie gebraucht, wollte diesen aber unbedingt kennenlernen. Ich konnte im Verlauf der Woche mehrere Sachen ausschneiden und lernte das Programm anzuwenden.
  • Mir hat diese Woche sehr viel Spass gemacht, da ich einfach ausprobieren konnte und nicht viele Vorgaben hatte. Sobald mir langweilig wurde, konnte ich etwas anders probieren und so hatte ich immer kleine Erfolgserlebnisse. Mit diesem Trial and Error Prinzip hatte ich extrem viel gelernt, speziell in Bezug auf das Arduino-Programmieren. Ich finde, solche DIY-Module sollten mehr in der HSLU stattfinden.

Patrick

Das einzigartige Format dieses Moduls ist optimal für interessierte Bastler. Man kann sich in einem grossen Rahmen austoben und probieren, was einem so in den Sinn kommt. Durch das DIY-Format erhält jede Person seine eigenen Erkenntnisse, welche mit den Anderen geteilt wird, um einen maximalen Lerneffekt zu erzielen. Aufgrund dessen gab es selbst für Personen aus dem Elektronikbereich neue Erfahrungen und Erkenntnisse. Neben den Grundlagen von Arduino programmieren, 3D-Drucker und Lasercutter bedienen, war mein grosser Lerneffekt, dass es mehr Module in diesem Format geben sollte. Es war eine tolle Abwechslung zum klassischen Frontalunterricht und ich finde es sehr schade, dass zukünftige Studierende nicht mehr dieses Angebot erhalten.

Philipp

  • Als aller Erstes kommt mir in Sinn, dass diese Woche perfekt zum Basteln ist. So kann man selbst Hand anlegen und ganz viel aus vielen Fehlern von sich oder von anderen lernen.
  • Schade ist, dass dies nicht mehr angeboten wird. Als zukünftiger Ingenieur ist es mir wichtig, einen guten Realitätsbezug zu bewahren. Gerade in so einem theoretischen Studiengang wie Maschinentechnik finde ich es traurig, die Praxis noch mehr zu verringern bzw. zu entfernen.
  • Ich werde in Zukunft dank dieser Blockwoche mehr basteln. Sei es Elektronik zusammen bauen und/oder dazu etwas programmieren.