kk logo

Wozu zur Lotto Annahmestelle gehen, wenn man den Nervenkitzel direkt auf den Schreibtisch holen kann? Dieses Projekt verwandelt einen Arduino und ein großes TFT-Display in eine digitale Lotto-Maschine. Ob als kleiner Zeitvertreib zwischendurch oder als Entscheidungshilfe, wer den nächsten Kaffee kocht das Spiel kombiniert präzise Eingabe mit einer spannenden Zufalls-Animation. Im Kern handelt es sich um eine digitale Spielkonsole für zwei Personen, die das Prinzip des Lottospiels simuliert. Das Besondere dabei ist die haptische Eingabe: Statt langweiliger Knöpfe nutzt dieses Projekt einen Rotary Encoder, um die Ziffern einzustellen. Dies vermittelt dem Spieler das Gefühl, an einem Safe-Schloss zu drehen, was die Spannung vor der Ziehung erhöht.

Spiel 64 aus der 200 Arduino Spiele Sammlung.

1 Digitales Arduino 7 Zahlen Lotto für 2 Personen

Verwendete Bauteile

  • Mikrocontroller: Arduino Uno oder Mega.
  • Display: 4" TFT LCD Modul mit ILI9486 Treiber (SPI-Schnittstelle).
  • Eingabe: Rotary Encoder (z. B. KY-040) zum Einstellen der Zahlen.
  • Taster: Ein Standard-Pushbutton an Pin 4 (oder der integrierte Encoder-Button).
  • Zubehör: Breadboard, Jumper-Kabel und eine Prise Glück.

So funktioniert das Spiel

  1. Zahlenwahl: Spieler 1 stellt über den Encoder sieben Ziffern (0–9) ein. Die aktuell gewählte Ziffer leuchtet gelb. Mit einem Tastendruck springt man zur nächsten Stelle.
  2. Spielerwechsel: Nachdem Spieler 1 fertig ist, wiederholt Spieler 2 den Vorgang.
  3. Die Ziehung: Sobald alle 14 Zahlen feststehen, startet ein Druck auf den Button die Animation. In der Mitte des Bildschirms "rattern" die Lottozahlen eine Sekunde lang durch, bevor sie bei einer zufälligen Kombination stehen bleiben.
  4. Die Auswertung: Das System vergleicht die Tipps automatisch. Treffer werden blau markiert, Nieten rot. Der Spieler mit den meisten Treffern gewinnt, und seine Zahlenreihe beginnt zur Feier des Tages schnell zu blinken.

Das eingeben der Zahlen:

3 Digitales Arduino 7 Zahlen Lotto für 2 Personen

Die Auswertung der Zahlen, das FÜR habe ich in FUER geändert. 

2 Digitales Arduino 7 Zahlen Lotto für 2 Personen

Hardware-Anschluss und SPI Setup

Bauteil Arduino Pin Funktion
TFT Display 10 CS (Chip Select)
8 DC (Data/Command)
9 RST (Reset)
11/13 MOSI / SCK (Standard SPI)
Encoder 2 Phase A
3 Phase B
Button 4 Start / Bestätigen

Die 4 wichtigsten Code-Stellen

1. Die Encoder-Logik (Modulo-Trick)

Damit die Zahlen beim Drehen sauber zwischen 0 und 9 springen, nutzen wir eine Modulo Rechnung.

if (currentDigit < 7) {
p1[currentDigit] = (p1[currentDigit] + diff + 10) % 10;
} else {
p2[currentDigit - 7] = (p2[currentDigit - 7] + diff + 10) % 10;
}

  • Erklärung: Das sorgt dafür, dass die Zahl beim Runterdrehen unter 0 sofort wieder bei 9 landet (und umgekehrt), ohne dass der Code abstürzt oder komplizierte -Abfragen braucht.

2. Die Lotto-Animation

Für das echte Casino-Feeling dürfen die Zahlen nicht einfach nur erscheinen.

