Zeit-, Entfernungs- und Gewichtsschätzung: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
 
(3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 362: Zeile 362:


{| class="wikitable"
{| class="wikitable"
|+ style = "text-align: left"| Tabelle 6: Kalibrierung des Drucksensors @2kg
|+ style = "text-align: left"| Tabelle 6: Kalibrierung des Drucksensors  
|-
|-
! style="font-weight: bold;" | Gewicht in g
! style="font-weight: bold;" | Gewicht in g
Zeile 400: Zeile 400:
\end{align}</math>
\end{align}</math>


Der IR-Abstandssensor GP2Y0A41SK0F verfügt über eine biaxiale Optik (siehe Abbildung 15), bei der die optischen Achsen von Sender und Empfänger voneinander getrennt verlaufen. Diese Konfiguration verbessert die Energieübertragung und optimiert die Entfernungsbestimmung. Typischerweise befinden sich die Achsen parallel zueinander, um die Funktionalität zu maximieren [3].
Der IR-Abstandssensor GP2Y0A41SK0F verfügt über eine biaxiale Optik (vgl. Abb. 19), bei der die optischen Achsen von Sender und Empfänger voneinander getrennt verlaufen. Diese Konfiguration verbessert die Energieübertragung und optimiert die Entfernungsbestimmung. Typischerweise befinden sich die Achsen parallel zueinander, um die Funktionalität zu maximieren [3].


<gallery widths="300" heights="200" perrow="3">
<gallery widths="300" heights="200" perrow="3">
Darstellung PSD.png|Abbildung 14: Schematischer Aufbau und Funktionsweise eines PSD-Elements. [3]
Darstellung PSD.png|Abbildung 18: Schematischer Aufbau und Funktionsweise eines PSD-Elements. [3]
Biaxiale Optik.png|Abbildung 15: Prinzipielles Schema beim Triangulations-, Puls-, Phasen- und Frequenzmessverfahren mit biaxialer Optik [3]  
Biaxiale Optik.png|Abbildung 19: Prinzipielles Schema beim Triangulations-, Puls-, Phasen- und Frequenzmessverfahren mit biaxialer Optik [3]  
Typische Verlauf biaxialer Optik.png| Abbildung 16: Typischer Verlauf einer biaxialer Optik [3]
Typische Verlauf biaxialer Optik.png| Abbildung 20: Typischer Verlauf einer biaxialer Optik [3]
</gallery>
</gallery>


Der Abstandssensor mit einem Messbereich von 40 bis 300 mm gibt eine analoge Spannung aus, die proportional zur gemessenen Entfernung ist (siehe Abbildung 16). Wenn der Abstand zum Objekt geringer ist, ist die ausgegebene Spannung höher (bei größerem Abstand ist die Spannung niedriger). Diese analoge Spannung kann an einen analogen Eingang eines Arduino-Boards angeschlossen werden. Der Arduino liest die Spannung, wandelt sie in einen digitalen Wert um und berechnet daraus die Distanz zum Objekt.
Der Abstandssensor mit einem Messbereich von 40 bis 300&thinsp;mm gibt eine analoge Spannung aus, die proportional zur gemessenen Entfernung ist (vgl. Abb. 20). Wenn der Abstand zum Objekt geringer ist, ist die ausgegebene Spannung höher (bei größerem Abstand ist die Spannung niedriger). Diese analoge Spannung kann an einen analogen Eingang eines Arduino-Boards angeschlossen werden. Der Arduino liest die Spannung, wandelt sie in einen digitalen Wert um und berechnet daraus die Distanz zum Objekt.


Für eine genaue Messung ist eine Kalibrierung erforderlich, da sich die analoge Spannung je nach reflektiertem Signal leicht verändern kann. Indem bekannte Abstände gemessen werden und die Spannungen erfasst wird (siehe Tabelle 6), kann eine Zuordnung erstellt werden, die dem Arduino hilft, die Spannung korrekt in eine Entfernung umzurechnen. Daraus lässt sich dann ein Lookup-Tabelle erstellen, die die Spannungswerte in die entsprechenden Entfernungen umwandelt.
Für eine genaue Messung ist eine Kalibrierung erforderlich, da sich die analoge Spannung je nach reflektiertem Signal leicht verändern kann. Indem bekannte Abstände gemessen werden und die Spannungen erfasst wird (vgl. Tab 6), kann eine Zuordnung erstellt werden, die dem Arduino hilft, die Spannung korrekt in eine Entfernung umzurechnen. Daraus lässt sich dann ein Lookup-Tabelle erstellen, die die Spannungswerte in die entsprechenden Entfernungen umwandelt. Als Referenz wurde ein Maßstab verwendet.


{| class="wikitable"
{| class="wikitable"

Aktuelle Version vom 15. Januar 2025, 18:06 Uhr

→ zurück zur Übersicht: WS 24/25: Escape Game

Autoren: Niklas Reeker, Oliver Scholze und Johann Kismann
Betreuer: Marc Ebmeyer
Abb. 01: Von der Skizze des Projekts bis zum fertigen Produkt

Einleitung

Bereits im Grundschulalter wurden wir von unseren Lehrern dazu herausgefordert, Zeitintervalle, Entfernungen und Gewichte zu schätzen. Dabei wurde uns oft bewusst, wie sehr wir danebenliegen konnten. Diese Übungen halfen uns, ein grundlegendes Gefühl für Zeit, Raum und Masse zu entwickeln und deren Bedeutung im Alltag zu erkennen. Während wir als Erwachsene ein besseres Gespür dafür entwickelt haben, bleibt die genaue Schätzung von Zeit, Entfernungen und Gewichten dennoch eine anspruchsvolle Herausforderung.

Unser Escape Game greift diese Phänomene auf spannende Weise auf. Die Aufgabe klingt einfach, erweist sich jedoch als knifflig: Halten Sie Ihren Finger genau 10 Sekunden lang auf einen Knopf – ohne Hilfsmittel zur Zeitmessung. Sobald diese erste Aufgabe erfolgreich abgeschlossen ist, müssen Sie zusätzlich eine Entfernung von 10 cm abschätzen. Zur Entfernungsmessung wird ein IR-Sensor verwendet, der die Genauigkeit der Schätzung ermittelt. Eine LED über dem IR-Sensor beginnt zu blinken, um anzuzeigen, dass die Entfernung nun geschätzt werden soll. Sobald Sie glauben, die richtige Entfernung gefunden zu haben, müssen Sie erneut den Knopf drücken, um Ihre Schätzung zu bestätigen. Ist diese Aufgabe korrekt gemeistert, erleuchtet die nächste LED über dem Drucksensor und es muss das dritte und damit auch das letzte Rätsel gelöst werden. Dies umfasst eine Gewichtsschätzung über einen Drucksensor. Dabei muss bei einer Auswahl von drei verschiedenen Gewichten das Gewicht mit 150 g ausgewählt und auf den Drucksensor gestellt werden. Auch hier stellt ein erneuter Knopfdruck die Bestätigung der Auswahl dar.

Lassen Sie den Knopf zu früh oder zu spät los, schätzen Sie die Entfernung falsch oder wählen Sie das falsche Gewicht, ertönt eine traurige Melodie und die tatsächlich gedrückte Zeit, die geschätzte Entfernung oder das ausgewählte Gewicht werden angezeigt. So erfahren Sie genau, wie weit Sie von den Zielwerten entfernt waren und ob Ihre Schätzungen zu kurz oder zu lang waren. Treffen Sie jedoch die richtigen Werte, werden Sie mit einer Siegermelodie belohnt und der Code für das Schloss erscheint auf dem Display. Nur mit diesem Code können Sie das Escape-Schloss öffnen und erfolgreich entkommen.

Wichtig: Es wird immer erst die Zeit, dann die Entfernung und anschließend das Gewicht geschätzt. Ist eine der drei Schätzungen falsch, müssen Sie von vorne beginnen, beginnend mit der Zeitmessung.

Dieses Spiel verbindet Spaß und Spannung und zeigt auf unterhaltsame Weise, wie herausfordernd es sein kann, alltägliche Größen, wie Zeit, Entfernung und Gewicht, präzise einzuschätzen. Stellen Sie Ihr Gefühl auf die Probe und finden Sie heraus, ob Sie den Code knacken können!

Anforderungen

Im nachfolgenden werden die testbaren Anforderungen gezeigt, welche den korrekten Betrieb der Zeit-, Entfernungs- und Gewichtsschätzung sicherstellen und hier hinterlegt sind.

Tabelle 1: Anforderungen an das Escape Game
ID Inhalt Prio Ersteller Datum Geprüft von Datum Umsetzung der Anforderung in %; Prüfer
1 Das Escape Game muss in 4-5 Minuten lösbar sein Mittel Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
2 Der Spieler muss den Button für 10 Sekunden +-1 s Sekunde gedrückt halten um zum zweiten Rätsel der Abstandsmessung zu gelangen. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
3 Wenn die Zeit falsch geschätzt wurde, wird die tatsächlich gedrückte Zeit auf dem Display angezeigt. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
4 Wenn die Zeit falsch geschätzt wurde, beginnt das Spiel erneut mit der Zeitmessung. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
5 Wenn die Zeit falsch geschätzt wurde, wird eine traurige Melodie abgespielt. Mittel Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
6 Ist die Zeit richtig geschätzt, blinkt eine LED, alle 250 ms, bei der Entfernungsschätzung, um dem Benutzer zu zeigen wo es weitergeht. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
7 Ist die Zeit richtig geschätzt, beginnt die Entfernungsschätzung von 10 cm +-1 cm. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
8 Wenn die Entfernung falsch geschätzt wird, beginnt das Spiel erneut mit der Zeitmessung. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
9 Wenn die Entfernung falsch geschätzt wird, wird die tatsächlich geschätzte Entfernung auf dem Bildschirm in cm angezeigt. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
10 Wenn die Entfernung falsch geschätzt wird, wird eine traurige Melodie abgespielt. Mittel Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
11 Ist die Entfernung richtig geschätzt, blinkt eine LED alle 250 ms bei der Gewichtsschätzung, um dem Benutzer anzuzeigen wo es weitergeht. Hoch Johann Kismann 11.10.2024 Oliver Scholze 11.10.2024 100%; Johann Kismann
12 Ist die Entfernung richtig geschätzt, beginnt die Gewichtsschätzung von 150 g +-10%. Hoch Johann Kismann 11.10.2024 Oliver Scholze 11.10.2024 100%; Johann Kismann
13 Wenn das Gewicht falsch geschätzt wird, beginnt das Spiel erneut mit der Zeitmessung. Hoch Johann Kismann 11.10.2024 Oliver Scholze 11.10.2024 100%; Johann Kismann
14 Wenn das Gewicht falsch geschätzt wird, wird das tatsächliche Gewicht auf dem Bildschirm in g angezeigt. Hoch Johann Kismann 11.10.2024 Oliver Scholze 11.10.2024 100%; Johann Kismann
15 Wenn das Gewicht falsch geschätzt wird, wird eine traurige Melodie abgespielt. Mittel Johann Kismann 11.10.2024 Oliver Scholze 11.10.2024 100%; Johann Kismann
16 Bei richtiger Zeitschätzung wird eine Siegesmelodie abgespielt. Mittel Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
17 Bei richtiger Entfernungsschätzung wird eine Siegesmelodie abgespielt. Mittel Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
18 Bei richtiger Gewichtsschätzung wird eine Siegesmelodie abgespielt. Mittel Johann Kismann 11.10.2024 Oliver Scholze 11.10.2024 100%; Johann Kismann
19 Die Zeitmessung wird bei der Ausgabe auf ganze Sekunden gerundet (Bsp: 12,6 s entspricht 13 s). Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
20 Die Entfernungsmessung wird bei der Ausgabe auf ganze Entfernungen in cm gerundet (Bsp: 12,6 cm entspricht 13 cm). Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
21 Nach der Gewichtsmessung wird der Wert des Gewichts in g ausgegeben. Hoch Johann Kismann 11.10.2024 Oliver Scholze 11.10.2024 100%; Johann Kismann
22 Bei richtiger Gewichtsschätzung wird der dreistellige Code für das Schloss auf dem Display ausgegeben. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
23 Das Spiel muss ohne visuelle Hilfsmittel zur Zeit-, Entfernungs- und Gewichtsmessung (wie Uhren, Lineale oder Waagen) funktionieren. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
24 Die Interaktion erfolgt über einen einfachen Knopf und einen Display für Rückmeldungen. Mittel Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
25 Das System muss benutzerfreundlich und für Kinder wie Erwachsene geeignet sein. Mittel Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
26 Das Arduino-System wird über Simulink gesteuert. Hoch Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann
27 Das Escape Game muss in einen Schuhkarton passen. Gering Niklas Reeker 02.10.2024 Oliver Scholze 02.10.2024 100%; Johann Kismann

Funktionaler Systementwurf/Technischer Systementwurf

Abb. 02: Funktionaler Systementwurf
Abb. 03: Technischer Systementwurf

Funktionaler Systementwurf

Das Eingabegerät wird von der Spielerin oder dem Spieler über einen Taster aktiviert, wie in Abbildung 02 zu sehen ist. Nach der Aktivierung startet die Zeitmessung. Die Herausforderung besteht darin, den Taster für eine vorgegebene Zeitspanne zu bedienen und dabei basierend auf der eigenen Einschätzung den richtigen Zeitpunkt zu treffen, an dem die Schätzdauer von 10s erreicht ist.

Sobald die Zeitspanne erfolgreich eingehalten wurde, muss die Spielerin oder der Spieler eine Entfernung von 10 cm mit einer Toleranz von ±1 cm schätzen. Wird auch diese Aufgabe korrekt gelöst, folgt die Schätzung eines Gewichts von 150 g. Alle drei Aufgaben müssen ohne Hilfsmittel bewältigt werden. Erst wenn Zeit-, Entfernungs- und Gewichtsschätzung erfolgreich abgeschlossen sind, erhält die Spielerin oder der Spieler einen Code, um das nächste Escape-Spiel freizuschalten.

Falls eine der drei Aufgaben nicht korrekt gelöst wird, muss der gesamte Vorgang erneut begonnen werden, beginnend mit der Zeitmessung.

Technischer Systementwurf

Die Steuerung und Überwachung des gesamten Spiels übernimmt ein Mikrocontroller, wie in Abbildung 03 des funktionalen Systementwurfs gezeigt. Er ist direkt mit der Spannungsversorgung verbunden, um eine durchgehende Funktion sicherzustellen. Das Eingabegerät besteht aus einem Taster, der direkt mit dem Mikrocontroller verbunden ist. Sobald der Taster aktiviert wird, startet der Mikrocontroller die Stoppuhrfunktion und beginnt die Zeitmessung.

Nach erfolgreicher Zeitmessung wird die Spielerin oder der Spieler aufgefordert, eine Entfernung von 10 cm mit einer Toleranz von ±1 cm zu schätzen. Für diese Aufgabe wird ein IR-Sensor verwendet, der ebenfalls an den Mikrocontroller angeschlossen ist. Um den nächsten Schritt anzuzeigen, beginnt eine LED über dem IR-Sensor zu blinken, sobald die Entfernungsmessung durchgeführt werden soll. Diese LED dient als visuelle Rückmeldung und ist direkt mit dem Mikrocontroller verbunden.

Für die anschließende Gewichtsschätzung wird ein Drucksensor verwendet. Nach einer korrekten Entfernungsschätzung zeigt eine weitere blinkende LED über dem Drucksensor an, dass die Gewichtsschätzung erfolgen soll. Auch hier dient die LED der visuellen Orientierung der Spielerin oder des Spielers.

Zur Darstellung der Spielergebnisse, wie gemessener Zeit, geschätzter Entfernung, geschätztem Gewicht oder des freizuschaltenden Codes, kommen drei 7-Segment-Displays zum Einsatz. Diese Displays sind über einen 7-Segment-Decoder mit dem Mikrocontroller verbunden, um die Anzahl der benötigten Verbindungen zu reduzieren und das System effizienter zu gestalten.

Ein Buzzer ergänzt das System und bietet eine akustische Rückmeldung in Form einer Melodie. Dieses Element macht das Spielerlebnis interaktiver, indem es den Spielstatus sowohl bei Erfolg als auch bei Misserfolg signalisiert.

Materialliste

Die Materialliste gibt einen Überblick der benötigten Komponenten. Zusätzlich wird der Bestellstatus festgehalten.

Tabelle 2: Materialliste
Nr. Anz. Beschreibung
1 1 Funduino Arduino Mega
2 1 Taster
3 3 7-Segment-Display
4 1 Lochrasterplatine
5 1 Verbindungskabel
6 3 7-Segment-Decoder
7 1 Summer
8 2 LED grün
9 2 Widerstand 10kOhm
10 1 Netzteil + Kabel
11 1 Gehäuse 3D-Druck
12 2 Widerstand 150Ohm
13 1 IR-Sensor
14 1 Drucksensor

Komponentenspezifikation

Stückliste (BOM)

In der nachfolgenden Tabelle ist die Bill of Materials für das Projekt zu finden.

Da ein Großteil der Materialien bei Reichelt bestellt werden kann, fallen für diese einmalig die Versandkosten von 5,95€ an.
Tabelle 3: BOM
ID Anzahl Kosten pro Stück € Summe Bezeichnung / Komponente technische Bezeichnung Beschreibung Datenblatt Abbildung
1 1x 19,30€ 19,30€ Arduino Mega ARD MEGA2560 R3 Arduino kompatibles Mega 2560 R3 Board Der Mircocontroller mit dem ATmega2560 verfügt über 54 digitale I/O - Schnittstellen. Des Weiteren sind 16 analoge Eingänge die die Verarbeitung analoger Signale vorhanden. ARD MEGA2560 R3 Arduino kompatibles Mega 2560 R3 Board
Abb. 04: Arduino Mega
2 1x 11,56€ 11,56€ + 4,95€ Versand Taster Pilztaster Not-Aus Pilz Taster IP65 Der Taster kann mit bis zu 24V belastet werden. Datenblatt Taster
Abb. 05: Taster
3 3x 0,99€ 2,97€ 7 Segment Display Single-7-Segment-Anzeige, rot, 14,2mm, 6,4 mcd, gem. Anode Ein 7-Segment-Display stellt eine elektronische Anzeigevorrichtung dar, die primär für die Visualisierung numerischer Daten verwendet wird. 7 Segment Display
Abb. 06: 7 Segment Display
4 3x 0,84€ 2,52€ BCD-to-7-Segment-Decoder CD 74HC4511E TEX Latch, 7-Segment, 2 ... 6 V, DIL-16 Ein 7-Segment-Decoder ist ein digitales Logikschaltkreis-Element, das digitale Eingangssignale in eine entsprechende 7-Segment-Anzeige umwandelt und die Anzahl der Anschlüsse von 7 Segment anzeigen auf die Hälfte reduzieren. BCD-to-7-Segment-Decoder
Abb. 07: 7 Segment Decoder
5 2x 0,07€ 0,14€ Pullup Widerstand 10kOhm METALL 2,10K Widerstand, Metallschicht, 2,10 kOhm, 0207, 0,6 W, 1% Der Pullup-Widerstand dient dazu den Eingang am Arduino auf einem definierten Wert zu halten und somit ein eindeutiges Signal zu gewährleisten. Pullup Widerstand 10kOhm
Abb. 08: Widerstand
6 1x 1,50€ 1,50€ Summer CMI-1295-0585T Buzzer, 85dB, 2300 Hz, 5 V Ein Summer wandelt elektrische in akustische Signale um, indem er bei Anlegung einer Spannung zu vibrieren beginnt und so Töne erzeugt. Summer
Abb. 09: Summer
7 2x 0,08€ 0,16€ LED Grün EVL 333-2SYGT/S5 LED, 5 mm, bedrahtet, grün, 400 mcd, 10° Die LED hat eine Vorwärtsspannung von 2 V und darf bei maximal 20mA betrieben werden. LED
Abb. 10: LED
8 2x 0,07€ 0,14€ Widerstand 150Ohm METALL 150 Widerstand, Metallschicht, 150 Ohm, 0207, 0,6 W, 1% Der Widerstand dient als Vorwiderstand der LEDs. Widerstand 150Ohm
Abb. 11: Widerstand
9 1x 5,15€ 5,15€ Drucksensor ARD SEN PRESSURE Arduino - Drucksensor, 20 g bis 2 kg Der Drucksensor ist in der Lage, Gewichte im Bereich von 0 bis 2 kg zu erfassen und gibt in Abhängigkeit von dem gemessenen Gewicht ein analoges Signal im Bereich von 0 bis 5 Volt aus. Drucksensor
Abb. 12: Drucksensor
10 1x 32,95 € 32,95 € IR-Sensor IR Abstandssensor, 40- 300mm, analog, inkl. Kabel Der GP2Y0A21YK0F-K Distanzsensor misst Entfernungen im Bereich von 40 mm bis 300 mm und gibt ein analoges Ausgangssignal proportional zur erfassten Distanz aus. Das Signal kann direkt zur weiteren Verarbeitung genutzt werden. IR-Sensor
Abb. 13: SHARP IR GP2Y0A41SK0F
10 1x 9,20€ 9,20€ Steckernetzteil 9V für ARD Mega HNP 18-090V2 Steckernetzteil, 18 W, 9 V, 2 A 18 W Steckerschaltnetzteil mit Universaleingang 90 - 264 V AC für die Spannungsversorgung des ARD Mega. Steckernetzteil
Abb. 14: Steckernetzteil

Technische Daten der Sensoren

Die technischen Daten (Tabelle 4) der Sensoren geben Aufschluss über den Einsatzbereich und die Anforderungen, die erfüllt werden müssen, um diese in die Messumgebung zu integrieren. Die Genauigkeiten, wenn gegeben, sind aus den jeweiligen Datenblättern übernommen.

Abb. 15: Drucksensor ARD SENPRESSURE
Abb. 16: SHARP IR GP2Y0A41SK0F
Tabelle 4: Technische Daten der Sensoren
GP2Y0A41SK0F ARD SENPRESSURE @2kg
Messbereich 4 - 30 cm 0 - 2 kg
Versorgungsspannung 4.5 V - 5.5 V 3,3 V - 5 V
Versorgungsstrom typ. 12 mA -
Genauigkeit - +-2,5%
Arbeitstemperatur -10 °C - +60 °C -20 °C - +60 °C

In Tabelle 5 wird die Pinbelegung der Sensoren erläutert, wobei beide Sensoren über drei Pins verfügen, die die Stromversorgung, den analogen Ausgang und die Erdung bereitstellen.

Tabelle 5: Pinbelegung der Sensoren
GP2Y0A41SK0F ARD SENPRESSURE
Pin 1 Versorgungsspannung VCC; 5 V Versorgungsspannung VCC; 5 V
Pin 2 Masse (GND); 0 V Analoger Ausgang; 0 V .. 5 V
Pin 3 Analoger Ausgang; 0 V .. 5 V Masse (GND); 0 V

Funktionsweise und Kalibrierung der Sensoren

Drucksensor

Abb. 17: Aufbau des Drucksensors


Der SEN-PRESSURE2 ist ein Dünnfilm-Drucksensor, der durch Veränderung seines elektrischen Widerstands den ausgeübten Druck misst. Im drucklosen Zustand ist der Widerstand des Sensors hoch, wodurch die Ausgangsspannung nahe der Versorgungsspannung liegt. Bei Druckausübung sinkt der Widerstand, wodurch sich die Spannung in einer Spannungsteiler-Schaltung entsprechend verringert. Der Sensor hat einen Messbereich von 0 bis 2 kg und wandelt mechanischen Druck in elektrische Signale um.

Der druckempfindlicher Widerstand (FSR) besteht aus mehreren Schichten (siehe Abb. 17: Aufbau des Drucksensors):

  • Klebstoff: Diese Schicht dient dazu, die oberen Schichten zusammenzuhalten und die mechanische Stabilität des Sensors zu gewährleisten.
  • Obere Substratschicht: Ein flexibles Material, das die leitfähigen Bahnen oder das leitfähige Polymer enthält. Dies ist die aktive Schicht, die mit der darunterliegenden Schicht interagiert, wenn Druck ausgeübt wird.
  • Abstands-Klebstoff: Diese Schicht sorgt für einen Abstand zwischen den oberen und unteren Substraten. Sie enthält oft eine Öffnung (eine sogenannte "aktive Zone"), wo die oberen und unteren Schichten bei Druck in Kontakt treten können.
  • Untere Substratschicht: Diese Schicht enthält ebenfalls leitfähige Bahnen oder leitfähiges Material und bildet die Gegenelektrode. Zusammen mit der oberen Schicht ermöglicht sie die Widerstandsänderung bei Druck.

In der Ruheposition (ohne Druck) sind die oberen und unteren Schichten durch den Abstandshalter getrennt, sodass der Widerstand hoch ist. Wenn Druck ausgeübt wird, kommen die leitfähigen Schichten in der aktiven Zone in Kontakt, wodurch der Widerstand sinkt und der Sensor ein Signal erzeugt.

Die Ausgangsspannung wird durch die folgende Gleichung beschrieben:

Aus den Datenblättern des Arduino Mega und der LEDs lassen diese Werte ermitteln:

  • die Betriebsspannung (5V),
  • Fester Widerstand (510 Ohm)
  • Druckabhängiger Widerstand
  • Ausgangsspannung des Spannungsteilers

Die analogen Spannungswerte wurden durch eine Kalibrierung in eine konkrete Gewichtskraft umgerechnet:

Tabelle 6: Kalibrierung des Drucksensors
Gewicht in g Druckabhängiger Widerstand in kOhm Spannung in V
50 22 0.1133
100 12.5 0.1960
150 11 0.2215
200 9.5 0.2547
400 7.5 0.3183
600 6.5 0.3638
800 5.9 0.3978
1000 5.5 0.4243
1200 5.1 0.4545
1400 4.9 0.4713
1600 4.2 0.5414
2000 4 0.5654

IR-Sensor

Optische Abstandssensoren verwenden Infrarotstrahlung, das auf ein Objekt ausgestrahlt und anschließend vom Sensor detektiert wird. Aus den empfangenen Daten berechnet der Sensor die Distanz zum Objekt (siehe Abbildung 14):

Der IR-Abstandssensor GP2Y0A41SK0F verfügt über eine biaxiale Optik (vgl. Abb. 19), bei der die optischen Achsen von Sender und Empfänger voneinander getrennt verlaufen. Diese Konfiguration verbessert die Energieübertragung und optimiert die Entfernungsbestimmung. Typischerweise befinden sich die Achsen parallel zueinander, um die Funktionalität zu maximieren [3].

Der Abstandssensor mit einem Messbereich von 40 bis 300 mm gibt eine analoge Spannung aus, die proportional zur gemessenen Entfernung ist (vgl. Abb. 20). Wenn der Abstand zum Objekt geringer ist, ist die ausgegebene Spannung höher (bei größerem Abstand ist die Spannung niedriger). Diese analoge Spannung kann an einen analogen Eingang eines Arduino-Boards angeschlossen werden. Der Arduino liest die Spannung, wandelt sie in einen digitalen Wert um und berechnet daraus die Distanz zum Objekt.

Für eine genaue Messung ist eine Kalibrierung erforderlich, da sich die analoge Spannung je nach reflektiertem Signal leicht verändern kann. Indem bekannte Abstände gemessen werden und die Spannungen erfasst wird (vgl. Tab 6), kann eine Zuordnung erstellt werden, die dem Arduino hilft, die Spannung korrekt in eine Entfernung umzurechnen. Daraus lässt sich dann ein Lookup-Tabelle erstellen, die die Spannungswerte in die entsprechenden Entfernungen umwandelt. Als Referenz wurde ein Maßstab verwendet.

Tabelle 6: Kalibrierung des IR-Sensors
Entfernung in cm Spannung in V
4 3.319
5.5 2.535
7 2.028
8.5 1.672
10 1.408
12 1.168
14 0.9827
16 0.8602
18 0.7429
22 0.6256
26 0.5523
30 0.5327

Messtechnik

In der Messtechnik ist die präzise Ermittlung der Messunsicherheit von Sensoren ein zentraler Bestandteil, um die Genauigkeit und Verlässlichkeit der Messergebnisse sicherzustellen. Bei der vorliegenden Analyse wurden drei verschiedene Messmethoden untersucht:

  • ein Abstandssensor,
  • eine Zeitmessung,
  • und ein Gewichtssensor.

Die Messgenauigkeit der Systeme wurde durch wiederholte Messungen und die Berechnung von Unsicherheiten detailliert analysiert. Dabei wurden sowohl die Typ-A- als auch die Typ-B-Unsicherheiten berücksichtigt und die kombinierte Messunsicherheit präzise bestimmt.

Alle relevanten Informationen werden im Wiki-Artikel ausführlich beschrieben und im SVN-System sorgfältig hinterlegt, um die Dokumentation vollständig nachvollziehbar zu machen.

Das Skript für die Zeitmessung ist hier exemplarisch dargestellt:

%****************************************************************
%                   Hochschule Hamm-Lippstadt                   *
%****************************************************************
% Modul	          : BerechnungderStandardunsicherheit.m         *
%                                                               *
% Datum           : 08.01.2025                                  *
%                                                               *
% Funktion        : Berechnung der Standarunsicherheiten und    *
%                   der Abweichungen vom Messergebnis (Gewicht) *
%                                                               *
% Implementation  : MATLAB 2023b                                *
%                                                               *
% Req. Toolbox    : Statistics and Machine Learning Toolbox     *
%                                                               *
% Author          : Oliver Scholze, Johann Kismann, Niklas Reeker*
%                                                               *
% Bemerkung       :   -                                         *
%                                                               *
% Letzte Änderung : 15.01.2025                                  *
%****************************************************************
clc; clear all; close all;

%% Messungen laden und verarbeiten
Gesamtmessung = [5.125, 5.142, 5.105, 5.136, 5.152]; % Zeit in Sekunden

%% Mittelwerte berechnen
R = mean(Gesamtmessung(:));  % Mittelwert der Messwerte

%% Empirische Standardabweichung bestimmen
s = std(Gesamtmessung(:));  % Standardabweichung der Messwerte

%% Standardunsicherheit Typ A bestimmen
p = 0.95;  % Vertrauensniveau (95%)
n = length(Gesamtmessung); % Anzahl der Messwerte
nu = n - 1; % Freiheitsgrade
t = tinv((1 + p) / 2, nu); % t-Quantil
uA = s * t / sqrt(n);  % Standardunsicherheit Typ A

%% Standardunsicherheit Typ B bestimmen
% Annahmen für Typ-B-Unsicherheit
time_resolution = 0.01;  % Zeitauflösung des Systems in Sekunden
taster_uncertainty = 0.02;  % Latenz des Tasters in Sekunden

% Typ-B-Unsicherheit
uB = sqrt((time_resolution^2 / 3) + (taster_uncertainty^2 / 3));  % Typ-B-Unsicherheit

%% Kombinierte Standardunsicherheit Typ C bestimmen
uC = sqrt(uA^2 + uB^2);  % Kombinierte Unsicherheit

%% Grad des Vertrauens bestimmen
k = 2;  % Vertrauensfaktor für 95% Konfidenzniveau

% Absolute Messunsicherheit bestimmen
uAbs = k * uC;

% Relative Messunsicherheit berechnen (%)
uRel = (uAbs / R) * 100;

%% Ergebnisdarstellung Typ C
figure;
yline(R, 'Color', 'k', 'DisplayName', 'Mittelwert');
yline(5.14, 'Color', 'g', 'DisplayName', 'Referenzwert Oszilloskop (5.14s)');
xlim([0 n]);
grid on;
hold on;
plot([0 n], [R + uC R + uC], '--b', [0 n], [R - uC R - uC], '--b', 'DisplayName', 'Unsicherheit Typ C');
plot(1:n, Gesamtmessung, '*-', 'DisplayName', 'Messwerte');  % Mittelwerte plotten
xlabel('Anzahl der Messpunkte');
ylabel('Zeit in s');
xlim([1 5])
ylim([5.05 5.25]);
title(['Messergebnis der Zeitmessung (Mittelwert = ', num2str(R), 's, Unsicherheit = \pm', num2str(uC), 's, ', num2str(uRel), '%)']);
grid on;
legend;



Die Ergebnisse der Untersuchung sind sowohl visuell als auch numerisch dargestellt:

Das Messergebnis in Abbildung 32 zeigt, dass der Abstandssensor über aufgenommene 6 Messungen hinweg einen Mittelwert von 10,066 cm bei einer kombinierten Messunsicherheit von ±0,57735 cm (11,47 %) liefert. Die Unsicherheiten resultieren aus den statistischen Schwankungen der Messwerte (Typ A) und der Fehlergrenze des Referenzwerkzeugs, einem Zollstock mit Genauigkeitsklasse 3 (Typ B). Die Messwerte streuen gleichmäßig um den Mittelwert und liegen vollständig innerhalb der berechneten Unsicherheitsgrenzen. Aufgrund der Fehlergrenze des Referenzwerkzeugs wird das Messergebnis als verwertbar eingestuft.

DRUCKSENSOR


Die durchgeführte Zeitmessung zeigt einen Mittelwert von 5,132 Sekunden mit einer kombinierten Messunsicherheit (Typ C) von ±0,025796 Sekunden und einer relativen Unsicherheit von 1,0053 %. Ein Referenzwert von 5,14 Sekunden, gemessen mit einem Oszilloskop, wurde zur Validierung herangezogen und zeigt die hohe Genauigkeit der Messung. Die Typ-B-Unsicherheit berücksichtigt dabei nicht nur systematische Fehler, sondern auch die Simulationsschrittweite, um eine präzise Bewertung zu gewährleisten. Das Ergebnis ist sehr präzise und bestätigt, dass das Messsystem zuverlässig arbeitet und alle Anforderungen erfüllt.

Umsetzung HW (mechanisch)

Für die mechanische Umsetzung des Projekts wurde ein Gehäuse entwickelt, das den Arduino, die Sensoren, den Buzzer und die erforderlichen Verkabelungen aufnimmt. Dieses Gehäuse ist so konzipiert, dass es sich für Wartungszwecke öffnen lässt. Nach einer initialen Skizze und Diskussion mit den Projektbeteiligten wurde ein finales Design festgelegt, das auch zusätzliche Komponenten wie eine IR-Reflexionsplatte und Gewichte für die Abstands- und Gewichtsmessung integriert.

Das Gehäuse wurde anhand der Zeichnungen in SolidWorks erstellt, als Baugruppe modelliert und anschließend als 3D-Render visualisiert. Die gedruckten Teile entsprechen den in dem Video gezeigten Komponenten.
Abb. 17: 3D Darstellung des Projektes

Gehäuse

Im nachfolgenden wird das Gehäuse, sowie sein Deckel näher beschrieben. Das Gehäuse besitzt eine Wandstärke von vier Millimetern, um dem Druck standzuhalten, der durch das Betätigen des Buttons entsteht und um die verbauten Sensoren und Bauteile zu schützen. Diese Wandung zieht sich bis zum Boden des Gehäuses, wodurch verhindert wird, dass der Druck auf den Gehäusedeckel weitergeleitet wird. Zusätzlich sind die Ecken des Gehäuses verstärkt, da in diesen Bereichen eine höhere Belastung auftritt als an den Außenflächen. Der Boden des Gehäuses wird von unten in das Gehäuse eingeschraubt. Eine umlaufende Kante sorgt dafür, dass der Boden nicht in das Gehäuse rutschen kann und die auftretenden Kräfte gleichmäßig verteilt werden. Gleichzeitig wird durch diese Konstruktion eine lückenlose Verbindung geschaffen, die das Eindringen von Verschmutzungen verhindert. Die Schrauben zur Befestigung des Bodens sind in die Bodenplatte eingelassen und greifen in die verstärkten Seitenwände des Gehäuses.
Die Oberseite des Gehäuses ist stufig gestaltet, um den Kräften, die durch das Betätigen des Tasters entstehen, gerecht zu werden. Dieses Design gewährleistet ein hohes Maß an Stabilität bei gleichzeitiger Einsparung von Material. Auch das Innere des Gehäuses wurde mit Bedacht entworfen. Es verfügt über spezielle Aussparungen, die das Einsetzen und die sichere Positionierung verschiedener Komponenten ermöglichen. Für den Taster sowie den IR-Sensor und die LEDs wurden präzise Öffnungen geschaffen, die eine einfache Montage sicherstellen.
Besonders hervorzuheben sind die Aussparungen für die 7-Segment-Anzeigen. Diese Anzeigen werden von hinten fixiert, um ein Hineinfallen zu verhindern und einen gleichmäßigen Abstand sicherzustellen. Die Gestaltung der Aussparungen erlaubt es, die Pins der Anzeigen ins Innere des Gehäuses zu führen, wo sie verkabelt werden können. Alternativ ist auch eine vorherige Verkabelung der Anzeigen möglich, die anschließend in das Gehäuse eingesetzt werden können, was den Zusammenbau erleichtert.
An der Seite des Gehäuses befindet sich ein zusätzlicher Anbau, der die Gewichte sicher hält, um ein Umkippen zu verhindern. Dieser Anbau gewährleistet zudem, dass der Drucksensor stets an der richtigen Stelle positioniert ist. Ein schmaler Kanal im Anbau leitet die Kabel des Drucksensors in das Innere des Gehäuses, ohne dabei die Funktionalität oder die Stabilität zu beeinträchtigen. Auf der Rückseite des Gehäuses wurden zwei Aussparungen integriert, die den Anschluss der Spannungsversorgung und des Programmierkabels des Arduino ermöglichen.

Weitere 3D Teile

Neben dem Gehäuse wurden ebenfalls eine Reflektionsplatte für die Entfernungsschätzung und Gewichte für die Gewichtsschätzung entwickelt. Die Reflektionsplatte ist in ihrer Größe und Dicke so gestaltet, dass sie nicht nur robust ist, sondern auch ein gewisses Gewicht aufweist, um stabil und sicher auf einem Tisch stehen zu können. Die Dimensionen der Platte wurden so gewählt, dass sie eine ausreichend große Fläche bietet, damit der Sensor sie zuverlässig erfassen kann. Zusätzlich sorgen die integrierten Standbeine der Platte für eine hohe Stabilität, wodurch ein Verrutschen während der Messung verhindert wird.

Die Gewichte wurden präzise an die Aussparung des Gehäuseauslegers angepasst und fügen sich passgenau in die dafür vorgesehene Halterung ein. Jedes Gewicht besteht aus einem hohlen Unterteil und einem Deckel. Das Unterteil wird mit einem spezifischen Gewichtsmaterial befüllt und sobald die Kombination aus Unterteil und Deckel das gewünschte Gewicht erreicht, werden die beiden Teile miteinander verklebt. Diese Verklebung stellt sicher, dass das Gewicht nicht mehr verändert werden kann, da eine Veränderung des Gewichts die Funktionsfähigkeit des Systems beeinträchtigen könnte. Die drei entwickelten Gewichte besitzen dieselbe äußere Form und Größe, unterscheiden sich jedoch in ihrem jeweiligen Gewicht. Das Design der Gewichte orientiert sich an klassischen Wiegegewichten, um eine einfache Handhabung und eine intuitive Nutzung zu ermöglichen.

Abschließend wurde bei der Gestaltung aller Teile darauf geachtet, dass sämtliche Kanten durch abgerundete Formen ersetzt wurden. Diese Rundungen tragen nicht nur zu einer angenehmen Haptik bei, sondern minimieren auch das Risiko von Verletzungen bei der Handhabung.

Umsetzung HW (elektrisch)

Verdrahtungsplan und Schaltplan

Abb. 22: Verdrahtungsplan
Abb. 23: Schaltplan (mit Multisim (siehe Versionen))


In Abbildung 22 befindet sich der Verdrahtungsplan des Projektes. In dem gezeigten Schaltplan in Abbildung 23 dienen die Netzbezeichnungen zur logischen Verbindung und Organisation der Signale zwischen verschiedenen Bauteilen. Diese Netzbezeichnungen ermöglichen es, dass elektrische Signale klar und übersichtlich an verschiedenen Stellen des Schaltplans verwendet werden können, ohne dass jede Leitung physisch durchgezeichnet werden muss. Dadurch wird der Schaltplan übersichtlicher, da wichtige Signalpfade und Verbindungen benannt und nachvollziehbar gestaltet werden. Die einzelnen Komponenten wurden zu Gruppen geordnet und mit deren Funktion beschriftet.

Anbindung des Tasters

Abb. 24: Pullup-Widerstand [2]

Im Schaltplan ist die Anbindung des Tasters dargestellt. Um im nicht-geschaltetem Zustand ein definiertes Potential zu gewährleisten, wird ein Pullup-Widerstand von 10 kOhm verwendet, die die Leitung auf einen logischen High-Pegel bzw. 5V ziehen. Bei Betätigung des Tasters wird die Spannung auf GND gezogen, was einen logischen LOW-Pegel am entsprechenden digitalen Pin des Arduinos Mega bewirkt, wie es in Abbildung 24 dargestellt ist [2].

Berechnung der Vorwiderstände der LEDs

Um den Strom, der durch die LED fließt, zu begrenzen, wird ein Vorwiderstand benötigt. Dieser Vorwiderstand schützt die LED vor Beschädigung durch Überstrom und sorgt dafür, dass der Strom innerhalb der zulässigen Grenzen bleibt. Die Berechnung des Vorwiderstands erfolgt nach folgender Formel [1]:

Aus den Datenblättern des Arduino Mega und der LEDs lassen diese Werte ermitteln:

  • die Betriebsspannung (hier 5V),
  • die Vorwärtsspannung der LED (hier 2V),
  • der Strom durch die LED (hier 20 mA).

Der benötigte Vorwiderstand beträgt also 150 Ohm.

Umsetzung und Montage sämtlicher Komponenten

Abb. 25: Aufbau einer Adapterplatine für den Arduino Mega 2560
Abb. 26: Montage der Adapterplatine mit dem Gehäuse und den elektrischen Komponenten


In Abbildung 25 wird der Aufbau der Adapterplatine gezeigt, die speziell für den Einsatz mit einem Arduino Mega 2560 und den elektrischen Komponenten des Projektes entwickelt wurde.

  • Oberseite der Platine:
    • Die Platine verfügt über drei Decoder für die 7-Segment Anzeigen, die mit den Bezeichnungen U8, U7 und U3 gekennzeichnet sind.
    • Drei Steckverbindungen sind mit jeweils 7 Pins für die 7-Segment-Anzeigen vorgesehen.
    • Ein akustischer Signalgeber (Buzzer, mit der Bezeichnung U9) und der Pullup-Widerstand (R4, 10kΩ) für den Taster sind ebenfalls integriert.
    • Spannungsversorgung: +5V und GND sind klar definiert und auf der Platine gekennzeichnet.
    • Pinbelegung: Die Pins D26, D28, A2, A1 und A0 sind spezifisch hervorgehoben und stellen wichtige Anschlusspunkte für die Steuerung und den Signaleingang dar.
  • Unterseite der Platine:
    • Hier sind die Lötverbindungen zu sehen, die die elektrische Verbindung zwischen den Komponenten herstellen.
    • Es sind mehrere blaue und orangefarbene Leitungen sichtbar, die gezielt für die Signal- und Spannungsübertragung verlegt wurden.
    • Die Spannungsleitungen (+5V und GND) sind klar gekennzeichnet, um eine korrekte Polung zu gewährleisten.

In Abbildung 26 wird die Adapterplatine in einem Gehäuse montiert gezeigt:

  • Die Adapterplatine ist auf dem Arduino Mega 2560 aufgesteckt.
  • Mehrere farbige Kabel sind angeschlossen, um die Verbindung zu externen Komponenten herzustellen.
  • Die Verkabelung ist beschriftet, um eine einfache Identifikation der Verbindungen zu ermöglichen (z. B. A0, D26).

Umsetzung SW

Verwendete Toolbox: DSP System Toolbox, Simulink Support Package für Arduino Hardware

Zusammenspiel der Komponenten und Module

Abb. 28: PaP von der Zeit-,Entfernungs- und Gewichtsschätzung
Abb. 27: Simulink Modell des Projektes

In der Abbildung 27 ist das Simulinkmodell des Projektes abgebildet. Daraus lässt sich das Zusammenspiel aller Softwarekomponenten und deren Verbindungen nachvollziehen. Es bietet einen strukturierten Überblick über die gesamte Systemarchitektur und die logischen Verknüpfungen zwischen den Modulen. Dieses Modell dient als zentrale Grundlage für die Implementierung der Steuerungslogik und erleichtert das Verständnis der Signalflüsse im System. Alle Softwaremodule werden im weiteren Verlauf genau erläutert, sodass diese Abbildung vor allem der Orientierung dient.

In Abbildung 28 ist der Stateflow des Projektes dargestellt. Der Stateflow bildet die zustandsbasierte Logik des Systems ab und zeigt die Abfolge und Bedingungen für Übergänge zwischen verschiedenen Zuständen. Hier werden zeitliche Abläufe, Sensorinteraktionen und Aktionen definiert, die für den Betrieb des Systems erforderlich sind. Durch die Visualisierung des Stateflows wird die Dynamik der Systemsteuerung verständlich gemacht und ermöglicht eine detaillierte Analyse und Weiterentwicklung der Logik.

Umrechnung des Digitalwerts in Volt der beiden Sensoren (Drucksensor und IR-Sensor)

Im Simulink-Modell werden die analogen Sensorwerte als Digitalwert erfasst und durch ein Gain, innerhalb von Matlab Simulink, in Volt umgerechnet. Die Sensoren liefern einen 10-Bit-Digitalwert, der von 0 bis 1023 reicht und mit einer Referenzspannung von 5V arbeitet. Dieser Wert wird vom Analog-Digital-Wandler (ADC) des Arduino aufgenommen. Um den Digitalwert in Volt umzurechnen, wird folgender Berechnungsschritt durchgeführt:


Der resultierende V-Wert wird anschließend gefiltert und im Modell für weitere Berechnungen verwendet.

Eingabe

In der Eingabe werden sowohl die einzelnen Eingabeelemente beschrieben als auch die Sensorauswertung und die damit verbundene Messunsicherheit analysiert.

Signalverarbeitung für den IR-Sensor (GP2Y0A41SK0F)

Abb. 29: Simulink Modell der Abstandssensorik
Abb. 30: Zusammenhang zwischen Spannung und Distanz des GP2Y0A41SK0F
Abb. 31: Signalfilterung mithilfe eines Medianfilters der Größe 30

Das analoge Ausgangssignal des Sensors wird vom Arduino am Pin 2 in ein Digitalwort umgewandelt, wie es in der Abbildung 29 dargestellt ist. Dieses Digitalwort wird anschließend in eine Spannung konvertiert, wie zuvor beschrieben. Um das Signal zu glätten und Störspitzen zu eliminieren, erfolgt eine Filterung mithilfe eines Medianfilters. Im nächsten Schritt wird die gemessene Spannung mithilfe der Kalibrierung des Sensors in einen Abstand in Zentimetern umgerechnet. Die Kalibrierdaten sind in Tabelle 7 aufgeführt und in Abbildung 30 grafisch dargestellt. Dieser Zusammenhang wird in Simulink durch eine 1D-Lookup-Tabelle umgesetzt, die die Zuordnung der gemessenen Spannung zur entsprechenden Distanz vornimmt.

Werte für die Lookup Table:

% Daten für die Distanz
IR_distances = [4, 5.5, 7, 8.5, 10, 12, 14, 16, 18, 22, 26, 30]; % Entfernung in cm
% Spannung für das schwarze Messobjekt
IR_voltages = [3.319, 2.535, 2.028, 1.672, 1.408, 1.168, 0.9827, 0.8602, 0.7429, 0.6256, 0.5523, 0.5327]; % Spannung in V

Anschließend erfolgt die Analyse der Messspitzen und Einsatz eines Medianfilters.

Bei der Verarbeitung der Ausgangsdaten des Infrarotsensors GP2Y0A41SK0F wurden ohne Filterung deutliche Schwankungen und zyklische Spikes festgestellt (siehe Abbildung 31). Diese resultieren aus Instabilitäten während der periodischen Berechnung und Aktualisierung des Ausgangssignals, wie in der technischen Dokumentation beschrieben. Die ungefilterten Schwankungen beeinträchtigen die Genauigkeit und Zuverlässigkeit der Messwerte, was vor allem in Anwendungen, die stabile Distanzdaten erfordern, problematisch ist.

Um diese Störungen zu minimieren, wurde ein Medianfilter implementiert:

  • Vorteile des Medianfilters:
    • Eignet sich besonders gut zur Eliminierung von Ausreißern.
    • Ignoriert extreme Abweichungen und bewahrt den zentralen Verlauf des Signals.
  • Filtergröße (30 Werte):
    • Effektive Glättung: Reduziert Spikes und Rauschen erheblich.
    • Minimale Verzögerung: Reaktionszeit bleibt für Echtzeitanwendungen akzeptabel.

Das Ergebnis zeigt, dass der Medianfilter die Spikes zuverlässig entfernt und ein robustes, geglättetes Signal erzeugt (siehe Abbildung 31).

Signalverarbeitung des Tasters

Abb. 32: Simulink Modell der Tasterauswertung
Abb. 33: Eingangssignal des Tasters mit und ohne Entprellung [2]
Abb. 34: Taster-Signal

Das vorgestellte Modell in Abbildung 32 dient der Auswertung eines mechanischen Tasters, der an einem Arduino-Mikrocontroller angeschlossen ist. Dabei wird das analoge Signal des Tasters am Pin A0 eingelesen und in eine digitale Ausgabe übersetzt. Zunächst erfolgt eine Umwandlung des digitalen Eingangswerts (Bereich 0–1023) in eine Spannung in Volt, indem das Signal mit einem Faktor von 5/1023 skaliert wird. Anschließend wird der umgerechnete Spannungswert in einer Statusabfrage mit einem Schwellenwert von 2V verglichen. Wenn der Spannungswert kleiner oder gleich 2V ist, wird ein LOW-Zustand erkannt, andernfalls ein HIGH-Zustand. Das Ergebnis wird als digitales Signal weitergegeben und kann für die Steuerung anderer Prozesse genutzt werden.

Eine zusätzliche Entprellung des Tasters ist in diesem Modell nicht implementiert, da der verwendete Taster bereits durch einen 10-kOhm-Pullup-Widerstand hardwareseitig entprellt wird. Dieser Pullup-Widerstand sorgt dafür, dass der Eingang des Mikrocontrollers im unbetätigten Zustand zuverlässig auf HIGH gezogen wird und beim Betätigen des Tasters auf LOW schaltet. Mechanische Prellvorgänge, die durch Vibrationen der Tasterkontakte entstehen können, werden durch die Stabilisierung des Signals mithilfe des Widerstands minimiert. Da die durch den Widerstand erreichte Stabilisierung ausreicht, wird das Signal bereits so geglättet, dass der Mikrocontroller keine Mehrfachimpulse registriert. Daher ist eine zusätzliche Entprellung in der Software überflüssig. Das daraus entstehende Signal des Tasters ist aus Abbildung 34 zu entnehmen. Diese effiziente Hardwarelösung spart Speicherplatz und Rechenleistung, während sie gleichzeitig eine zuverlässige Funktionalität gewährleistet [2].

Signalverarbeitung des Drucksensors

Abb. 35: Simulink Modell der Gewichtsmessung

Das gezeigte Simulink-Modell in Abbildung 35 dient der Verarbeitung von Drucksensor-Daten, die über einen Arduino eingelesen werden, um sie in Gewichtswerte umzuwandeln. Zunächst wird das analoge Signal des Sensors vom Arduino als digitaler Wert erfasst (0–1023). Dieser Wert wird dann mithilfe eines Gain-Blocks in eine Spannung von 0V bis 5V umgerechnet. Um Messrauschen zu reduzieren, durchläuft das Signal anschließend einen Median-Filter, der unerwünschte Störimpulse entfernt und das Signal glättet. Die gefilterte Spannung wird schließlich durch eine 1-D Lookup Table in ein Gewicht umgewandelt.

Werte für die Lookup Table aus der Kalibrierung:

% Daten für das Gewicht
Drucksensor_Gewicht = [2000 1600 1400 1200 1000 800 600 400 200 150 100 50]; % Gewicht in g
% Spannung 
Drucksensor_Spannung = [0.5654 0.5414 0.4713 0.4545 0.4243 0.3978 0.3638 0.3183 0.2547 0.2215 0.1960 0.1133]; % Spannung in V

Timer

Abb. 38: Timer zur Zeitmessung und Taktung
Abb. 39: Aufbau der Timer-Funktion

Der Timer enthält einen Timerbaustein und eine Auswertung ob das Ziel der von 10s erreicht wurde oder nicht. Alle Parameter werden ausgegegen.

Der Ablauf des Timerbausteins wird im folgendem erläutert:

  1. Initialisierung: Der Timer startet im Zustand Idle und wartet, bis StartMeasurement auf 1 gesetzt wird.
  2. Start des Timers: Bei StartMeasurement == 1 wird der Timer in den Zustand TimerRunning versetzt, und die Zeitmessung beginnt (ElapsedTime wird kontinuierlich um 0.01 erhöht).
  3. Stopp des Timers: Wenn StartMeasurement wieder auf 0 gesetzt wird, kehrt der Timer in den Zustand Idle zurück, und die Zeitmessung stoppt.

Ausgabe

Ansteuerung der 7-Segment-Anzeigen

Die Ansteuerung der 7-Segment-Anzeige erfolgt über einen 7-Segment-Decoder, wie den 74HC47, der in Abbildung 14 des Schaltbildes dargestellt ist. Diese Decoder sind dafür konzipiert, binäre Eingaben (BCD – Binary Coded Decimal) in Steuersignale für die sieben Segmente (1-8) der Anzeige umzuwandeln. Die genaue Zuordnung und Ansteuerung der Pins ist in Tabelle 07 aufgeführt.

Die Tabelle zeigt die Steuerung einer 7-Segment-Anzeige. Sie enthält Binärwerte (D3, D2, D1, D0), die die verschiedenen Ziffern von 0 bis 9 darstellen, und gibt an, welche Segmente (a bis g) der Anzeige aktiviert ("H" = High) oder deaktiviert ("L" = Low) sind, um die jeweilige Ziffer anzuzeigen.

  • D3 bis D0 sind die BCD-Eingaben (binär codierte Dezimalzahlen).
  • a bis g repräsentieren die Segmente der 7-Segment-Anzeige, die durch die jeweilige Kombination von High- und Low-Signalen angesteuert werden.
  • Die letzte Spalte „Display“ zeigt die entsprechende Zahl, die auf der Anzeige dargestellt wird.

Zum Beispiel:

  • Für „0“ (D3: L, D2: L, D1: L, D0: L) werden die Segmente a, b, c, d, e und f aktiviert, g bleibt deaktiviert.
  • Für „1“ (D3: L, D2: L, D1: L, D0: H) sind nur die Segmente b und c aktiviert.
Tabelle 7: Funktionale Tabelle zur Ansteuerung
D3 D2 D1 D0 a b c d e f g Display
L L L L H H H H H H L 0
L L L H L H H L L L L 1
L L H L H H L H H L H 2
L L H H H H H H L L H 3
L H L L L H H L L H H 4
L H L H H L H H L H H 5
L H H L L L H H H H H 6
L H H H H H H L L L L 7
H L L L H H H H H H H 8
H L L H H H H L L H H 9
H L H L L L L L L L L blank

Diese Tabelle wird mithilfe einer S-Funktion in Matlab-Simulink umgesetzt, dazu wird das S-Function Basic Template (sfuntmpl_basic.c) von Simulink verwendet und erweitert. Die erweiterte Funktion mit der Bezeichnung sfun_SetLogicalValueForSevenSegementDisp ließt eine Zahl ein, und separiert die einzelnen Ziffern und setzt daraufhin die Bits. Hier ist der C-Code der S-Function hinterlegt:

//%*************************************************************** *
//%                   Hochschule Hamm-Lippstadt                    *
//%*************************************************************** *
//% Modul	        : sfun_SetLogicalValueForSevenSegementDisp.c   *
//%                                                                *
//% Datum           : 18.11.2024                                   *
//%                                                                *
//% Funktion        : Drei 7-Segment-Decoder steuern und die       *
//%                   jeweiligen vier Bits setzten für das Output  *
//%                                                                *
//% Implementation  : MATLAB 2023b                                 *
//%                                                                *
//% Req. Toolbox    : -                                            *
//%                                                                *
//% Author          : Oliver Scholze, Niklas Reeker, Johann Kismann*
//%                                                                *
//% Anpassung in    : mdlInitializeSizes(SimStruct *S)             *
//%                   mdlOutputs(SimStruct *S, int_T tid)          *
//%                                                                *
//% Letzte Änderung : 18.11.2024                                   *
//%****************************************************************


/*
 * Modul: sfun_SetLogicalValueForSevenSegementDisp
 * Funktion: Vier Bits der 7-Segement-Decoder setzen 
 * Angepasste Funktionen: static void mdlInitializeSizes(SimStruct *S); 
 */


/*
 * You must specify the S_FUNCTION_NAME as the name of your S-function
 * (i.e. replace sfuntmpl_basic with the name of your S-function).
 */

#define S_FUNCTION_NAME  sfun_SetLogicalValueForSevenSegementDisp
#define S_FUNCTION_LEVEL 2

/*
 * Need to include simstruc.h for the definition of the SimStruct and
 * its associated macro definitions.
 */
#include "simstruc.h"



/* Error handling
 * --------------
 *
 * You should use the following technique to report errors encountered within
 * an S-function:
 *
 *       ssSetErrorStatus(S,"Error encountered due to ...");
 *       return;
 *
 * Note that the 2nd argument to ssSetErrorStatus must be persistent memory.
 * It cannot be a local variable. For example the following will cause
 * unpredictable errors:
 *
 *      mdlOutputs()
 *      {
 *         char msg[256];         {ILLEGAL: to fix use "static char msg[256];"}
 *         sprintf(msg,"Error due to %s", string);
 *         ssSetErrorStatus(S,msg);
 *         return;
 *      }
 *
 */

/*====================*
 * S-function methods *
 *====================*/

/* Function: mdlInitializeSizes ===============================================
 * Abstract:
 *    The sizes information is used by Simulink to determine the S-function
 *    block's characteristics (number of inputs, outputs, states, etc.).
 */
static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, 0);  /* Number of expected parameters */
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        /* Return if number of expected != number of actual parameters */
        return;
    }

    ssSetNumContStates(S, 0);
    ssSetNumDiscStates(S, 0);

    if (!ssSetNumInputPorts(S, 1)) return;
    ssSetInputPortWidth(S, 0, 1);
    ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/
    /*
     * Set direct feedthrough flag (1=yes, 0=no).
     * A port has direct feedthrough if the input is used in either
     * the mdlOutputs or mdlGetTimeOfNextVarHit functions.
     */
    ssSetInputPortDirectFeedThrough(S, 0, 1);

    if (!ssSetNumOutputPorts(S, 12)) return;
    ssSetOutputPortWidth(S, 0, 1);
    ssSetOutputPortWidth(S, 1, 1);
    ssSetOutputPortWidth(S, 2, 1);
    ssSetOutputPortWidth(S, 3, 1);

    ssSetOutputPortWidth(S, 3, 1);
    ssSetOutputPortWidth(S, 5, 1);
    ssSetOutputPortWidth(S, 6, 1);
    ssSetOutputPortWidth(S, 7, 1);

    ssSetOutputPortWidth(S, 8, 1);
    ssSetOutputPortWidth(S, 9, 1);
    ssSetOutputPortWidth(S, 10, 1);
    ssSetOutputPortWidth(S, 11, 1);

    ssSetNumSampleTimes(S, 1);
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);

    /* Specify the operating point save/restore compliance to be same as a 
     * built-in block */
    ssSetOperatingPointCompliance(S, USE_DEFAULT_OPERATING_POINT);

    ssSetOptions(S, 0);
}



/* Function: mdlInitializeSampleTimes =========================================
 * Abstract:
 *    This function is used to specify the sample time(s) for your
 *    S-function. You must register the same number of sample times as
 *    specified in ssSetNumSampleTimes.
 */
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);

}



#define MDL_INITIALIZE_CONDITIONS   /* Change to #undef to remove function */
#if defined(MDL_INITIALIZE_CONDITIONS)
  /* Function: mdlInitializeConditions ========================================
   * Abstract:
   *    In this function, you should initialize the continuous and discrete
   *    states for your S-function block.  The initial states are placed
   *    in the state vector, ssGetContStates(S) or ssGetRealDiscStates(S).
   *    You can also perform any other initialization activities that your
   *    S-function may require. Note, this routine will be called at the
   *    start of simulation and if it is present in an enabled subsystem
   *    configured to reset states, it will be call when the enabled subsystem
   *    restarts execution to reset the states.
   */
  static void mdlInitializeConditions(SimStruct *S)
  {
  }
#endif /* MDL_INITIALIZE_CONDITIONS */



#define MDL_START  /* Change to #undef to remove function */
#if defined(MDL_START) 
  /* Function: mdlStart =======================================================
   * Abstract:
   *    This function is called once at start of model execution. If you
   *    have states that should be initialized once, this is the place
   *    to do it.
   */
  static void mdlStart(SimStruct *S)
  {
  }
#endif /*  MDL_START */



/* Function: mdlOutputs =======================================================
 * Abstract:
 *    In this function, you compute the outputs of your S-function
 *    block.
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{
    const real_T *number = (const real_T*) ssGetInputPortSignal(S,0);

    real_T       *Xxx_D3 = ssGetOutputPortSignal(S,0);
    real_T       *Xxx_D2 = ssGetOutputPortSignal(S,1);
    real_T       *Xxx_D1 = ssGetOutputPortSignal(S,2);
    real_T       *Xxx_D0 = ssGetOutputPortSignal(S,3);

    real_T       *xXx_D3 = ssGetOutputPortSignal(S,4);
    real_T       *xXx_D2 = ssGetOutputPortSignal(S,5);
    real_T       *xXx_D1 = ssGetOutputPortSignal(S,6);
    real_T       *xXx_D0 = ssGetOutputPortSignal(S,7);

    real_T       *xxX_D3 = ssGetOutputPortSignal(S,8);
    real_T       *xxX_D2 = ssGetOutputPortSignal(S,9);
    real_T       *xxX_D1 = ssGetOutputPortSignal(S,10);
    real_T       *xxX_D0 = ssGetOutputPortSignal(S,11);

    /* Nummer in ihre Ziffern aufteilen und Gleitkommazahl zu Ganzzahl casten */
    int num_Xxx = (int)number[0] / 100;          // Erste Ziffer (Hunderterstelle)
    int num_xXx = ((int)number[0] / 10) % 10;    // Zweite Ziffer (Zehnerstelle)
    int num_xxX = (int)number[0] % 10;           // Dritte Ziffer (Einerstelle)

   /* Switch Case Anweisung für die erste Zahl Xxx */  
    switch (num_Xxx) {
        case 0:
           Xxx_D3[0] = 0;
           Xxx_D2[0] = 0;
           Xxx_D1[0] = 0;
           Xxx_D0[0] = 0;
           break;
        case 1:
           Xxx_D3[0] = 0;
           Xxx_D2[0] = 0;
           Xxx_D1[0] = 0;
           Xxx_D0[0] = 1;
           break;
        case 2:
           Xxx_D3[0] = 0;
           Xxx_D2[0] = 0;
           Xxx_D1[0] = 1;
           Xxx_D0[0] = 0;
           break;
        case 3:
           Xxx_D3[0] = 0;
           Xxx_D2[0] = 0;
           Xxx_D1[0] = 1;
           Xxx_D0[0] = 1;
           break;
        case 4:
           Xxx_D3[0] = 0;
           Xxx_D2[0] = 1;
           Xxx_D1[0] = 0;
           Xxx_D0[0] = 0;
           break;
        case 5:
           Xxx_D3[0] = 0;
           Xxx_D2[0] = 1;
           Xxx_D1[0] = 0;
           Xxx_D0[0] = 1;
           break;
        case 6:
           Xxx_D3[0] = 0;
           Xxx_D2[0] = 1;
           Xxx_D1[0] = 1;
           Xxx_D0[0] = 0;
           break;
        case 7:
           Xxx_D3[0] = 0;
           Xxx_D2[0] = 1;
           Xxx_D1[0] = 1;
           Xxx_D0[0] = 1;
           break;
        case 8:
           Xxx_D3[0] = 1;
           Xxx_D2[0] = 0;
           Xxx_D1[0] = 0;
           Xxx_D0[0] = 0;
           break;
        case 9:
           Xxx_D3[0] = 1;
           Xxx_D2[0] = 0;
           Xxx_D1[0] = 0;
           Xxx_D0[0] = 1;
           break;
       default:
           /* Bei ungültiger Zahl blank Anzeigen */
           Xxx_D3[0] = 1;
           Xxx_D2[0] = 0;
           Xxx_D1[0] = 1;
           Xxx_D0[0] = 0;
           break;}

     /* Switch Case Anweisung für die zweite Zahl xXx */                                           
     switch (num_xXx) {
        case 0:
           xXx_D3[0] = 0;
           xXx_D2[0] = 0;
           xXx_D1[0] = 0;
           xXx_D0[0] = 0;
           break;
        case 1:
           xXx_D3[0] = 0;
           xXx_D2[0] = 0;
           xXx_D1[0] = 0;
           xXx_D0[0] = 1;
           break;
        case 2:
           xXx_D3[0] = 0;
           xXx_D2[0] = 0;
           xXx_D1[0] = 1;
           xXx_D0[0] = 0;
           break;
        case 3:
           xXx_D3[0] = 0;
           xXx_D2[0] = 0;
           xXx_D1[0] = 1;
           xXx_D0[0] = 1;
           break;
        case 4:
           xXx_D3[0] = 0;
           xXx_D2[0] = 1;
           xXx_D1[0] = 0;
           xXx_D0[0] = 0;
           break;
        case 5:
           xXx_D3[0] = 0;
           xXx_D2[0] = 1;
           xXx_D1[0] = 0;
           xXx_D0[0] = 1;
           break;
        case 6:
           xXx_D3[0] = 0;
           xXx_D2[0] = 1;
           xXx_D1[0] = 1;
           xXx_D0[0] = 0;
           break;
        case 7:
           xXx_D3[0] = 0;
           xXx_D2[0] = 1;
           xXx_D1[0] = 1;
           xXx_D0[0] = 1;
           break;
        case 8:
           xXx_D3[0] = 1;
           xXx_D2[0] = 0;
           xXx_D1[0] = 0;
           xXx_D0[0] = 0;
           break;
        case 9:
           xXx_D3[0] = 1;
           xXx_D2[0] = 0;
           xXx_D1[0] = 0;
           xXx_D0[0] = 1;
           break;
       default:
           /* Bei ungültiger Zahl blank Anzeigen */
           xXx_D3[0] = 1;
           xXx_D2[0] = 0;
           xXx_D1[0] = 1;
           xXx_D0[0] = 0;
           break;}


     /* Switch Case Anweisung für die dritte Zahl xxX */                                           
     switch (num_xxX) {
        case 0: 
           xxX_D3[0] = 0;
           xxX_D2[0] = 0;
           xxX_D1[0] = 0;
           xxX_D0[0] = 0;
           break;
        case 1:
           xxX_D3[0] = 0;
           xxX_D2[0] = 0;
           xxX_D1[0] = 0;
           xxX_D0[0] = 1;
           break;
        case 2:
           xxX_D3[0] = 0;
           xxX_D2[0] = 0;
           xxX_D1[0] = 1;
           xxX_D0[0] = 0;
           break;
        case 3:
           xxX_D3[0] = 0;
           xxX_D2[0] = 0;
           xxX_D1[0] = 1;
           xxX_D0[0] = 1;
           break;
        case 4:
           xxX_D3[0] = 0;
           xxX_D2[0] = 1;
           xxX_D1[0] = 0;
           xxX_D0[0] = 0;
           break;
        case 5:
           xxX_D3[0] = 0;
           xxX_D2[0] = 1;
           xxX_D1[0] = 0;
           xxX_D0[0] = 1;
           break;
        case 6:
           xxX_D3[0] = 0;
           xxX_D2[0] = 1;
           xxX_D1[0] = 1;
           xxX_D0[0] = 0;
           break;
        case 7:
           xxX_D3[0] = 0;
           xxX_D2[0] = 1;
           xxX_D1[0] = 1;
           xxX_D0[0] = 1;
           break;
        case 8:
           xxX_D3[0] = 1;
           xxX_D2[0] = 0;
           xxX_D1[0] = 0;
           xxX_D0[0] = 0;
           break;
        case 9:
           xxX_D3[0] = 1;
           xxX_D2[0] = 0;
           xxX_D1[0] = 0;
           xxX_D0[0] = 1;
           break;
       default:
           /* Bei ungültiger Zahl blank Anzeigen */
           xxX_D3[0] = 1;
           xxX_D2[0] = 0;
           xxX_D1[0] = 1;
           xxX_D0[0] = 0;
           break;}
}



