

Mit Hilfe einer Fernbedienung wird auf einem TFT-Display ein Ball durch ein kleines Labyrinth bewegt. Beim Druck auf die *-Taste wird die Zeitmessung gestartet.
Benötigte Bauteile:
- Keyes Fernbedienung oder beliebige andere Fernbedienung
- Infrarotempfänger
- 1,77 oder 1,8 Zoll TFT-Display
- Leitungsdrähte
Baue die Schaltung auf:

⇒Pinbelegung verschiedener TFT-Displays

1,77 und 1,8-Zoll große TFT-Module haben eine Bildschirmauflösung von 128×160 Pixeln.
Achte auf die Pinbelegung der Infrarotempfänger.

Achte darauf, dass die Batterie richtig eingelegt wurde. Der Minus-Pol liegt oben.

Die Fernbedienung sendet beim Druck auf die Tasten einen Zahlencode.
Tastencodes Keyes-Fernbedienung
Pfeil oben | |||
Tastencode | 70 (0×46) | ||
Pfeil links | Taste OK | Pfeil rechts | |
Tastencode | 68 (0×44) | 64 (0×40) | 67 (0×43) |
Pfeil unten | |||
Tastencode | 21 (0×15) | ||
Taste 1 | Taste 2 | Taste 3 | |
Tastencode | 22 (0×16) | 25 (0×19) | 13 (0xD) |
Taste 4 | Taste 5 | Taste 6 | |
Tastencode | 12 (0xC) | 24 (0×18) | 94 (0x5E) |
Taste 7 | Taste 8 | Taste 9 | |
Tastencode | 8 (0xB) | 28 (0x1C) | 90 (0x5A) |
Taste * | Taste 0 | Taste # | |
Tastencode | 66 (0×42) | 82 (0×52) | 74 (0x4A) |

⇒Tastencodes OpenSmart Fernbedienung

⇒Testprogramm beliebige Fernbedienung
Benötigte Bibliotheken:


Die Tastencodes kannst du mit folgendem Programm herausfinden. Sie werden im Seriellen Monitor angezeigt.
// benötigte Bibliothek einbinden
#include "IRremote.h"
// der Pin, an dem der Infrarot-Empfänger angeschlossen ist
int EmpfaengerPin = 11;
void setup()
{
// Seriellen Monitor starten
Serial.begin(9600);
// Infrarot-Empfänger starten
IrReceiver.begin(EmpfaengerPin);
}
void loop()
{
// decode() -> Daten lesen
if (IrReceiver.decode())
{
// kurzes delay, damit nur ein Tastendruck gelesen wird
delay(200);
// resume -> nächsten Wert lesen
IrReceiver.resume();
/*
der Empfänger empfängt zwischendurch Signale,
die nicht ausgewertet werden können
es sollen dehalb nur die korrekt erkannten Tasten ausgewertet werden
die Dezimalwerte der korrekten erkannten Tasten liegen zwischen > 0 und < 95
es wird abgefragt, ob das empfangene Kommando decodedIRData.command
zwischen 0 und (&&) 95 liegt
*/
if (IrReceiver.decodedIRData.command > 0 && IrReceiver.decodedIRData.command < 95)
{
Serial.print("Dezimalwert: ");
// IrReceiver.decodedIRData.command = Wert der gedrückten Taste
Serial.print(IrReceiver.decodedIRData.command);
Serial.print(" -> ");
// Werte abfragen und anzeigen
if (IrReceiver.decodedIRData.command == 22) Serial.println("Taste 1");
if (IrReceiver.decodedIRData.command == 25) Serial.println("Taste 2");
if (IrReceiver.decodedIRData.command == 13) Serial.println("Taste 3");
if (IrReceiver.decodedIRData.command == 12) Serial.println("Taste 4");
if (IrReceiver.decodedIRData.command == 24) Serial.println("Taste 5");
if (IrReceiver.decodedIRData.command == 94) Serial.println("Taste 6");
if (IrReceiver.decodedIRData.command == 8) Serial.println("Taste 7");
if (IrReceiver.decodedIRData.command == 28) Serial.println("Taste 8");
if (IrReceiver.decodedIRData.command == 90) Serial.println("Taste 9");
if (IrReceiver.decodedIRData.command == 82) Serial.println("Taste 0");
if (IrReceiver.decodedIRData.command == 66) Serial.println("Taste *");
if (IrReceiver.decodedIRData.command == 74) Serial.println("Taste #");
if (IrReceiver.decodedIRData.command == 68) Serial.println("Pfeil links");
if (IrReceiver.decodedIRData.command == 67) Serial.println("Pfeil rechts");
if (IrReceiver.decodedIRData.command == 70) Serial.println("Pfeil oben");
if (IrReceiver.decodedIRData.command == 21) Serial.println("Pfeil unten");
if (IrReceiver.decodedIRData.command == 64) Serial.println("OK");
}
}
}