while (millis() - startTime < 1000)
            { tft.print(random(0, 10)); delay(70); }

  • Erklärung: In einer -Schleife werden für eine Sekunde lang ständig neue Zufallszahlen an die gleiche Position geschrieben. Das menschliche Auge nimmt dies als schnelles "Rattern" oder Wirbeln wahr, wie man es von echten Spielautomaten kennt.

3. Die Gewinn Auswertung

Hier wird entschieden, wer die Krone (oder das Blinken) verdient.

if(p1[i] == lotto[i]) {
tft.setTextColor(BLUE, BLACK);
score1++;
} else {
tft.setTextColor(RED, BLACK);
}

  • Erklärung: Während der Auswertung wird jede einzelne Ziffer geprüft. Ein Treffer ändert die Textfarbe des Spielers auf Blau und erhöht seinen Punktestand (). Am Ende vergleicht der Arduino die Scores von Spieler 1 und 2, um den Sieger für die Blink-Animation festzulegen.

4. Die visuelle Ziehungs-Animation

Um Spannung aufzubauen, werden die Zahlen nicht einfach statisch angezeigt, sondern "gewirbelt".

while (millis() - startTime < 1000) {
tft.setCursor(300, 200);
tft.setTextColor(YELLOW, BLACK);
for (int i = 0; i < 7; i++) {
tft.print(random(0, 10)); // Schneller Zufallswechsel
}
delay(70);
}

  • Erklärung: In dieser -Schleife generiert der Arduino für genau eine Sekunde ständig neue Zufallszahlen an derselben Position. Das Auge nimmt das als schnelles Flimmern wahr, was den Effekt einer rotierenden Lostrommel perfekt imitiert.

5. Der gesamte Code

 

#include <SPI.h>
#include <ILI9486_SPI.h>
#include <Encoder.h>
#define TFT_CS 10
#define TFT_DC 8
#define TFT_RST 9
#define ENC_A 2
#define ENC_B 3
#define ENC_BTN 4

ILI9486_SPI tft(TFT_CS, TFT_DC, TFT_RST);
Encoder myEnc(ENC_A, ENC_B);

#define BLACK 0x0000
#define WHITE 0xFFFF
#define RED 0xF800
#define BLUE 0x001F
#define YELLOW 0xFFE0
#define GREEN 0x07E0
#define GRAY 0x7BEF

int p1[7], p2[7], lotto[7];
int currentDigit = 0;
bool drawStarted = false;
bool gameOver = false;
int winner = 0;
long oldPosition = -999;

void setup() {
pinMode(ENC_BTN, INPUT_PULLUP);
tft.setSpiKludge(false);
tft.init();
tft.setRotation(1); // Querformat
resetGame(); // Initialisiert alles
}

void loop() {
if (!drawStarted) {
handleEncoder();
} else if (gameOver) {
blinkWinner();
}


if (digitalRead(ENC_BTN) == LOW) {
delay(250);

if (gameOver) {
resetGame();
}
else if (currentDigit < 13) {
currentDigit++;
drawUI();
}
else if (!drawStarted) {
startLottoDraw();
}
}
}

void resetGame() {
// Variablen nullen
for(int i=0; i<7; i++) {
p1[i] = 0; p2[i] = 0; lotto[i] = 0;
}
currentDigit = 0;
drawStarted = false;
gameOver = false;
winner = 0;

tft.fillScreen(BLACK);
randomSeed(analogRead(A0));
drawUI();
}