#define MDL_UPDATE  /* Change to #undef to remove function */
#if defined(MDL_UPDATE)
  /* Function: mdlUpdate ======================================================
   * Abstract:
   *    This function is called once for every major integration time step.
   *    Discrete states are typically updated here, but this function is useful
   *    for performing any tasks that should only take place once per
   *    integration step.
   */
  static void mdlUpdate(SimStruct *S, int_T tid)
  {
  }
#endif /* MDL_UPDATE */



#define MDL_DERIVATIVES  /* Change to #undef to remove function */
#if defined(MDL_DERIVATIVES)
  /* Function: mdlDerivatives =================================================
   * Abstract:
   *    In this function, you compute the S-function block's derivatives.
   *    The derivatives are placed in the derivative vector, ssGetdX(S).
   */
  static void mdlDerivatives(SimStruct *S)
  {
  }
#endif /* MDL_DERIVATIVES */



/* Function: mdlTerminate =====================================================
 * Abstract:
 *    In this function, you should perform any actions that are necessary
 *    at the termination of a simulation.  For example, if memory was
 *    allocated in mdlStart, this is the place to free it.
 */
static void mdlTerminate(SimStruct *S)
{
}


/*=============================*
 * Required S-function trailer *
 *=============================*/

#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif



Ansteuerung des Buzzers

