„Triff die Zahl“ ist ein Reaktionsspiel. In dem Spiel geht es darum, eine gedrückt-gehaltene Taste im richtigen Moment
loszulassen. Sobald ein Spieler eine Taste betätigt, wird auf den zwei linken Feldern der zentralen Spielanzeige, die aus einer
7-Segmentanzeige mit 4-Digit besteht, eine zweistellige Ziel-Zahl eingeblendet. Gleichzeitig beginnt auf der rechten Seite der Spielanzeige
ein Zähler hochzulaufen. Die Aufgabe des Spielers besteht darin, die Taste dann loszulassen, wenn der Zähler die Ziel-Zahl erreicht hat.
Stimmen nach dem Loslassen der Taste beide Zahlen überein, gibt es einen Punkt. Andernfalls wird ein Punkt abgezogen. Es gewinnt der
Spieler, der die meisten Punkte eingesammelt hat. Der rechts laufende Zähler der Spielanzeige zeigt jedoch nur die Ziffern 0 bis 9 an.
Bei einer Ziel-Zahl von z.B. 47 muss sich der Spieler die vier Zehnerreihen selbst merken.
Es wird bei dem Spiel demnach nicht nur die Reaktionsfähigkeit des Spielers, sondern auch sein Gedächtnis
auf die Probe gestellt.
In dem Beispiel kann man zwei Spiellevels anwählen. Jeder Level bedeutet ein anderes Tempo des Hochzählens.
Zwei weitere 7-Segmentanzeigen, die jeweils aus einem Digit bestehen, zeigen die Punkte, die die Spieler erzielt haben, an. Zwei
Leuchtdioden signalisieren, welcher Spieler gerade an der Reihe ist.
Die Koordinationsarbeiten der Schaltung werden von Arduino bewältigt. Insgesamt werden in der Schaltung 20 Digital
I/O Pins in Anspruch genommen.
Mit zwei 1-Digit 7-Segmentanzeigen 5101AH werden die Punkte der Spieler angezeigt. Beide Anzeigen werden mithilfe zwei
Schieberegistern 74HC595 angesteuert. Die Schieberegister sind in Reihe (Kaskadenschaltung) verschaltet. Die Weiterleitung der Bits von
einem Schieberegister zu dem anderen erfolgt über die DS Leitung. Für die Koordination bei Laden der Bits sorgen die Leitungen SHCP und STCP.
Die einzelnen Elemente der 7-Segmentanzeigen sind mit 1 kOhm Widerständen abgesichert.
Die Ziel-Zahl und der laufende Zähler werden auf der 4-Digit 7-Segmentanzeige SH5461AS angezeigt. Die Anzeige wird
ohne Zwischenbausteine direkt von Arduino gesteuert. Bei Ansteuerung der Anzeige wird Multiplexing-Verfahren angewendet. Dabei werden
die einzelnen Digits nacheinander ein- und ausgeschaltet. Das Umschalten findet so schnell statt, dass ein Mensch das nicht wahrnehmen
kann. Die Anzeige braucht dank der Methode nicht 28 (4x7), sondern nur 11 (7+4) I/O-Pins.
// ***********************************************************************
// Triff die Zahl
// Reaktionsspiel
// 7-Segmentanzeige 1 und 4-Digit, Schieberegister 74HC595
// Arduino Mega 2560, IDE 1.8.13
// ************************************************************************
// Ausgänge für die Segmente
// der 4fach 7-Segmentanzeige
int Segment [7] = {31,33,35,37,39,41,43};
// Digit 1 bis 4
// der 4fach 7-Segmentanzeige
int Digit [4] = {45, 47, 49, 51};
// Schieberegister
int SHCP = 40;
int STCP = 42;
int DS = 44;
// Anzeige LEDs
int LED_1 = 23;
int LED_2 = 25;
// Schalter
int Schalter_1 = 46; // Spieler 1 (Taster)
int Schalter_2 = 48; // Spieler 2 (Taster)
int Schalter_3 = 50; // Reset (Neustart) (Taster)
int Schalter_4 = 52; // Level (Schalter)
// Bits für die Ziffern 0 bis 9
int Ziffern [11] = { B11111100, B01100000, B11011010, B11110010, B01100110,
B10110110, B10111110, B11100000, B11111110, B11110110 };
int Punkte_Aktuell [2]; // Pos 0 = Punkte Spieler 1
// Pos 1 = Punkte Spieler 2
int Spieler; // Spieler Nummer (2 Spieler)
bool Start;
unsigned long MillisAktuell;
unsigned long MillisLevel;
int Wert [4] ; // Pos 0 = Soll Ziffer 1
// Pos 1 = Soll Ziffer 2
// Pos 2 = Ist Ziffer 1
// Pos 3 = Ist Ziffer 2
// ........................................................ SetUp
void setup() {
// Ausgänge
for (int i=0; i<7; i++) {
pinMode (Segment[i], OUTPUT); }
for (int i=0; i<4; i++) {
pinMode (Digit[i], OUTPUT); }
pinMode (SHCP, OUTPUT);
pinMode (STCP, OUTPUT);
pinMode (DS, OUTPUT);
pinMode (LED_1, OUTPUT);
pinMode (LED_2, OUTPUT);
// Eingänge
pinMode (Schalter_1, INPUT_PULLUP);
pinMode (Schalter_2, INPUT_PULLUP);
pinMode (Schalter_3, INPUT_PULLUP);
pinMode (Schalter_4, INPUT_PULLUP);
// Vorbelegung
Punkte_Aktuell [0] = 5;
Punkte_Aktuell [1] = 5;
}
// ........................................................ 4 Digit Anzeige
void Anzeige (int DigitNr, int Wert) {
for (int i=0; i<4; i++) { // Alle Digit aus
digitalWrite (Digit [i], HIGH); }
digitalWrite (Digit [DigitNr], LOW); // DigitNr ein
for (int i=0; i<7; i++) { // Segmente a-g e/a
digitalWrite(Segment[i], bitRead(Ziffern[Wert],7-i));
}
delay(5); }
// ........................................................ Zufallszahlen als Aufgabe
void Ziel_Zahl_holen () {
Wert [0] = random (1,3);
Wert [1] = random (0,9);
}
// ........................................................ Hauptprogramm
void loop() {
if (digitalRead(Schalter_3) == LOW) { // RESET
Punkte_Aktuell [0] = 5;
Punkte_Aktuell [1] = 5;
Spieler = 0;
}
MillisLevel = 400;
if (digitalRead(Schalter_4) == LOW) { // Level Wechsel
MillisLevel = 100;
}
if (Spieler == 0) {
digitalWrite(LED_1, HIGH);
digitalWrite(LED_2, LOW);
}
if (Spieler == 1) {
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, HIGH);
}
// Spielstand anzeigen
digitalWrite(STCP, LOW);
shiftOut(DS, SHCP, LSBFIRST, Ziffern [Punkte_Aktuell[1]]);
shiftOut(DS, SHCP, LSBFIRST, Ziffern [Punkte_Aktuell[0]]);
digitalWrite(STCP, HIGH);
// Versuch gestartet
while ((digitalRead(Schalter_1) == LOW) or (digitalRead(Schalter_2) == LOW)) {
if (not Start) { delay (10); } // Schalter Prellung abwarten
// Spieler 1 am Zug
if ((digitalRead(Schalter_1) == LOW) && not Start) {
Spieler = 0;
digitalWrite(LED_1, HIGH); }
// Spieler 2 am Zug
if ((digitalRead(Schalter_2) == LOW) && not Start){
Spieler = 1;
digitalWrite(LED_2, HIGH); }
Start = true;
if (Wert[0] == 0) { Ziel_Zahl_holen(); } // Aufgabe holen (Zufall)
if (millis () > (MillisAktuell + MillisLevel)) {
MillisAktuell = millis();
Wert[3]++;
if (Wert[3] > 9) {
Wert[3] = 0;
Wert[2]++;
}
}
for (int i=0; i<4; i++) { // Anzeige 4 Digit
if (i != 2) { // Feld 3 bleibt aus
Anzeige (i, Wert [i]); }
}
}
// Taster losgelassen
if (Start) {
for (int j=0; j<100; j++) {
for (int i=0; i<4; i++) { // Anzeige 4 Digit
Anzeige (i, Wert [i]); } }
Punkte_Aktuell [Spieler]++; // Auswertung
if ((Wert[0] != Wert[2]) or (Wert[1] != Wert[3])) {
Punkte_Aktuell [Spieler] = Punkte_Aktuell [Spieler] - 2;
}
for (int i=0; i<4; i++) { // Werte löschen
Wert [i] = 0; }
digitalWrite (Digit [3], HIGH); // Anzeige aus
int Spielerwechsel = Spieler; // Spielerwechsel
Spieler = 0;
if (Spielerwechsel == 0) { Spieler = 1; }
Start = false;
}
}