Escape Game: Chromatic Lock: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
|||
| (7 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 248: | Zeile 248: | ||
=== Elektronische Umsetzung === | === Elektronische Umsetzung === | ||
Als zentrale Recheneinheit wird ein Arduino Mega 2560 verwendet. | |||
Der Mikrocontroller übernimmt die Erfassung der Bedienelemente, die | |||
Ausführung der Spiellogik sowie die Ansteuerung der Anzeige- und | |||
Ausgabekomponenten. | |||
'''Eingabekomponenten''' | |||
Zur Eingabe stehen insgesamt drei inkrementelle Drehencoder zur Verfügung. | |||
Zwei Encoder dienen zur Einstellung der Farbanteile Rot und Blau. | |||
Der dritte Encoder wird zur Einstellung des grünen Farbanteils verwendet | |||
und zusätzlich zur Auswahl des Schwierigkeitsgrades | |||
(Leicht, Mittel, Schwer). | |||
Zusätzlich sind drei Taster vorhanden: | |||
* ein Select-Taster zur Bestätigung von Menüauswahlen, | |||
* ein Power-Taster zum Ein- und Ausschalten des Systems, | |||
* ein Reset-Taster zum Neustart des Spiels. | |||
Die Drehencoder liefern digitale Quadratur-Signale (A/B), die vom | |||
Mikrocontroller ausgewertet werden. Die Taster werden entprellt, um | |||
Fehlauslösungen zu vermeiden. | |||
'''Ausgabekomponenten''' | |||
Zur visuellen Ausgabe werden zwei Displays eingesetzt. | |||
Ein 2,8" TFT-Display mit ILI9341-Controller, angebunden über SPI, dient zur | |||
Darstellung der aktuellen RGB-Farbmischung sowie der einzelnen Farbkanäle. | |||
Ein 20×4 LCD-Display mit I²C-Schnittstelle wird zur Anzeige von Menüs, | |||
Hinweisen und Statusmeldungen verwendet. | |||
Für akustisches Feedback ist ein Piezo-Buzzer integriert, der bei | |||
erfolgreichen oder fehlerhaften Eingaben entsprechende Signaltöne ausgibt. | |||
Die Kommunikation mit den Peripheriekomponenten erfolgt über SPI, I²C sowie | |||
digitale GPIO-Pins. Der Hardwareaufbau erlaubt eine getrennte Ansteuerung | |||
von Eingabe-, Anzeige- und Audio-Komponenten. | |||
Encoder & Taster → Arduino Mega → LCD (I2C) | TFT (SPI) | Buzzer | |||
=== Software Umsetzung === | === Software Umsetzung === | ||
Die Software des Escape Games „Chromatic Lock“ wurde modellbasiert mit | |||
MATLAB/Simulink entwickelt und anschließend als C/C++-Code für den | |||
Arduino Mega 2560 generiert. Die Spiellogik ist als endlicher | |||
Zustandsautomat (Finite State Machine, FSM) umgesetzt, welcher den | |||
gesamten Spielablauf steuert. | |||
==== Gesamtarchitektur ==== | |||
Die Software ist in klar getrennte Funktionsbereiche gegliedert: | |||
Eingabeverarbeitung (Drehencoder und Taster), Spiellogik (Game Manager) | |||
sowie Anzeige- und Ausgabelogik (LCD, TFT und Buzzer). | |||
[[Datei:ChromaticLock Simulink Toplevel.png| 1000px | 700px | thumb | left | Abbildung 10: Top-Level-Simulink-Modell des Systems]] | |||
<br clear="all"> | |||
Das Simulink-Modell bildet die zentrale Steuerung ab und verbindet die | |||
hardwarebezogenen Funktionsblöcke mit dem Game Manager. | |||
==== Zustandsautomat (Game Manager) ==== | |||
Der Game Manager stellt den Kern der Software dar und ist als FSM | |||
implementiert. Er verwaltet den aktuellen Spielzustand, die Anzahl der | |||
zu lösenden Puzzle sowie die Ausgabe der entsprechenden Texte, Farben | |||
und akustischen Signale. | |||
Implementierte Zustände: | |||
* Welcome – Startbildschirm | |||
* Difficulty – Auswahl des Schwierigkeitsgrades | |||
* Play – Lösen der RGB-Farbpuzzle | |||
* Win – Anzeige des Codes | |||
<syntaxhighlight lang="matlab"> | |||
%% ================= FSM ================= | |||
switch state | |||
case 0 | |||
L1 = uint8(' CHROMATIC LOCK '); | |||
L4 = uint8('Select: Start '); | |||
if Select_g | |||
Tone_Event = uint8(1); | |||
state = uint8(1); | |||
end | |||
case 1 | |||
L1 = uint8('-- SCHWIERIGKEIT -- '); | |||
diff_scroll = Difficulty_g; | |||
if diff_scroll == 1 | |||
L2 = uint8('> LEICHT (3) '); | |||
L3 = uint8(' MITTEL (4) '); | |||
L4 = uint8(' SCHWER (6) '); | |||
elseif diff_scroll == 2 | |||
L2 = uint8(' LEICHT (3) '); | |||
L3 = uint8('> MITTEL (4) '); | |||
L4 = uint8(' SCHWER (6) '); | |||
else | |||
L2 = uint8(' LEICHT (3) '); | |||
L3 = uint8(' MITTEL (4) '); | |||
L4 = uint8('> SCHWER (6) '); | |||
end | |||
if Select_g | |||
diff_committed = diff_scroll; | |||
% --- FIXED, CODEGEN-SAFE --- | |||
puzzle_table = uint8([3 4 6]); | |||
total_puzzles = puzzle_table(diff_committed); | |||
puzzle = uint8(1); | |||
state = uint8(2); | |||
end | |||
case 2 | |||
L1 = uint8('Mische RGB nach Hint'); | |||
L2 = reshape(HintR(puzzle,diff_committed,:),1,20); | |||
L3 = reshape(HintG(puzzle,diff_committed,:),1,20); | |||
L4 = reshape(HintB(puzzle,diff_committed,:),1,20); | |||
R_color = single(R_idx_g)/6; | |||
G_color = single(G_idx_g)/6; | |||
B_color = single(B_idx_g)/6; | |||
Mix_color = (R_color + G_color + B_color)/3; | |||
if Match_g | |||
if R_idx_g == tgtR(puzzle) && ... | |||
G_idx_g == tgtG(puzzle) && ... | |||
B_idx_g == tgtB(puzzle) | |||
Tone_Event = uint8(2); | |||
puzzle = puzzle + 1; | |||
if puzzle > total_puzzles | |||
state = uint8(3); | |||
end | |||
else | |||
Tone_Event = uint8(3); | |||
end | |||
end | |||
case 3 | |||
RGB = [0 1 0]; | |||
L1 = uint8('*** GEWONNEN *** '); | |||
L2 = uint8('Alle Raetsel geloest'); | |||
L3 = uint8('CODE: 4729 '); | |||
L4 = uint8('Reset zum Neustart '); | |||
end | |||
</syntaxhighlight> | |||
Zustandswechsel erfolgen ausschließlich über explizite Benutzereingaben | |||
(z. B. Select-Taster), wodurch ein deterministischer und stabiler | |||
Spielablauf gewährleistet wird. | |||
==== Eingabeverarbeitung ==== | |||
Die drei Drehencoder liefern digitale Quadratur-Signale (A/B), die in | |||
einem separaten C-Modul ausgewertet werden. Um eine stabile Bedienung zu | |||
ermöglichen, werden mehrere Encoder-Flanken zu einem logischen Schritt | |||
zusammengefasst, bevor daraus ein diskreter Indexwert berechnet wird. | |||
Der grüne Encoder wird kontextabhängig eingesetzt: Einerseits zur | |||
Einstellung des grünen Farbanteils, andererseits zur Auswahl des | |||
Schwierigkeitsgrades im Menü. | |||
'''Beispiel: Quantisierung der Encoderwerte''' | |||
<syntaxhighlight lang="c"> | |||
#define ENC_DIV 4 | |||
static uint8_T countToIndex(int32_T count, uint8_T maxVal) | |||
{ | |||
int32_T step = count / ENC_DIV; | |||
int32_T m = step % maxVal; | |||
if (m < 0) m += maxVal; | |||
return (uint8_T)(m + 1); | |||
} | |||
</syntaxhighlight> | |||
Durch dieses Verfahren wird verhindert, dass mechanisches Prellen oder | |||
schnelle Drehbewegungen zu instabilen Eingabewerten führen. | |||
==== Spiellogik und Eingabe-Ownership ==== | |||
Der Game Manager legt fest, welche Eingaben in welchem Zustand gültig | |||
sind. So werden im Schwierigkeitsmenü ausschließlich die | |||
Schwierigkeitsauswahl und der Select-Taster ausgewertet, während im | |||
Spielzustand nur die RGB-Encoder und der Match-Taster aktiv sind. | |||
Für die Schwierigkeitsauswahl wird zwischen einem temporären Scroll-Wert | |||
und einem dauerhaft übernommenen Wert unterschieden. Der endgültige | |||
Schwierigkeitsgrad wird erst nach Betätigung des Select-Tasters | |||
übernommen. | |||
'''Beispiel: Latching der Schwierigkeitsauswahl''' | |||
<syntaxhighlight lang="matlab"> | |||
diff_scroll = Difficulty_Input; | |||
if Select_g | |||
diff_committed = diff_scroll; | |||
total_puzzles = uint8([3 4 6](diff_committed)); | |||
state = uint8(2); | |||
end | |||
</syntaxhighlight> | |||
==== Anzeige- und Ausgabelogik ==== | |||
Die Textausgabe auf dem 20×4 LCD-Display erfolgt zustandsabhängig. Um | |||
Flackern zu vermeiden, werden die zuletzt ausgegebenen Textzeilen | |||
zwischengespeichert und nur bei Inhaltsänderungen neu geschrieben. | |||
Das TFT-Display visualisiert sowohl die Ziel-Farbe als auch die aktuell | |||
eingestellte RGB-Farbmischung. Ein statisches Layout wird beim Start | |||
einmalig gezeichnet, während die Farbfelder nur bei relevanten | |||
Änderungen aktualisiert werden. | |||
[[Datei:ChromaticLock TFT Layout.jpg| 700px | 500px | thumb | left | Abbildung 11: Darstellung der Ziel- und aktuellen RGB-Farbe auf dem TFT]] | |||
<br clear="all"> | |||
[[Datei:ChromaticLock LCD Layout.jpg| 700px | 500px | thumb | left | Abbildung 11: LCD Layout des ChromaticLock im Spiel]] | |||
<br clear="all"> | |||
==== Akustisches Feedback ==== | |||
Akustisches Feedback wird über einen Piezo-Buzzer realisiert. Der Game | |||
Manager erzeugt ereignisbasierte Signale, die zwischen Erfolgs- und | |||
Fehlermeldungen unterscheiden. | |||
==== Integration ==== | |||
Der aus Simulink generierte Game Manager sowie die handgeschriebenen | |||
C/C++-Module für Encoder-, LCD- und TFT-Ansteuerung werden in der | |||
Arduino-Umgebung zusammengeführt. Diese Trennung ermöglicht eine klare | |||
Struktur und erleichtert Wartung und Erweiterung des Systems. | |||
== Komponententest == | == Komponententest == | ||
| Zeile 298: | Zeile 521: | ||
|} | |} | ||
== | == Ergebnis == | ||
Das entwickelte System erfüllt alle grundlegenden Anforderungen des | |||
Chromatic-Lock-Escape-Games. Die Bedienung über Drehencoder und Taster | |||
funktioniert zuverlässig, und die Anzeige auf LCD- und TFT-Display ist | |||
stabil und übersichtlich. | |||
Die modellbasierte Entwicklung mit MATLAB/Simulink ermöglichte eine | |||
strukturierte Umsetzung der Spiellogik sowie eine einfache Integration | |||
in die Arduino-Umgebung. Die Verwendung eines zustandsbasierten Ansatzes | |||
führte zu einem deterministischen und reproduzierbaren Spielverhalten. | |||
Das Projekt zeigt, dass sich auch komplexere interaktive Anwendungen mit | |||
Embedded-Systemen erfolgreich realisieren lassen und stellt eine | |||
geeignete Grundlage für zukünftige Erweiterungen dar. | |||
== Zusammenfassung == | == Zusammenfassung == | ||
Das Projekt „Escape Game: Chromatic Lock“ entstand im Rahmen einer | |||
hochschulischen Lehrveranstaltung im Bereich Embedded Systems. Ziel war | |||
die Entwicklung eines interaktiven Escape-Game-Moduls, bei dem durch das | |||
Mischen von RGB-Farbwerten verschiedene Rätsel gelöst werden müssen. | |||
Das System basiert auf einem Arduino Mega und kombiniert Drehencoder, | |||
Taster, Displays sowie akustisches Feedback zu einem spielbaren | |||
Gesamtsystem. Die Spiellogik steuert den Ablauf von der Auswahl des | |||
Schwierigkeitsgrades bis zur Anzeige eines finalen Codes nach dem Lösen | |||
aller Rätsel. | |||
=== Lessons Learned === | === Lessons Learned === | ||
'''1. Begrenzte Interrupt-Ressourcen:''' | |||
Die gleichzeitige Nutzung von drei Encodern mit Interrupts und eines LCDs über I²C (Pins 20/21) führte zu Instabilitäten und Anzeigeausfällen. In komplexen Hardware-Setups sollten Interrupts daher sparsam eingesetzt oder durch Polling bzw. funktionale Zusammenlegung ersetzt werden. | |||
'''2. Trennung von Konfiguration und Spielbetrieb:''' | |||
Die Doppelfunktion des grünen Encoders (Schwierigkeitswahl und Farbsteuerung) verursachte unerwünschte Seiteneffekte. Die Schwierigkeit wurde daher nach der Auswahl persistent gespeichert und während des Spiels vollständig entkoppelt. | |||
'''3. Skalierung trotz fixer Farbpalette:''' | |||
Trotz lediglich sechs Helligkeitsstufen pro Farbkanal konnte durch gezielte Auswahl von Zielkombinationen innerhalb des 6×6×6-Farbraums ein Pool von 38 unterscheidbaren Rätseln realisiert werden. | |||
'''4. Fixierte Hinweise zur Sicherstellung der Lösbarkeit:''' | |||
Hinweise mussten pro Puzzle konstant bleiben, um ein stabiles mentales Ziel zu ermöglichen. Zusätzlich wurden die Hinweisformulierungen nach Schwierigkeitsstufen abgestuft, um die begrenzten Helligkeitsstufen sinnvoll interpretierbar zu machen. | |||
'''5. Zustandsbasierte Spiellogik:''' | |||
Die Implementierung einer expliziten Zustandsmaschine (Start → Schwierigkeit → Spiel → Abschluss) erhöhte die Robustheit des Systems und verhinderte unbeabsichtigte Eingabeeffekte. | |||
== Projektunterlagen == | == Projektunterlagen == | ||
| Zeile 309: | Zeile 571: | ||
=== Projektplan === | === Projektplan === | ||
[[Datei:GanntUpdate CL.png| thumb | none | 1000px | 1500px | Abbildung | [[Datei:GanntUpdate CL.png| thumb | none | 1000px | 1500px | Abbildung 12: Projektplan]] | ||
===ZIP-Archiv=== | ===ZIP-Archiv=== | ||
Im folgenden Ordner befindet sich das Zip-Archiv des Projekts: | Im folgenden Ordner befindet sich das Zip-Archiv des Projekts: | ||
<br> | |||
[[Datei:Simulink V2 CL.zip|mini|Projektdaten]] | |||
<br> | |||
[[Datei:CL Projektdaten.zip]] | [[Datei:CL Projektdaten.zip]] | ||
== YouTube Video == | == YouTube Video == | ||
Aktuelle Version vom 13. Januar 2026, 00:07 Uhr
| Autoren: | Dominique Kamdem und Tatiana Kouomo Tchengang |
| Betreuer: | Prof. Krome |
Einleitung
Das „Chromatic Lock“ ist ein Rätsel für Escape‑Games, bei dem die Spieler durch Drehen an drei Reglern eine bestimmte Farbkombination einstellen müssen. Treffen sie die gesuchte Farbe, wird ein vierstelliger Code auf einem Display ausgegeben, der für den weiteren Spielverlauf benötigt wird. Akustisches und visuelles Feedback unterstützt den Moment der Lösung. Mit einer durchschnittlichen Spieldauer von rund fünf Minuten ist das Rätsel kompakt, mobil einsetzbar und für unterschiedliche Zielgruppen geeignet.
Schwierigkeitslevel:
Das Chromatic Lock verfügt über drei Schwierigkeitsstufen: Einsteiger, Fortgeschrittene und Profis. Die Unterscheidung erfolgt über die Komplexität der Farbhinweise, die von einfachen alltagsnahen Begriffen bis hin zu kulturellen, historischen und abstrakten Referenzen reichen. Dadurch lässt sich das Rätsel flexibel an unterschiedliche Zielgruppen und Spielniveaus anpassen.
Lernziele:
- Mikrocontroller-Programmierung mit Interrupts und Zustandsautomaten
- Integration von Sensorik (Encoder) und Aktorik (LED, Buzzer, Display)
- Anwendung von RGB-Farbtheorie und Farbtoleranzberechnung
Bezug zum MTR Studium:
- Praktische Umsetzung von Inhalten aus Elektrotechnik-Praktikum, Informatik, Lichttechnik und CAD
- Anwendung von Farbmetrik und Displaytechnologie im Kontext Lighting Systems Engineering
- Verbindung von Embedded Systems, Sensorintegration und technischer Dokumentation
Anforderungen
Tabelle 1: Anforderungen an das Chromatic Lock System| ID | Inhalt | Prio | Ersteller | Datum | Geprüft von | Datum |
|---|---|---|---|---|---|---|
| 01 | Die Stromversorgung muss über einen Steckernetzteil mit 9 V Ausgangsspannung und 2 A Stromstärke erfolgen. | high | D. Kamdem, T. Kouomo | 03.10.2025 | T. Kouomo | 28.11.2025 |
| 02 | Der Arduino muss drei Rotary Encoder auslesen und deren Drehrichtung sowie Tastendruck erkennen können. | high | D. Kamdem, T. Kouomo | 03.10.2025 | T. Kouomo | 28.11.2025 |
| 03 | Das System muss für jeden Farbkanal (R, G, B) eine vordefinierte Palette von 5-6 Farbstufen bereitstellen. | high | D. Kamdem, T. Kouomo | 03.10.2025 | D. Kamdem | 28.11.2025 |
| 04 | Das 2.8" TFT-Display muss oben die aktuelle Mischung (AKTUELL) und unten die Zielfarbe (ZIEL) anzeigen. | high | D. Kamdem, T. Kouomo | 03.10.2025 | D. Kamdem | 28.11.2025 |
| 05 | Das 20×4 LCD muss kontextabhängige Hinweise basierend auf Schwierigkeitsgraden anzeigen. | high | D. Kamdem, T. Kouomo | 03.10.2025 | T. Kouomo | 28.11.2025 |
| 06 | Das System muss die gewählte Farbkombination mit einer vordefinierten Zielfarbe vergleichen und bei Übereinstimmung einen Match erkennen. | high | D. Kamdem, T. Kouomo | 03.10.2025 | D. Kamdem | 05.01.2026 |
| 07 | Die Zielfarbe muss zufällig generiert werden und alle Schwierigkeitsgrade müssen gelöst werden. | high | D. Kamdem, T. Kouomo | 03.10.2025 | D. Kamdem | 05.01.2026 |
| 08 | Bei erfolgreichem Farbmatch muss ein vierstelliger Code auf dem LCD angezeigt werden, begleitet von einer Glückwunschnachricht. | high | D. Kamdem, T. Kouomo | 03.10.2025 | T. Kouomo | 05.01.2026 |
| 09 | Das System muss über einen Reset-Taster auf der Front für die Spielleitung und einen seitlichen Ein-/Aus-Schalter verfügen. | high | D. Kamdem, T. Kouomo | 03.10.2025 | D. Kamdem | 05.01.2026 |
| 10 | Das System muss über eine rote LED für Ein-/Aus-Status (Stromversorgung) und eine blaue LED für Reset verfügen. | low | D. Kamdem, T. Kouomo | 03.10.2025 | T. Kouomo | 05.01.2026 |
| 11 | Das System muss akustisches Feedback über einen Piezo-Buzzer bei Erfolg und Fehlversuchen geben. | low | D. Kamdem, T. Kouomo | 03.10.2025 | T. Kouomo | 05.01.2026 |
| 12 | Das System muss in einem kompakten 3D-gedruckten Gehäuse untergebracht werden. | low | D. Kamdem, T. Kouomo | 03.10.2025 | D. Kamdem | 08.01.2026 |
Funktionaler Systementwurf
Systemarchitektur und Komponentenübersicht
Das System ist als Farbcode‑Rätsel aufgebaut, das in mehreren Schritten abläuft:
- Initialisierung: Beim Start werden Zielfarbe und Hinweise geladen und angezeigt.
- Eingabe: Spieler wählen über drei Drehgeber diskrete Werte für Rot, Grün und Blau.
- Anzeige:
- TFT zeigt aktuelle Mischung und Zielfarbe.
- LCD gibt Hinweise abhängig vom Schwierigkeitsgrad und zeigt im Erfolgsfall den vierstelligen Code.
- Vergleich: Die aktuelle Farbmischung wird mit der Zielfarbe innerhalb einer Toleranz verglichen.
- Feedback: Akustisches Signal über Buzzer und visuelles Signal über LED.
- Erfolg: Bei Übereinstimmung erscheint der Code, begleitet von Feedback.
- Reset: Über einen Taster kann das System zurückgesetzt werden; ein Schalter steuert die Stromversorgung.
Die Kernfunktionen sind damit: Eingabe von Farbwerten, Anzeige von Informationen, Vergleich mit der Zielfarbe, Ausgabe von Rückmeldungen und Code sowie Rücksetzung des Systems.
Technischer Systementwurf
Die technische Umsetzung basiert auf einer Hardware‑ und Softwarearchitektur:
Hardwarearchitektur:
Steuereinheit: Arduino Mega 2560 als zentrale Logik.
Eingabe: Drei Rotary Encoder (KY‑040) für die RGB‑Werte.
Ausgabe:
- TFT‑Display (2.8″, SPI) für aktuelle Mischung und Zielfarbe.
- LCD (20×4, I²C) für Hinweise und Code.
- Piezo‑Buzzer für akustisches Feedback.
- Status‑LED für visuelle Rückmeldung.
Bedienung: Reset‑Taster auf der Front, seitlicher Ein-/Aus‑Schalter.
Stromversorgung: Steckernetzteil (18 W, 9 V, 2 A).
Gehäuse: 3D‑gedruckt, ca. 150 × 100 mm, mit Aussparungen für Bedienelemente.
Schaltplan

Pin-Belegung der Arduino
| ID | Komponente | Signal/Funktion | Arduino Mega Pin(s) |
|---|---|---|---|
| 1 | Encoder 1 | CLK, DT | D2, D3 |
| 2 | Encoder 2 | CLK, DT | D18, D19 |
| 3 | Encoder 3 | CLK, DT | D22, D23 |
| 4 | TFT‑Display (ILI9341, SPI) | CS, RESET, DC, MOSI, SCK, MISO | D53, D49, D48, D51, D52, D50 |
| 5 | LCD 20×4 (I²C) | SDA, SCL | D20, D21 |
| 6 | Piezo‑Buzzer | Buzzer‑Ansteuerung | D6 |
| 7 | Status‑LED | Statusanzeige | D5 |
| 8 | Reset‑Taster | Reset‑Eingang | D7 |
Softwarearchitektur:
- Arduino IDE für Encoder‑Auswertung, Farbpalettenverwaltung, Vergleichslogik, Displaysteuerung und Codegenerierung.
- Simulink zur Modellierung des Signalflusses (Encoder → Farblogik → Vergleich → Ausgabe).
Zustandsautomat und Datenflussdiagramm


Komponentenspezifikation
BOM – Komponentenübersicht
Tabelle 3: Material und Stückliste| ID | Anzahl | Komponente | Technische Bezeichnung | Kosten (Stück) | Datenblatt | Link zum Artikel |
|---|---|---|---|---|---|---|
| 1 | 1 | Mikrocontroller-Board | Arduino Mega 2560 (Funduino kompatibel) | 18,90 € | Arduino Mega | Funduino Mega 2560 |
| 2 | 3 | Rotary Encoder | KY-040 Drehgeber | 1,25 € | KY-040 | Roboter-Bausatz |
| 3 | 1 | TFT Display | 2.8" SPI TFT 240x320 (ILI9341) | 12,45 € | ILI9341 | Roboter-Bausatz |
| 4 | 1 | LCD | 20x4 I²C LCD HD44780 | 6,90 € | HD44780 | Funduino LCD 20x4 |
| 5 | 1 | Piezo Buzzer | Aktiver Buzzer 5 V | 0,90 € | Components101 Buzzer | Funduino Buzzer |
| 6 | 1 | Power LED | 3 mm LED rot | 0,15 € | 3mm Red LED | LED-Shop Rot |
| 7 | 1 | Reset LED | 3 mm LED blau | 0,35 € | 3mm LED Specs | Reichelt Blau |
| 8 | 2 | Widerstand | 220 Ω, 0,25 W | 0,18 € | - | Reichelt Widerstand |
| 9 | 1 | Gehäuse | 3D-Druck PLA | - | - | - |
| 10 | 1 | Steckernetzteil | 18 W, 9 V, 2 A | 11,95 € | Datenblatt | Reichelt Netzteil |
| 11 | 1 | Verkabelung | Jumper Wires + Platine | 3,36 € | - | Roboter-Bausatz Jumper / Funduino Platine |
| Gesamtkosten : | 59,07 € |
Technische Komponentenspezifikation
Arduino Mega 2560
- Funktion: Zentrale Steuereinheit für komplexere Projekte mit vielen Ein- und Ausgängen
- Mikrocontroller: ATmega2560
- Digitale I/O: 54 Pins (davon 15 PWM-fähig)
- Analoge Inputs: 16 Pins
- Speicher: 256 KB Flash, 8 KB SRAM, 4 KB EEPROM
- Verwendete Schnittstellen: Digital I/O, I²C, SPI, UART (4 serielle Schnittstellen)
Rotary Encoder (KY-040)
- Funktion: Farbpalettennavigation durch Drehbewegung
- Ausgänge: CLK, DT (Quadraturencoder)
- Rastung: 20 Schritte/Umdrehung
- Auswertung: Interrupt-basierte Zählung (CLK/DT Flanken)
2.8" TFT-Display (ILI9341)
- Funktion: Visuelle Darstellung der Farbmischung und Zielfarbe
- Auflösung: 240×320 Pixel
- Schnittstelle: SPI (MOSI, SCK, CS, DC, RST)
- Farbtiefe: 16-bit RGB (65.536 Farben)
- Darstellung: Geteilter Bildschirm (50/50 für Ist/Soll-Farbe)
20×4 LCD-Display (I²C)
- Funktion: Textausgabe für Hinweise und Code
- Schnittstelle: I²C (SDA, SCL)
- I²C-Adresse: 0x27 oder 0x3F (konfigurierbar)
- Zeichen: 20 Zeichen × 4 Zeilen
Piezo-Buzzer
- Funktion: Akustisches Feedback bei erfolgreicher Lösung
- Typ: Passiver Buzzer
- Frequenzbereich: 2-4 kHz
- Ansteuerung: PWM-Signal (Pin 12)
- Tonsequenz: Erfolgssignal (z.B. C-E-G Akkord)
Power LED (Rot)
- Funktion: Anzeige des Betriebszustands (Ein/Aus)
- Typ: 3mm Standard-LED
- Farbe: Rot
- Vorwiderstand: 220Ω
Reset LED (Blau)
- Funktion: Anzeige des Reset-Status
- Typ: 3mm Standard-LED
- Farbe: Blau
- Vorwiderstand: 220Ω
Umsetzung (HW/SW)
Mechanische Umsetzung
Für das Projekt Chromatic Lock wurde ein maßgeschneidertes Gehäuse entwickelt, das zentrale Komponenten wie den Mikrocontroller, die Anzeigeeinheiten und die Bedienelemente aufnimmt. Ziel war eine robuste, wartungsfreundliche Konstruktion, die sowohl funktional als auch optisch klar strukturiert ist.



Die Gehäusekonstruktion entstand in mehreren Iterationsschritten. Nach ersten Skizzen und Diskussion im Team wurde das finale Design in SolidWorks modelliert und anschließend als 3D‑Modell visualisiert.
Die Gehäusewände sind so dimensioniert, dass sie mechanischen Belastungen durch Tastenbetätigung standhalten und die verbauten Komponenten zuverlässig schützen. Am Boden befinden sich stabile Halterungen, die eine sichere und präzise Aufnahme des Arduino-Boards ermöglichen. Die Verschraubung erfolgt ausschließlich am oberen Gehäusedeckel, wo die Schrauben in den dafür vorgesehenen Bohrungen fixiert werden. Diese Konstruktion sorgt für eine gleichmäßige Kraftverteilung und verhindert das Eindringen von Staub oder Fremdkörpern.
Auf der Rückseite des Gehäuses befinden sich zwei Öffnungen für Stromversorgung und den USB Programmierzugang. Die Kabelzuführung erfolgt über definierte Kanäle, die die Funktionalität nicht beeinträchtigen und gleichzeitig eine saubere Innenführung ermöglichen.

Die Oberseite des Gehäuses ist als abgesetztes Deckelteil gestaltet, das neben der strukturellen Stabilität auch die Montage der Bedienelemente und Schnittstellen erleichtert. Hier sind Aussparungen für Displays, Taster und Drehregler vorgesehen, die eine klare und intuitive Benutzerführung ermöglichen. Die Komponente Öffnungen sind so gestaltet, dass die Module von hinten eingesetzt und sicher fixiert werden können. Die Pins lassen sich ins Gehäuseinnere führen und dort direkt verdrahten. Alternativ ist auch eine vorkonfektionierte Montage möglich.
Besondere Aufmerksamkeit gilt der Frontplatte. Sie enthält klar beschriftete Aussparungen für Anzeige, Power-Button und Reset-Funktion. Die Anordnung der Bedienelemente folgt einer intuitiven, benutzerfreundlichen Logik, die eine einfache und schnelle Bedienung gewährleistet. Dadurch wird eine klare Orientierung unterstützt und ein flüssiger Bedienfluss ermöglicht.


Elektronische Umsetzung
Als zentrale Recheneinheit wird ein Arduino Mega 2560 verwendet. Der Mikrocontroller übernimmt die Erfassung der Bedienelemente, die Ausführung der Spiellogik sowie die Ansteuerung der Anzeige- und Ausgabekomponenten.
Eingabekomponenten
Zur Eingabe stehen insgesamt drei inkrementelle Drehencoder zur Verfügung. Zwei Encoder dienen zur Einstellung der Farbanteile Rot und Blau. Der dritte Encoder wird zur Einstellung des grünen Farbanteils verwendet und zusätzlich zur Auswahl des Schwierigkeitsgrades (Leicht, Mittel, Schwer).
Zusätzlich sind drei Taster vorhanden:
- ein Select-Taster zur Bestätigung von Menüauswahlen,
- ein Power-Taster zum Ein- und Ausschalten des Systems,
- ein Reset-Taster zum Neustart des Spiels.
Die Drehencoder liefern digitale Quadratur-Signale (A/B), die vom Mikrocontroller ausgewertet werden. Die Taster werden entprellt, um Fehlauslösungen zu vermeiden.
Ausgabekomponenten
Zur visuellen Ausgabe werden zwei Displays eingesetzt. Ein 2,8" TFT-Display mit ILI9341-Controller, angebunden über SPI, dient zur Darstellung der aktuellen RGB-Farbmischung sowie der einzelnen Farbkanäle. Ein 20×4 LCD-Display mit I²C-Schnittstelle wird zur Anzeige von Menüs, Hinweisen und Statusmeldungen verwendet.
Für akustisches Feedback ist ein Piezo-Buzzer integriert, der bei erfolgreichen oder fehlerhaften Eingaben entsprechende Signaltöne ausgibt.
Die Kommunikation mit den Peripheriekomponenten erfolgt über SPI, I²C sowie digitale GPIO-Pins. Der Hardwareaufbau erlaubt eine getrennte Ansteuerung von Eingabe-, Anzeige- und Audio-Komponenten.
Encoder & Taster → Arduino Mega → LCD (I2C) | TFT (SPI) | Buzzer
Software Umsetzung
Die Software des Escape Games „Chromatic Lock“ wurde modellbasiert mit MATLAB/Simulink entwickelt und anschließend als C/C++-Code für den Arduino Mega 2560 generiert. Die Spiellogik ist als endlicher Zustandsautomat (Finite State Machine, FSM) umgesetzt, welcher den gesamten Spielablauf steuert.
Gesamtarchitektur
Die Software ist in klar getrennte Funktionsbereiche gegliedert: Eingabeverarbeitung (Drehencoder und Taster), Spiellogik (Game Manager) sowie Anzeige- und Ausgabelogik (LCD, TFT und Buzzer).

Das Simulink-Modell bildet die zentrale Steuerung ab und verbindet die hardwarebezogenen Funktionsblöcke mit dem Game Manager.
Zustandsautomat (Game Manager)
Der Game Manager stellt den Kern der Software dar und ist als FSM implementiert. Er verwaltet den aktuellen Spielzustand, die Anzahl der zu lösenden Puzzle sowie die Ausgabe der entsprechenden Texte, Farben und akustischen Signale.
Implementierte Zustände:
- Welcome – Startbildschirm
- Difficulty – Auswahl des Schwierigkeitsgrades
- Play – Lösen der RGB-Farbpuzzle
- Win – Anzeige des Codes
%% ================= FSM =================
switch state
case 0
L1 = uint8(' CHROMATIC LOCK ');
L4 = uint8('Select: Start ');
if Select_g
Tone_Event = uint8(1);
state = uint8(1);
end
case 1
L1 = uint8('-- SCHWIERIGKEIT -- ');
diff_scroll = Difficulty_g;
if diff_scroll == 1
L2 = uint8('> LEICHT (3) ');
L3 = uint8(' MITTEL (4) ');
L4 = uint8(' SCHWER (6) ');
elseif diff_scroll == 2
L2 = uint8(' LEICHT (3) ');
L3 = uint8('> MITTEL (4) ');
L4 = uint8(' SCHWER (6) ');
else
L2 = uint8(' LEICHT (3) ');
L3 = uint8(' MITTEL (4) ');
L4 = uint8('> SCHWER (6) ');
end
if Select_g
diff_committed = diff_scroll;
% --- FIXED, CODEGEN-SAFE ---
puzzle_table = uint8([3 4 6]);
total_puzzles = puzzle_table(diff_committed);
puzzle = uint8(1);
state = uint8(2);
end
case 2
L1 = uint8('Mische RGB nach Hint');
L2 = reshape(HintR(puzzle,diff_committed,:),1,20);
L3 = reshape(HintG(puzzle,diff_committed,:),1,20);
L4 = reshape(HintB(puzzle,diff_committed,:),1,20);
R_color = single(R_idx_g)/6;
G_color = single(G_idx_g)/6;
B_color = single(B_idx_g)/6;
Mix_color = (R_color + G_color + B_color)/3;
if Match_g
if R_idx_g == tgtR(puzzle) && ...
G_idx_g == tgtG(puzzle) && ...
B_idx_g == tgtB(puzzle)
Tone_Event = uint8(2);
puzzle = puzzle + 1;
if puzzle > total_puzzles
state = uint8(3);
end
else
Tone_Event = uint8(3);
end
end
case 3
RGB = [0 1 0];
L1 = uint8('*** GEWONNEN *** ');
L2 = uint8('Alle Raetsel geloest');
L3 = uint8('CODE: 4729 ');
L4 = uint8('Reset zum Neustart ');
end
Zustandswechsel erfolgen ausschließlich über explizite Benutzereingaben (z. B. Select-Taster), wodurch ein deterministischer und stabiler Spielablauf gewährleistet wird.
Eingabeverarbeitung
Die drei Drehencoder liefern digitale Quadratur-Signale (A/B), die in einem separaten C-Modul ausgewertet werden. Um eine stabile Bedienung zu ermöglichen, werden mehrere Encoder-Flanken zu einem logischen Schritt zusammengefasst, bevor daraus ein diskreter Indexwert berechnet wird.
Der grüne Encoder wird kontextabhängig eingesetzt: Einerseits zur Einstellung des grünen Farbanteils, andererseits zur Auswahl des Schwierigkeitsgrades im Menü.
Beispiel: Quantisierung der Encoderwerte
#define ENC_DIV 4
static uint8_T countToIndex(int32_T count, uint8_T maxVal)
{
int32_T step = count / ENC_DIV;
int32_T m = step % maxVal;
if (m < 0) m += maxVal;
return (uint8_T)(m + 1);
}
Durch dieses Verfahren wird verhindert, dass mechanisches Prellen oder schnelle Drehbewegungen zu instabilen Eingabewerten führen.
Spiellogik und Eingabe-Ownership
Der Game Manager legt fest, welche Eingaben in welchem Zustand gültig sind. So werden im Schwierigkeitsmenü ausschließlich die Schwierigkeitsauswahl und der Select-Taster ausgewertet, während im Spielzustand nur die RGB-Encoder und der Match-Taster aktiv sind.
Für die Schwierigkeitsauswahl wird zwischen einem temporären Scroll-Wert und einem dauerhaft übernommenen Wert unterschieden. Der endgültige Schwierigkeitsgrad wird erst nach Betätigung des Select-Tasters übernommen.
Beispiel: Latching der Schwierigkeitsauswahl
diff_scroll = Difficulty_Input;
if Select_g
diff_committed = diff_scroll;
total_puzzles = uint8([3 4 6](diff_committed));
state = uint8(2);
end
Anzeige- und Ausgabelogik
Die Textausgabe auf dem 20×4 LCD-Display erfolgt zustandsabhängig. Um Flackern zu vermeiden, werden die zuletzt ausgegebenen Textzeilen zwischengespeichert und nur bei Inhaltsänderungen neu geschrieben. Das TFT-Display visualisiert sowohl die Ziel-Farbe als auch die aktuell eingestellte RGB-Farbmischung. Ein statisches Layout wird beim Start einmalig gezeichnet, während die Farbfelder nur bei relevanten Änderungen aktualisiert werden.


Akustisches Feedback
Akustisches Feedback wird über einen Piezo-Buzzer realisiert. Der Game Manager erzeugt ereignisbasierte Signale, die zwischen Erfolgs- und Fehlermeldungen unterscheiden.
Integration
Der aus Simulink generierte Game Manager sowie die handgeschriebenen C/C++-Module für Encoder-, LCD- und TFT-Ansteuerung werden in der Arduino-Umgebung zusammengeführt. Diese Trennung ermöglicht eine klare Struktur und erleichtert Wartung und Erweiterung des Systems.
Komponententest
Durchführung
Die Komponententests wurden durchgeführt, um die Funktionsfähigkeit sämtlicher Hardwarekomponenten des Systems vor der Integration sicherzustellen. Alle Tests folgten einem standardisierten Vorgehen.
- Vorbereitung
Alle relevanten Komponenten wurden gemäß der definierten Pinbelegung und Systemarchitektur auf einem separaten Testaufbau installiert. Hierzu zählten unter anderem Mikrocontroller, Drehencoder, Anzeigeeinheiten, akustische Ausgabegeräte, Statusanzeigen sowie die Spannungsversorgung.
- Einzeltests
Jede Komponente wurde isoliert geprüft, um elektrische und funktionale Eigenschaften ohne Einfluss anderer Systembestandteile zu evaluieren. Dabei wurde insbesondere auf Signalstabilität, Steuerbarkeit und Reaktionsverhalten geachtet.
- Integrationstest
Nach erfolgreichem Abschluss der Einzelprüfungen wurden alle Komponenten in das Gesamtsystem integriert. Anschließend wurde der vollständige Funktionsablauf getestet, einschließlich Farbauswahl, Wertedetektion, Berechnung, Vergleich mit dem Zielwert sowie finale Ausgabe des vierstelligen Codes.
- Dokumentation
Die Test Ergebnisse wurden dokumentiert. Auffälligkeiten wurden analysiert und behoben.
Textfassung
Tabelle 4: Textfassung der Komponententest| Test Nr. | Komponente | Durchführung | Erwartetes Ergebnis | Test bestanden? |
|---|---|---|---|---|
| TC01 | Stromversorgung (Netzteil 9 V) | Netzteil angeschlossen und Spannungsstabilität gemessen | Ausgangsspannung konstant bei 9 V ± 0,1 V. System startet ohne Spannungseinbruch | Ja |
| TC02 | Rotary Encoder R | Drehimpulse einzeln geprüft | Drehimpulse werden korrekt gezählt und erzeugt eindeutiges Signal am vorgesehenen Pin | Ja |
| TC03 | Rotary Encoder G | Testverfahren wie bei TC02 | Drehimpulse werden korrekt gezählt und erzeugt eindeutiges Signal am vorgesehenen Pin | Ja |
| TC04 | Rotary Encoder B | Testverfahren wie bei TC02 | Drehimpulse werden korrekt gezählt und erzeugt eindeutiges Signal am vorgesehenen Pin | Ja |
| TC05 | TFT-Display 2.8" | Ausgabe eines Testbildes über SPI | Testbild zeigt Test RGB-Farbkanäle ohne Artefakte. Der SPI-Kommunikation ist stabil | Ja |
| TC06 | LCD 20×4 (I²C) | Ausgabe des Texts „Hello World“ über I²C | Text erscheint vollständig und ohne Zeichensprünge. Die I²C-Adresse wurde korrekt erkannt | Ja |
| TC07 | Piezo-Buzzer | Erzeugung mehrere Prüftöne per PWM | PWM-Signal erzeugt Ton bei 1 kHz und die Lautstärke ist konstant. Keine Verzerrungen bemerkt | Ja |
| TC08 | Status-LEDs (rot/blau) | LEDs per Software ein- und ausgeschaltet | LEDs leuchten bei HIGH-Signal stabil | Ja |
| TC09 | Reset-Taster / Ein-Aus-Schalter | Reset-Vorgang und vollständiger Neustart geprüft | System startet nach Tastendruck neu und alle Register werden zurückgesetzt | Ja |
| TC10 | Gehäusemontage | Mechanische Passform und Kabelführung geprüft | Bauteile sind passgenau montiert; Kabel verlaufen spannungsfrei und ohne Quetschung |
Ergebnis
Das entwickelte System erfüllt alle grundlegenden Anforderungen des Chromatic-Lock-Escape-Games. Die Bedienung über Drehencoder und Taster funktioniert zuverlässig, und die Anzeige auf LCD- und TFT-Display ist stabil und übersichtlich.
Die modellbasierte Entwicklung mit MATLAB/Simulink ermöglichte eine strukturierte Umsetzung der Spiellogik sowie eine einfache Integration in die Arduino-Umgebung. Die Verwendung eines zustandsbasierten Ansatzes führte zu einem deterministischen und reproduzierbaren Spielverhalten.
Das Projekt zeigt, dass sich auch komplexere interaktive Anwendungen mit Embedded-Systemen erfolgreich realisieren lassen und stellt eine geeignete Grundlage für zukünftige Erweiterungen dar.
Zusammenfassung
Das Projekt „Escape Game: Chromatic Lock“ entstand im Rahmen einer hochschulischen Lehrveranstaltung im Bereich Embedded Systems. Ziel war die Entwicklung eines interaktiven Escape-Game-Moduls, bei dem durch das Mischen von RGB-Farbwerten verschiedene Rätsel gelöst werden müssen.
Das System basiert auf einem Arduino Mega und kombiniert Drehencoder, Taster, Displays sowie akustisches Feedback zu einem spielbaren Gesamtsystem. Die Spiellogik steuert den Ablauf von der Auswahl des Schwierigkeitsgrades bis zur Anzeige eines finalen Codes nach dem Lösen aller Rätsel.
Lessons Learned
1. Begrenzte Interrupt-Ressourcen: Die gleichzeitige Nutzung von drei Encodern mit Interrupts und eines LCDs über I²C (Pins 20/21) führte zu Instabilitäten und Anzeigeausfällen. In komplexen Hardware-Setups sollten Interrupts daher sparsam eingesetzt oder durch Polling bzw. funktionale Zusammenlegung ersetzt werden.
2. Trennung von Konfiguration und Spielbetrieb: Die Doppelfunktion des grünen Encoders (Schwierigkeitswahl und Farbsteuerung) verursachte unerwünschte Seiteneffekte. Die Schwierigkeit wurde daher nach der Auswahl persistent gespeichert und während des Spiels vollständig entkoppelt.
3. Skalierung trotz fixer Farbpalette: Trotz lediglich sechs Helligkeitsstufen pro Farbkanal konnte durch gezielte Auswahl von Zielkombinationen innerhalb des 6×6×6-Farbraums ein Pool von 38 unterscheidbaren Rätseln realisiert werden.
4. Fixierte Hinweise zur Sicherstellung der Lösbarkeit: Hinweise mussten pro Puzzle konstant bleiben, um ein stabiles mentales Ziel zu ermöglichen. Zusätzlich wurden die Hinweisformulierungen nach Schwierigkeitsstufen abgestuft, um die begrenzten Helligkeitsstufen sinnvoll interpretierbar zu machen.
5. Zustandsbasierte Spiellogik: Die Implementierung einer expliziten Zustandsmaschine (Start → Schwierigkeit → Spiel → Abschluss) erhöhte die Robustheit des Systems und verhinderte unbeabsichtigte Eingabeeffekte.
Projektunterlagen
Projektplan

ZIP-Archiv
Im folgenden Ordner befindet sich das Zip-Archiv des Projekts:
Datei:Simulink V2 CL.zip
Datei:CL Projektdaten.zip
YouTube Video
Literatur
→ zurück zur Übersicht: WS 25/26: Escape Game