Abb. 36: Ansteuerung des Buzzers





Ansteuerung der LEDs

Abb. 37: Simulink Modell zur Ansteuerung der LEDs

Die Abbildung 37 zeigt die Steuerung von zwei LEDs über einen Arduino. Die Zustände `Zustand_LED_IR` und `Zustand_LED_Druck` steuern die Pins 26 und 28, die jeweils die LED des IR-Sensors und die LED des Drucksensors aktivieren. Die LEDs blinken mit einer Frequenz von 25ms und zeigen an, wo man weiterspielen muss. Schafft man beispielsweise die Zeitschätzung, blinkt die LED über dem IR-Sensor um anzuzeigen, dass man mit der Entfernungsschätzung fortfahren soll.

Steuerung

Stateflow

Abb. 40: Zustandsautomat des Projektes
Abb. 41: Aufbau des Zustandsautomats

Das gezeigte Stateflow-Diagramm beschreibt den Ablauf eines Spiels, bei dem der Spieler nacheinander drei Aufgaben lösen muss: eine Zeit-, eine Entfernungs- und eine Gewichtsschätzung. Jede dieser Aufgaben wird in einem eigenen Modul dargestellt, die miteinander verbunden sind und jeweils durch unterschiedliche Zustände und Übergänge gesteuert werden. Der Timer spielt dabei eine zentrale Rolle, da er die Dauer der Anzeige von Zahlen und das Blinken der LEDs steuert.

Das Spiel beginnt im Modul zur Zeitschätzung, welches im Zustand 'TasterNichtGedrueckt' startet. Hier werden alle Variablen initialisiert, zum Beispiel: 'Gewonnen=0', 'disp_zahl_code=888', 'Melodie=0', 'Status=1'. Der Spieler muss den Taster gedrückt halten, um den Timer zu starten und damit die Zeit zu messen. Der Zustand wechselt zu 'TasterGedrueckt', solange der Taster gedrückt bleibt. Das Ziel ist es, den Taster möglichst genau 10 Sekunden lang zu halten. Sobald der Taster losgelassen wird, erfolgt die Auswertung. Ist die Zeit korrekt, wird der Zustand 'ZeitRichtig' erreicht. Hier wird eine Belohnungsmelodie abgespielt ('Melodie=2'), und die gehaltene Zeit ('ElapsedTime') wird angezeigt. War die Schätzung falsch, erfolgt der Übergang in den Zustand 'ZeitFalsch', wo eine Fehlermelodie abgespielt wird ('Melodie=1'), und das Spiel beginnt von vorne im ersten Modul.

Nach Abschluss der Zeitschätzung wechselt das Spiel in das Modul zur Entfernungsschätzung. In diesem Modul startet das Spiel im Zustand 'LED_An', in dem eine LED ein Signal gibt, während ein Timer für das Blinken der LED läuft. Der Spieler gibt seine Schätzung ab, indem er den Taster drückt, woraufhin der Zustand 'Auswertung' erreicht wird. Je nach Richtigkeit der Schätzung wird entweder der Zustand 'EntfernungRichtig' oder 'EntfernungFalsch' aktiviert. Bei einer korrekten Schätzung wird eine Belohnungsmelodie abgespielt ('Melodie=2'), und die geschätzte Entfernung ('Entfernung_cm') wird angezeigt. Bei einer falschen Schätzung erfolgt der Übergang in den Zustand 'EntfernungFalsch', wo eine Fehlermelodie abgespielt wird ('Melodie=1'), und das Spiel beginnt wieder im ersten Modul bei der Zeitschätzung.

Im letzten Modul, der Gewichtsschätzung, startet das Spiel im Zustand 'LED_An', wo ebenfalls eine LED als Signal dient und ein Timer das Blinken der LED steuert. Der Spieler drückt den Taster, um seine Schätzung abzugeben. Danach erfolgt die Auswertung. Wenn die Schätzung richtig ist, wechselt der Automat in den Zustand 'GewichtRichtig', wo eine Belohnungsmelodie abgespielt wird ('Melodie=2'), die geschätzte Gewichtsanzeige ('Gewicht_kg') erfolgt, und der Gewinn registriert wird ('Gewonnen=1'). Ist die Schätzung falsch, wird der Zustand 'GewichtFalsch' erreicht, wo eine Fehlermelodie abgespielt wird ('Melodie=1'), und das Spiel beginnt ebenfalls wieder im ersten Modul bei der Zeitschätzung.

Nach erfolgreicher Beendigung aller Module (korrekte Zeit-, Entfernungs- und Gewichtsschätzung) wechselt das Spiel in den Zustand 'Gewonnen'. Hier wird der Gewinncode ausgegeben und ein Timer gestartet ('StartTimer=1500'), der die Abschlussanimation steuert.

Komponententest

Durchführung der Komponententest

In den Komponententests werden sämtliche Funktionalitäten des Projekts einzeln geprüft, um sicherzustellen, dass jede Komponente ordnungsgemäß funktioniert, bevor der Stateflow validiert werden kann. Die Tabelle 8 dokumentiert die einzelnen Komponententests, einschließlich der jeweiligen Komponente, der durchgeführten Testmethoden, der erwarteten Ergebnisse sowie der gemessenen Ergebnisse. Dies ermöglicht eine umfassende Überprüfung der Funktionalität jeder Komponente.

