Arduino LCD-Projekt: 16×2 Display mit Tastern & Widerständen selbst bauen
Komponenten und Materialien
| Komponente | Anzahl | Hinweis |
|---|---|---|
| Widerstand 10 kΩ | 2 | Einer für LCD-Kontrast, einer für Taster (Pull-Down!) |
| Widerstand 1 kΩ | 1 | Für LCD-Kontrast (in Reihe mit 10 kΩ) |
| Taster 12 mm (SparkFun) | 1 | |
| LCD 16×2 Weiß auf Blau (Adafruit Standard) | 1 | Pin-Header vorab einlöten |
| Arduino UNO | 1 | |
| Jumper-Kabel | 1 Satz |
Projekthintergrund
Ursprünglich Teil eines größeren Projekts, das sich verzögerte. Ich nutzte die Zeit, um das bisher ungenutzte LCD-Display aus meinem Arduino-Starterkit in Betrieb zu nehmen – und lernte dabei erstmals Löten.
Nach ersten Tests mit der LiquidCrystal-Bibliothek (laufender Text) entwickelte ich eine eigene kleine Animation („0“ hüpft über den Bildschirm) und schließlich ein komplettes Spiel: „Dodge the Defs“ (Verteidiger ausweichen).
Aufbau & Verdrahtung
LCD-Anschluss (4-Bit-Modus)
Die Pin-Belegung im Code: LiquidCrystal lcd(4, 6, 10, 11, 12, 13); → RS=4, EN=6, D4=10, D5=11, D6=12, D7=13.
Kontrasteinstellung
Statt eines Potentiometers werden zwei Festwiderstände (1 kΩ + 10 kΩ in Reihe) zwischen VCC und GND geschaltet, der Mittelabgriff geht an VO (Pin 3 des LCD). Dies fixiert den Kontrast dauerhaft.
Taster-Anschluss (Wichtig!)
Der Taster wird im Pull-Down-Modus an Pin 8 angeschlossen:
- Ein Taster-Pin → 5 V
- Anderer Pin → Arduino Pin 8 und über 10 kΩ → GND
Nicht den Pull-Up aus dem Arduino-Tutorial verwenden – der Code erwartet HIGH bei gedrücktem Taster.
Spielprinzip: „Dodge the Defs“
Sie sind ein Fußballspieler (eigenes Custom-Character) unten links. Verteidiger (Custom-Characters) rücken von rechts nach. Drücken Sie den Taster im richtigen Moment, um zu springen. Nach 10 Verteidigern haben Sie gewonnen. Die Geschwindigkeit steigt mit jedem Verteidiger.
Eigene Zeichen (Custom Characters)
Erstellt mit LCD Character Generator:
- Spieler Lauf-Pose 1 & 2
- Spieler Sprung-Pose
- Verteidiger Lauf-Pose 1 & 2
- Verteidiger Rutsch-Pose (nah am Spieler)
Vollständiger Programmcode
/* Dodge the Defs!! – 16x2 LCD Spiel mit Taster
* Erstellt: Shreyas R P, 21.06.2018
* Lizenz: GPL v3
*/
#include <LiquidCrystal.h>
const int btn = 8; // Taster an Pin 8 (Pull-Down)
// Intro-Texte
char* introText[] = {
"Dodge the Defs!!",
"Created on:",
"Hit the button..."
};
// Variablen
int game = 0;
int buttonPress = 0;
int buttonState = 0;
int obstaclePos;
int obsDelay;
int score = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
int lastButtonState = LOW;
// Custom Characters (8 Bytes each)
byte runnin1[8] = {0b01100, 0b01100, 0b00000, 0b11100, 0b01110, 0b01100, 0b11110, 0b00011};
byte runnin2[8] = {0b00110, 0b00110, 0b00000, 0b00111, 0b01110, 0b00110, 0b01110, 0b00101};
byte jump[8] = {0b00100, 0b01100, 0b11100, 0b01110, 0b01100, 0b11111, 0b00000, 0b00001};
byte def1[8] = {0b00100, 0b00110, 0b00111, 0b01110, 0b00110, 0b01111, 0b01000, 0b00000};
byte def2[8] = {0b00100, 0b00110, 0b00111, 0b01110, 0b00110, 0b00110, 0b00110, 0b00010};
byte slide[8] = {0b00000, 0b00000, 0b00011, 0b00011, 0b00000, 0b01111, 0b11111, 0b00000};
LiquidCrystal lcd(4, 6, 10, 11, 12, 13);
void setup() {
Serial.begin(9600);
pinMode(btn, INPUT);
lcd.begin(16, 2);
lcd.createChar(0, runnin1);
lcd.createChar(1, runnin2);
lcd.createChar(2, jump);
lcd.createChar(3, def1);
lcd.createChar(4, def2);
lcd.createChar(5, slide);
buttonState = digitalRead(btn);
}
void loop() {
intro();
while (game == 1) ballActive();
endGame();
}
void intro() {
score = 0;
lcd.clear();
lcd.print(introText[0]);
lcd.setCursor(7, 1);
lcd.print("By SRP888");
delay(2000);
lcd.clear();
lcd.print(introText[1]);
lcd.setCursor(0, 1);
lcd.print("21-06-2018");
delay(2000);
lcd.clear();
while (button() != 1) { // Warten auf Tastendruck
lcd.setCursor(0, 0);
lcd.print(introText[2]);
delay(100);
}
game = 1;
}
void reset() {
// Spieler animieren (Lauf-Pose wechseln)
if (obstaclePos % 2 == 0) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.write(byte(0));
} else {
lcd.clear();
lcd.setCursor(0, 1);
lcd.write(byte(1));
}
}
void ballActive() {
obsDelay = 200; // Startverzögerung
obstaclePos = 15; // Startposition ganz rechts (0-15)
while (game == 1) {
reset();
if (button() == 1) { // Taster gedrückt -> Springen
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(byte(2)); // Sprung-Pose
obstacle(obstaclePos);
delay(400); // Anzeigedauer
lcd.clear();
lcd.setCursor(0, 1);
lcd.write(byte(1)); // Wieder am Boden
obstacle(obstaclePos);
} else {
if (obstaclePos != 0) {
reset();
obstacle(obstaclePos);
} else {
// Verteidiger erreicht Spieler am Boden -> Game Over
game = 0;
break;
}
}
obstaclePos--; // Verteidiger rückt näher
if (obstaclePos < 0) { // Erfolgreich ausgewichen
obsDelay -= 20; // Schneller werden
obstaclePos = 15; // Zurück zum Start
score++;
}
if (obsDelay == 0) { // 10 Verteidiger geschafft (200/20=10)
game = 0;
}
delay(obsDelay);
}
}
// Taster-Entprellung
int button() {
int reading = digitalRead(btn);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
buttonState = reading;
if (buttonState == HIGH) {
lastButtonState = reading;
return 1;
}
}
lastButtonState = reading;
return 0;
}
// Verteidiger an Position i zeichnen
void obstacle(int i) {
if (obstaclePos % 2 == 0 && obstaclePos > 2) {
lcd.setCursor(i, 1);
lcd.write(byte(3)); // Laufen 1
} else if (obstaclePos % 2 != 0 && obstaclePos > 2) {
lcd.setCursor(i, 1);
lcd.write(byte(4)); // Laufen 2
} else {
lcd.setCursor(i, 1);
lcd.write(byte(5)); // Rutschen (gefährlich nah)
}
}
void endGame() {
lcd.clear();
if (score == 10) {
lcd.print("Congratulations!");
lcd.setCursor(0, 1);
lcd.print("You beat 'em all");
} else if (score < 3) {
lcd.print("You suck");
lcd.setCursor(0, 1);
lcd.print("Score: ");
lcd.print(score);
} else if (score < 6) {
lcd.print("Not bad!");
lcd.setCursor(0, 1);
lcd.print("Score: ");
lcd.print(score);
} else {
lcd.print("Great!");
lcd.setCursor(0, 1);
lcd.print("Score: ");
lcd.print(score);
}
delay(3000);
}
Schaltplan
Die Verdrahtung entspricht dem Fritzing-Schaltplan: LCD im 4-Bit-Modus, Kontrast über 1 kΩ + 10 kΩ Spannungsteiler, Taster mit 10 kΩ Pull-Down an Pin 8.
Lizenz
GPL v3 – Weiterentwicklung und Verbesserungen ausdrücklich erwünscht!
Herstellungsprozess
- Warum Rapid Prototyping für erfolgreiche Produktentwicklung unverzichtbar ist
- Produktdesign meistern: Bewährte Strategien zur Überwindung gängiger Herausforderungen
- Die Tetrode: Design, Funktion und Einfluss auf die Verstärkerleistung
- Professionelle Temperaturüberwachung mit Raspberry Pi und DS18B20
- Primal Display: Raspberry Pi LCD-Temperaturmonitor mit DHT11 bauen
- Drone Pi: Dual-Mode Multiwii & Raspberry Pi Quadrocopter für Smartphone- und Fernsteuerung
- Archimedes: Der emotionserkennende KI-Roboter-Eule
- Strategische Datensourcen: Der Schlüssel zu resilienten Lieferketten
- Bewährte Schritte für schnelle, günstige industrielle Touchscreen-Reparatur
- Laubbläser 2024: Das passende Modell für Ihren Garten finden