void drawUI() {
tft.setTextSize(2);
tft.setTextColor(RED, BLACK);
tft.setCursor(120, 10);
tft.print("www.kreativekiste.de");
tft.drawFastHLine(0, 35, 480, GRAY);

tft.setTextSize(3);
// Spieler 1
tft.setCursor(20, 60);
tft.setTextColor(WHITE, BLACK);
tft.print("Spieler 1: ");
for(int i=0; i<7; i++) {
if(!drawStarted && currentDigit == i) tft.setTextColor(YELLOW, BLACK);
else tft.setTextColor(WHITE, BLACK);
tft.print(p1[i]); tft.print(" ");
}

// Spieler 2
tft.setCursor(20, 120);
tft.setTextColor(WHITE, BLACK);
tft.print("Spieler 2: ");
for(int i=0; i<7; i++) {
if(!drawStarted && currentDigit == i + 7) tft.setTextColor(YELLOW, BLACK);
else tft.setTextColor(WHITE, BLACK);
tft.print(p2[i]); tft.print(" ");
}

if(currentDigit > 12 && !drawStarted) {
tft.setTextSize(2);
tft.setCursor(120, 280);
tft.setTextColor(GREEN, BLACK);
tft.print("BEREIT? DRUECKEN ZUM STARTEN!");
}
}

void handleEncoder() {
long newPosition = myEnc.read() / 4;
if (newPosition != oldPosition) {
int diff = (newPosition > oldPosition) ? 1 : -1;
if (currentDigit < 7) p1[currentDigit] = (p1[currentDigit] + diff + 10) % 10;
else p2[currentDigit - 7] = (p2[currentDigit - 7] + diff + 10) % 10;
oldPosition = newPosition;
drawUI();
}
}

void startLottoDraw() {
drawStarted = true;
tft.fillRect(0, 260, 480, 60, BLACK);
tft.setTextSize(3);
tft.setCursor(20, 200);
tft.setTextColor(WHITE, BLACK);
tft.print("Lotto-Ziehung: ");

unsigned long startTime = millis();
while (millis() - startTime < 1000) {
tft.setCursor(300, 200);
tft.setTextColor(YELLOW, BLACK);
for (int i = 0; i < 7; i++) tft.print(random(0, 10));
delay(70);
}

tft.setCursor(300, 200);
tft.setTextColor(GREEN, BLACK);
for (int i = 0; i < 7; i++) {
lotto[i] = random(0, 10);
tft.print(lotto[i]);
}
checkResults();
}

void checkResults() {
int score1 = 0, score2 = 0;
tft.setCursor(215, 60);
for(int i=0; i<7; i++) {
if(p1[i] == lotto[i]) { tft.setTextColor(BLUE, BLACK); score1++; }
else tft.setTextColor(RED, BLACK);
tft.print(p1[i]); tft.print(" ");
}
tft.setCursor(215, 120);
for(int i=0; i<7; i++) {
if(p2[i] == lotto[i]) { tft.setTextColor(BLUE, BLACK); score2++; }
else tft.setTextColor(RED, BLACK);
tft.print(p2[i]); tft.print(" ");
}
winner = (score1 > score2) ? 1 : (score2 > score1 ? 2 : 3);
gameOver = true;

tft.setTextSize(2);
tft.setCursor(100, 280);
tft.setTextColor(GRAY, BLACK);
tft.print("DRUECKE FUER NEUSTART");
}

void blinkWinner() {
static unsigned long lastBlink = 0;
static bool state = true;
if (millis() - lastBlink > 250) {
state = !state;
uint16_t color = state ? YELLOW : BLACK;
tft.setTextSize(3);
if (winner == 1 || winner == 3) {
tft.setCursor(215, 60);
tft.setTextColor(color, BLACK);
for(int i=0; i<7; i++) { tft.print(p1[i]); tft.print(" "); }
}
if (winner == 2 || winner == 3) {
tft.setCursor(215, 120);
tft.setTextColor(color, BLACK);
for(int i=0; i<7; i++) { tft.print(p2[i]); tft.print(" "); }
}
lastBlink = millis();
}
}

Ronnie

schwäbischer tüftler und bastler, kraftsportler, neurodivers, 45 Jahre, 1 Frau, 5 Kinder und 1003 Ideen. 

1.2 ronnie berzins

Kontakt

visitenkarte