Die Tests werden von einem Erstprüfer durchgeführt, wobei die Freigabe durch einen Zweitprüfer erfolgt. Zur besseren Nachvollziehbarkeit und Verständlichkeit des Prüfprozesses wird außerdem der Messaufbau detailliert dokumentiert.

Tabelle 8: Durchführung der Komponententest
Testcase Komponente Durchführung Erwartendes Ergebnis Gemessenes Ergebnis (rot = n.i.O., grün = i.O.) Erstprüfer Zweitprüfer Messaufbau
1 Taster Überprüfung der Betätigungsdauer eines mechanischen Tasters und Vergleich der gemessenen Zeiten zwischen einem externen Timer und der Softwaremessung. 5s+-10%, 10s+-10%, 15s+-10% 5,123s, 10,078s, 14,781s Johann Kismann Niklas Reeker
Abb. 42: Referenzwert mit dem Oszilloskop
2 IR-Sensor Überprüfung der Genauigkeit eines Infrarot-Abstandssensors durch Vergleich der gemessenen Abstände zwischen einem externen Messgerät (Lineal) und der Softwaremessung des Sensors. 8cm+-10%, 10cm+-10%, 15cm+-10%
Abb.: Auswertung des IR-Sensors
7.966cm, 10cm und 14.8cm
Oliver Scholze Johann Kismann
Abb. 43: Messaufbau für den Test des IR-Sensors
3 Drucksensor Überprüfung der Gewichtsmessung eines Drucksensors durch den Vergleich der gemessenen Gewichte mit externen Referenzgewichten und der Softwaremessung des Drucksensors. 100g+-10%, 150g+-10% 109g, 146g Niklas Reeker Oliver Scholze
Abb. 44: Messaufbau für den Test des Drucksensors
4 LEDs Überprüfung der Funktionalität von LEDs in dem System, um sicherzustellen, dass sie ordnungsgemäß leuchten. zwei LEDs leuchten zwei LED leuchten (siehe Messaufbau) Oliver Scholze Johann Kismann
Abb. 45: Erfolgreiche Ausgabe der dreistelligen Zahl
5 7-Segment-Anzeigen Überprüfung der korrekten Ausgabe einer dreistelligen Zahl durch das System, um sicherzustellen, dass die Zahl korrekt dargestellt und ohne Fehler übergeben wird. 580
Abb. 46: Erfolgreiche Ausgabe der dreistelligen Zahl
Oliver Scholze Niklas Reeker siehe Testergebnis
6 Ton Überprüfung der Tonausgabe eines Buzzers, indem eine Gewinner- und eine Verlierer-Melodie abgespielt wird. Ziel ist es sicherzustellen, dass der Buzzer die Melodien korrekt und klar wiedergibt. Melodie gewonnen und verloren Melodie gewonnen und verloren Niklas Reeker Johann Kismann keine Darstellung

Im Rahmen des Komponententests wurden verschiedene Systeme und Sensoren überprüft, um deren Funktionalität, Genauigkeit und Zuverlässigkeit zu bewerten. Die Tests umfassten:

  1. Taster: Die Betätigungsdauer eines mechanischen Tasters wurde gemessen und mit einem externen Timer verglichen. Die gemessenen Zeiten lagen innerhalb der erwarteten Toleranzen, was auf eine präzise Messung hinweist.
  2. IR-Sensor: Die Genauigkeit eines Infrarot-Abstandssensors wurde durch den Vergleich der gemessenen Abstände mit einem externen Referenzgerät (Lineal) überprüft. Die Abweichungen blieben innerhalb der spezifizierten Toleranzen von ±10 %, was die Zuverlässigkeit des Sensors bestätigt.
  3. Drucksensor: Der Drucksensor wurde durch den Vergleich gemessener Gewichte mit Referenzgewichten getestet. Die Messwerte zeigten geringe Abweichungen, die innerhalb der spezifizierten Toleranzen lagen.
  4. LEDs: Die LEDs wurden erfolgreich auf ihre Funktionalität überprüft, und beide LEDs leuchteten ordnungsgemäß.
  5. 7-Segment-Anzeige: Die korrekte Darstellung einer dreistelligen Zahl wurde überprüft, wobei die Anzeige fehlerfrei funktionierte.
  6. Ton: Ein Buzzer wurde getestet, indem er eine Gewinner- und Verlierermelodie korrekt und klar wiedergab.

Alle getesteten Komponenten erfüllten die definierten Anforderungen und wiesen keine Abweichungen außerhalb der zulässigen Toleranzen auf.

Integration des Stateflows

Nach der Integration von Stateflow wurde ein umfassender Systemtest durchgeführt, der alle definierten Funktionen des Escape Games abdeckte. Die Anforderungsliste wurde entsprechend erweitert und jede Funktion anhand eines Erfüllungsgrads von 0 bis 100 % bewertet. Ziel war es, sicherzustellen, dass das System alle Anforderungen wie Zeitmessung, Entfernungsschätzung und Gewichtsschätzung zuverlässig erfüllt.

Das System zeigte ein fehlerfreies Verhalten und erfüllte alle Anforderungen vollständig (100 %). Es reagierte korrekt auf Benutzereingaben, spielte die vorgesehenen Melodien ab und zeigte die geschätzten Werte präzise an. Darüber hinaus wurden auch die funktionalen Anforderungen an Interaktion, Benutzerfreundlichkeit und Kompatibilität mit Simulink erfüllt. Die abschließende Integration in die geplante Hardware (Schuhkarton) wurde ebenfalls erfolgreich umgesetzt.

Die systematische Prüfung bestätigte die Funktionalität und Robustheit des Systems, sodass es für die vorgesehene Anwendung freigegeben werden konnte.

Ergebnis und Diskussion

Testauswertung

Der Komponententest zeigt, dass alle getesteten Systeme und Sensoren die Anforderungen an Funktionalität und Genauigkeit erfüllen. Die gemessenen Abweichungen blieben durchweg innerhalb der spezifizierten Toleranzen, was auf eine hohe Zuverlässigkeit und Präzision der Systeme hinweist. Besonders hervorzuheben sind die Messungen des IR-Sensors und des Drucksensors, die trotz unterschiedlicher Umgebungsbedingungen konsistente Ergebnisse lieferten. Die funktionalen Tests der LEDs, der 7-Segment-Anzeige und des Buzzers zeigten, dass die Ausgabekomponenten ordnungsgemäß arbeiten und ihre definierten Aufgaben erfüllen. Zusammenfassend kann festgestellt werden, dass die getesteten Komponenten robust und einsatzbereit sind, wobei keine kritischen Fehler oder Optimierungsbedarfe festgestellt wurden.

Systemverhalten und Erfüllungsgrad der Anforderungen

Der Systemtest des Escape Games war ein voller Erfolg. Sämtliche Anforderungen wurden zu 100 % erfüllt, was die Zuverlässigkeit und Funktionsfähigkeit des Systems bestätigt. Die Integration von Stateflow und die umfassende Prüfung aller Funktionen zeigten, dass das System robust ist und präzise auf Benutzereingaben reagiert.

Besonders hervorzuheben ist die korrekte Implementierung der Kernfunktionen wie Zeitmessung, Entfernungsschätzung und Gewichtsschätzung. Alle Messwerte lagen innerhalb der geforderten Toleranzen, und das System reagierte wie vorgesehen mit akustischen und visuellen Rückmeldungen. Auch die Benutzerfreundlichkeit wurde durch eine einfache Bedienung und klare Ausgaben sichergestellt, was das System sowohl für Kinder als auch Erwachsene geeignet macht.

Die erfolgreiche Umsetzung der Anforderungen zeigt, dass das System für den praktischen Einsatz bereit ist. Die 100%ige Erfüllung aller Anforderungen verdeutlicht die hohe Qualität der Entwicklung, und das Escape Game erfüllt alle vorgesehenen Ziele. Das Ergebnis ist ein vollständig funktionales und interaktives System, das sowohl technisch als auch benutzerseitig überzeugt.

Defizite
Der Drucksensor (ARD SENPRESSURE) funktioniert nicht optimal für die ausgewählte Funktion der präzisen Gewichtsmessung, da eine begrenzte Stabilität in der Befestigung besteht und beim Auflegen der Gewichte die Kontaktierung zum Drucksensor nicht optimal ist. Ein Sensor wie der HX711 in Kombination mit einer Wägezelle wäre hier vorteilhafter, da er speziell für hochpräzise Messungen entwickelt wurde und lineare sowie stabile Ergebnisse liefert. Zusätzlich ermöglicht der HX711 eine einfache Integration und bietet eine hohe Auflösung, die den Anforderungen an zuverlässige Gewichtsmessungen mehr gerecht wird.

Zusammenfassung

Das Projekt Zeit-, Entfernungs- und Gewichtsschätzung ist ein interaktives Escape-Game, das die Fähigkeiten der Teilnehmer im Schätzen von Zeit, Entfernung und Gewicht auf die Probe stellt. Die Spieler müssen nacheinander drei Aufgaben lösen:

  • Zeit schätzen: Einen Knopf genau 10 Sekunden lang gedrückt halten.
  • Entfernung schätzen: Eine Distanz von 10 cm korrekt bestimmen, unterstützt durch einen IR-Sensor.
  • Gewicht schätzen: Aus drei zur Verfügung stehenden Gewichten das mit 150 g auswählen und auf einen Drucksensor platzieren.

Bei korrekter Lösung aller Aufgaben wird ein Code für ein Schloss angezeigt, der den erfolgreichen Abschluss des Spiels ermöglicht. Fehlerhafte Schätzungen werden mit einer entsprechenden Rückmeldung quittiert, und das Spiel beginnt von vorne.

Die durchgeführten Tests und Systemprüfungen des Escape-Games bestätigen die erfolgreiche Umsetzung aller definierten Anforderungen. Die Integration der Sensoren und die Verarbeitung der Benutzereingaben funktionieren zuverlässig, und die Rückmeldungen an die Spieler sind klar und informativ. Die Spieler erhalten präzise Rückmeldungen zu ihren Schätzungen, was den Lerneffekt und den Spielspaß erhöht. Insgesamt bietet das System eine unterhaltsame und lehrreiche Erfahrung, die die Fähigkeiten im Schätzen von Zeit, Entfernung und Gewicht fördert.

Lessons Learned

  • Bedeutung der Planung: Eine gründliche und detaillierte Planung ist entscheidend für den Projekterfolg.
  • Effiziente Aufgabenteilung und Zeitmanagement: Klare Zuständigkeiten und eine realistische Zeiteinteilung wirken sich positiv auf das Endergebnis aus.
  • Anwendung von Bibliotheken im Simulink Projekt: Durch die Verwendung von Bibliotheken im Simulink-Projekt wurde ein kollaboratives Arbeiten an der Software ermöglicht. Die Bibliotheken konnten dabei gesperrt (Locking), sodass Programmierkonflikte während der Entwicklungsphase effektiv vermieden wurden.
  • Berücksichtigung von Fertigungstoleranzen: Um Nacharbeiten zu minimieren, sollten die Toleranzen beim 3D-Druck frühzeitig berücksichtigt werden.
  • Optimierung durch PCB-Design mit Multisim: Der Einsatz von Multisim zur Leiterplattenentwicklung verringert den Arbeitsaufwand und erhöht die Effizienz, da umfangreiche Lötarbeiten entfallen und die Verbindungen präziser und zuverlässiger gestaltet werden können.

Projektunterlagen

Abb. XX: Gantt Projektplan für das Projekt "Zeit-, Entfernungs- und Gewichtsschätzung“

SVN-Projektdaten

  1. Aufsteller
  2. Dokumentation
    1. Projektplan
    2. Lastenheft/ Anforderungsliste
    3. Programmablaufplan
    4. Bilder
  3. HW Elektrotechnik
    1. Schaltplan
    2. Fritzing Verdrahtungsplan
  4. HW Mechanik
  5. Software
    1. Bibliotheken
    2. Messtechnik
    3. Darstellung
    4. Funktionen
    5. Parameter
    6. start.m
  6. Unterlagen und Datenblätter

Projektplan

Der Projektplan in Abbildung XX zeigt den zeitlichen Ablauf eines Projekts von Oktober 2024 bis Januar 2025. Verschiedene Aufgaben sind in einem Gantt-Diagramm als Balken dargestellt, die die Start- und Enddaten visualisieren. Aufgaben wie die mechanische Vorinstallation, die Installation des Schutzhauses und Systemtests sind aufgeführt. Abhängigkeiten zwischen den Aufgaben werden durch Pfeile verdeutlicht. Das Projekt endet Anfang Januar 2025 mit der abschließenden Dokumentation und der Vorbereitung für die Projektmesse. Der Projektplan ist hier hinterlegt.

Projektdurchführung

Die Projektdurchführung begann mit einer gemeinsamen Ideenfindung zu Beginn des Semesters. Die Projektteilnehmer haben dabei verschiedene Möglichkeiten diskutiert und sich schließlich auf die hier dargestellten Schätzaufgaben geeinigt. Nachfolgend wird der Ablauf der Projektdurchführung beschrieben, der an die Ideenausarbeitung anschloss.

Zielsetzung

Das Ziel des Projekts war es, die menschliche Wahrnehmung von Zeit, Entfernung und Gewicht auf spielerische Weise zu untersuchen und die damit verbundenen Herausforderungen hervorzuheben.

Aufgabenstellung

  1. Zeitschätzung: Die Teilnehmer sollen eine Zeitspanne von exakt 10 Sekunden durch Drücken eines Knopfes abschätzen. Bei korrekter Schätzung wird eine Melodie abgespielt und ein Code angezeigt. Andernfalls wird die tatsächlich erreichte Zeit zurückgemeldet.
  2. Entfernungsschätzung: Es soll die Entfernung von 10cm geschätzt werden. Die Abweichung zur tatsächlichen Entfernung wird anschließend mitgeteilt.
  3. Gewichtsschätzung: Verschiedene Objekte mit unbekanntem Gewicht werden den Teilnehmern präsentiert. Es soll das Gewicht ausgewählt werden welches 150g wiegt.

Planung und Vorbereitung

Die Aufgabenstellung wurde in verschiedene Arbeitspakete aufgeteilt. Diese Pakete wurden im Anschluss zeitlich mit einem Gantt-Diagramm geplant, um den Überblick über die Projektfortschritte zu behalten. Feste Meilensteine wurden definiert, um den Abschluss der jeweiligen Pakete sicherzustellen.

Umsetzung

Regelmäßige Treffen wurden eingeplant, um den Fortschritt zu überprüfen und gemeinsam an den Arbeitspaketen zu arbeiten. Während dieser Treffen wurden die Aufgaben innerhalb der Pakete flexibel und je nach Bedarf spontan verteilt. Diese Arbeitsweise ermöglichte eine gleichmäßige Verteilung der Arbeitslast über das gesamte Semester und verhinderte unnötigen Stress kurz vor der Abgabe.

YouTube Video

Das folgende Video bietet einen spannenden Einblick in den Aufbau und die Funktionsweise eines Escape Games, das im Rahmen des Moduls Angewandte Mechatronik entwickelt wurde. Die Herausforderung des Spiels besteht darin, eine Taste genau 10 Sekunden lang gedrückt zu halten. Doch das ist noch nicht alles: Die Teilnehmer müssen außerdem eine Entfernung von 10 cm sowie ein Gewicht von 150 g möglichst präzise schätzen.

Die gezeigte Aufgabe verdeutlicht eindrucksvoll, wie anspruchsvoll es sein kann, Zeit, Entfernung und Gewicht korrekt einzuschätzen.

Im Video wird nicht nur der technische Aufbau des Projekts vorgestellt, sondern auch das Spiel in Aktion gezeigt. Dabei werden typische Herausforderungen und Fehler der Teilnehmer sichtbar, die den Schwierigkeitsgrad der Aufgabe unterstreichen.

Abschließend wird die Lösung des Escape Games präsentiert, wodurch die Funktionsweise und die Erfolgsmomente des Spiels verständlich gemacht werden. Dieses Video ist eine hervorragende Gelegenheit, mehr über innovative Spielkonzepte und die Grenzen der menschlichen Wahrnehmung zu erfahren.

Erleben Sie das Escape Game in Aktion und lassen Sie sich inspirieren:

Ergebnisvideo zu dem ARD VIB 01 - Piezo Vibrationssensor [4]

Feedback und Anregungen sind in der Kommentarfunktion bei YouTube herzlich willkommen!

Weblinks

ZIP FILE DES PROJEKTES !!!!!!!!!!!!!!

Literatur


→ zurück zur Übersicht: WS 24/25: Escape Game