Binde die benötigen Bibliotheken ein und definiere die Variablen.
Das Aussehen kann durch verschiedene Parameter beeinflusst werden:
- Farbe der Blöcke im Parcours (FarbeBloecke)
- Farbe des Kreises (Kreisfarbe)
- Farbe der Schrift beim Start und bei der Anzeige der verstrichenen Zeit (Schriftfarbe)
- Radius des Kreises (Radius)
- Geschwindigkeit der Kreisbewegung (Geschwindigkeit)
- Anzahl der Pixel bei der Vorwärtsbewegung (Bewegung)
#include "IRremote.h"
#include "Adafruit_ST7735.h"
/*
Arduino
SCK 13
RST 9
DC 8
CS 10
COPI 11
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
*/
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
/*
Farben als hexadezimal definiert
alternativ:
int SCHWARZ = 0;
int FARBE = 15;
. . .
*/
// Pin des IR-Empfängers
int EmpfaengerPin = D6;
// Farben
#define SCHWARZ 0x0000 // dezimal 0
#define BLAU 0x000F // dezimal 15
#define ROT 0xF800 // dezimal 406664
#define GRUEN 0x0E81 // dezimal 3713
#define CYAN 0x07FF // dezimal 2047
#define MAGENTA 0xF81F // dezimal 63519
#define GELB 0xAFE5 // dezimal 65504
#define WEISS 0xFFFF // dezimal 65535
#define BRAUN 0xFC00 // dezimal 64512
#define GRAU 0xF7F0 // dezimal 63472
#define GRUENGELB 0xAFE5 // dezimal 45029
#define DUNKELCYAN 0x03EF // dezimal 1007
#define ORANGE 0xFD20 // dezimal 64800
#define PINK 0xFC18 // dezimal 64536
// Farbe der Blöcke
#define FarbeBloecke GRUEN
// Farbe des Kreises
#define Kreisfarbe ROT
// Farbe der Schrift
#define Schriftfarbe WEISS
// Spiel starten wenn * gedrückt wurde
bool SpielStart = false;
// Radius des Kreises
const int Radius = 10;
const int Abstand = Radius * 2;
// je höher, dest langsamer
const int Geschwindigkeit = 100;
// Vorwärtsbewegung des Kreises in Pixeln
const int Bewegung = 5;
// Startposition des Kreises
int CursorX = Radius;
int CursorY = tft.height() / 2 - Abstand;
// Variable für die Zeitmessung
long Start;
Der setup-Teil:
void setup()
{
// Startbildschirm
// schwarzes Farbschema horizontale Ausrichtung
// Cursor setzen, Schriftgröße und -farbe definieren
tft.initR(INITR_BLACKTAB);
tft.setRotation(0);
tft.fillScreen(SCHWARZ);
tft.setTextSize(2);
tft.setCursor(1, 10);
tft.setTextColor(Schriftfarbe);
tft.println("Start:");
tft.print("-> *");
Serial.begin(9600);
IrReceiver.begin(EmpfaengerPin);
}
Der loop-Teil. Beachte die Kommentare.
void loop()
{
// nur ausführen, wenn SpielStart true
if (IrReceiver.decode() && !SpielStart)
{
// nächsten Wert lesen
IrReceiver.resume();
// Start mit *
if (IrReceiver.decodedIRData.command == 66)
{
// Spiel wird gestartet
SpielStart = true;
// Parcours bauen
ParcoursBauen();
// Zeitmessung starten
Start = millis();
}
}
// wenn die Taste * gedrückt wurde
if (SpielStart)
{
if (IrReceiver.decode())
{
// nächsten Wert lesen
IrReceiver.resume();
// nach oben
if (IrReceiver.decodedIRData.command == 0x46)
{
// Kreis an der aktuellen Position "löschen"
tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
// wenn der Bildschirmrand noch nicht erreicht wurde
// rückwärts (Richtung x = 1) bewegen
if (CursorY > Radius) CursorY -= Bewegung;
tft.fillCircle(CursorX, CursorY, Radius, Kreisfarbe);
delay(Geschwindigkeit);
}
// nach unten
if (IrReceiver.decodedIRData.command == 21)
{
tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
if (CursorY < tft.height() - Radius) CursorY += Bewegung;
tft.fillCircle(CursorX, CursorY, Radius, Kreisfarbe);
delay(Geschwindigkeit);
}
// nach links
if (IrReceiver.decodedIRData.command == 68)
{
tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
if (CursorX > Radius) CursorX -= Bewegung;
tft.fillCircle(CursorX, CursorY, Radius, Kreisfarbe);
delay(Geschwindigkeit);
}
// nach rechts
if (IrReceiver.decodedIRData.command == 67)
{
tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
CursorX += Bewegung;
tft.fillCircle(CursorX, CursorY, Radius, Kreisfarbe);
delay(Geschwindigkeit);
}
}
// rechter Bildschirmrand erreicht -> Spielende
if (CursorX > tft.height() - Radius * 2)
{
ErgebnisZeigen();
}
}
}
Jetzt fehlen noch die ⇒Funktionen ErgebnisZeigen() und ParcoursBauen():
void ErgebnisZeigen()
{
// Zeit berechnen
int Sekunden;
long VerstricheneZeit = millis() - Start;
Sekunden = int(VerstricheneZeit / 1000);
// Zeit anzeigen
tft.fillScreen(SCHWARZ);
tft.setTextSize(2);
tft.setCursor(1, 10);
tft.println("Zeit:");
tft.println(String(Sekunden) + " s");
tft.setCursor(1, 40);
tft.setTextColor(ROT);
tft.println();
tft.println("Neustart:");
tft.println("-> *");
// Neustart
SpielStart = false;
}
void ParcoursBauen()
{
CursorX = Radius;
CursorY = tft.height() / 2 - Abstand;
tft.fillScreen(SCHWARZ);
// Kreis anzeigen
tft.fillCircle(CursorX, CursorY, Radius, Kreisfarbe);
// Parcours "bauen"
tft.fillRect(65, 35, 5, 45, FarbeBloecke);
tft.fillRect(1, 1, 35, 35, FarbeBloecke);
tft.fillRect(1, 80, 70, 80, FarbeBloecke);
tft.fillRect(110, 1, 70, 95, FarbeBloecke);
tft.fillRect(110, 130, 140, 160, FarbeBloecke);
}
Verwandte Anleitungen:
- Automatische Tür mit Hall-Sensoren
- Bibliothek TFT_eSPI
- Countdown mit einer einstelligen 7-Segment-Anzeige
- Countdown mit einem OLED-Display
- Datum und Zeit mit dem NTP-Protokoll anzeigen
- DHT - Messdaten und Zeit auf TFT anzeigen
- ESP - DHT Messdaten auf Waveshare 1,54 Zoll E-Ink anzeigen
- ESP32-Wroom – BMP280/DHT Zeit und Messdaten auf TFT anzeigen
- Wetterdaten von Openweather mit der API 3.0 auf einem TFT anzeigen
- Farbenspiele mit einer RGB-Matrix
- Glücksrad mit NeoPixel-Ring
- Labyrinthspiel mit Joystick und TFT
- Länder-Info
- LED-Matrix - Countdown
- LED-Matrix - Joystick-Spiel
- LED-Matrix - Lauflicht
- LED-Matrix Würfeln
- Lottozahlen - Anzeige auf einem LCD
- Lottozahlen - Anzeige auf einem OLED-Display
- MQTT mit ESP
- Multiplikations-Taschenrechner
- Spiel mit einer RGB-Matrix
- Spielautomat mit einer RGB-Matrix
- Taschenrechner Grundrechenarten
- Würfeln einstellige 7-Segment-Anzeige und Fernbedienung
Letzte Aktualisierung: