Reaktionstest-Minispiel Code Probleme

Hallo erstmal,
Ich versuche gerade ein Reaktionstest-Minispiel zu programmieren, mit 3 Tastern, einem Piezo Speaker und dem seriellem Monitor. Mir werden keine Fehlermeldungen angezeigt und ich bin mir auch bei dem Schaltplan sicher, dass er richtig ist. Deswegen wollte ich hier fragen ob ihr Fehler in dem Code findet. Wenn ich den Code hochlade, funktioniert alles, bis zu dem eintscheidenden Teil, den Tastern.
Hier der Code:

int a=0;                                                                                  
 // die Variablen werden festgelegt und initialisiert
int Taster=13;
int Piepser=8;
int Tasterstatus=0;
int Reaktionszeit=0;
int Tasterx=12;
int Tastery=11;
int Tasterstatusx=0;
int Tasterstatusy=0;
int Reaktionszeitx=0;
int Reaktionszeity=0;                                                                          

void setup() {
 Serial.begin(9600) ;
 randomSeed (analogRead(A0));                                                            
// verhindert, dass sich Zufallszahlen wiederholen
 pinMode(Taster,INPUT);
 pinMode(Tasterx,INPUT);                                                                 
// stellt die digitalen Pins der Taster auf INPUT
 pinMode(Tastery,INPUT);
 pinMode(Piepser,OUTPUT);                                                                
// und den Piezo Speaker auf OUTPUT
}

void loop() {
 a=random(3000,10000);                                                                  
 // a wird auf eine Zufallszahl zwischen 3000 und 10000 festgelegt
 Serial.println("Start");                                                               
 // den Kandidaten wird auf dem seriellen Monitor angezeigt, dass der Test startet
 delay(a);                                                                               
// es wird a Millisekunden lang gewartet
 Serial.println("Signal");
 digitalWrite(Piepser,HIGH);                                                             
// der Piezo Speaker wird als Signal, dass man jetzt drücken soll angeschaltet
 while(Tasterstatus!=HIGH||Tasterstatusx!=HIGH||Tasterstatusy!=HIGH)                     
// bis einer der Taster gedrückt wird, werden sie ausgelesen und jede ms werden alle Reaktionszeiten um 1 erweitert
 {
  Tasterstatus=digitalRead(Taster);
  Tasterstatusx=digitalRead(Tasterx);
  Tasterstatusy=digitalRead(Tastery);
  delay(1);
  Reaktionszeit=Reaktionszeit+1 ;
  Reaktionszeitx=Reaktionszeitx+1 ;
  Reaktionszeity=Reaktionszeity+1;
 }
 digitalWrite(Piepser,LOW);                                                              
// Nachdem einer der Kandidaten auf einen Taster drückt, geht der Speaker wieder aus
 if (Tasterstatus==HIGH) {
 Serial.println ("Reaktionszeit:");
 Serial.println (Reaktionszeit);
 }
 if (Tasterstatusx==HIGH){
// Der Gewinner, also wessen Tasterstatus auf HIGH ist, wird zusammen mit seiner Reaktionszeit  angezeigt
 Serial.println ("Reaktionszeit Kandidat X:");                                           
 Serial.println (Reaktionszeitx); 
 }
 if (Tasterstatusy==HIGH) {
 Serial.println ("Reaktionszeit Kandidat Y:");
 Serial.println (Reaktionszeity);
 }
 if (Reaktionszeit<5 || Reaktionszeitx<5 || Reaktionszeity<5){                           
// Wenn die Reaktionszeit unter 5ms ist, was ja quasi unmöglich ist, er also vor dem Piepsen gedrückt und damit den Taster ausgelöst hat, wird der angebliche Gewinner als "CHEATER" bezeichnet
  Serial.println("CHEATER");
 }
 delay(10000);                                                                           
//Nach 10 s werden alle relevanten Werte zurückgesetzt und eine neue Runde wird gestartet
 Reaktionszeit=0;
 Reaktionszeitx=0;
 Reaktionszeity=0;
 Tasterstatus=LOW;
 Tasterstatusx=LOW;
 Tasterstatusy=LOW;
 
}

Ich hoffe ich habe in meinem ersten Beitrag hier alles richtig gemacht...
Danke für eine baldige Antwort!

wie haben Sie die tastern verkabelt?
Haben Sie einen externen Pull-Down?

Ja habe ich und jeweils mit 5V, GND und einem digitalen Pin.

bitte zeichne einen Schaltplan aus dem wir die Verkabelung sehen können.
Hast du Pulldown oder Pullup Widerstände?
Mach ein Echtbild von deinem Aufbau.

Am Pin 13 hängt auch die interne LED, das kann sich negativ auf deine Logik auswirken.

das kann sich je nach verwendeten Arduino-Modell negativ auf Deine Logik auswirken.

und kein Resistor?

@anonym0811
bitte beantworte die Fragen der freiwilligen Helfer.

Wenn man Pulldown Widerstände verwendet und die Taster nach VCC schließen, dann funktioniert ein Sketch wie dieser:

// https://forum.arduino.cc/t/reaktionstest-minispiel-code-probleme/951155
// die Variablen werden festgelegt und initialisiert
//#define NOIASCA jawoi
#ifndef NOIASCA
// der Poster
constexpr byte Taster = 13;
constexpr byte Piepser = 8;
constexpr byte Tasterx = 12;
constexpr byte Tastery = 11;
#else
constexpr byte Piepser = 13;
constexpr byte Taster = A1;
constexpr byte Tasterx = A2;
constexpr byte Tastery = A3;
#endif

constexpr byte player = 3;         // how many players
const char *playerName[player] {"Anton", "Berta", "Cäsar"};      // names for the players
uint32_t reaktionszeit[player];
constexpr byte pin[player] {Taster, Tasterx, Tastery};           // copy the pins into an array
uint32_t pressed[player];          // has the player already pressed
uint32_t previousMillis[player];   // when has the player pressed

void setup() {
  Serial.begin(9600) ;
  randomSeed (analogRead(A0));
  // verhindert, dass sich Zufallszahlen wiederholen
  pinMode(Taster, INPUT);
  pinMode(Tasterx, INPUT);
  // stellt die digitalen Pins der Taster auf INPUT
  pinMode(Tastery, INPUT);
  pinMode(Piepser, OUTPUT);
  // und den Piezo Speaker auf OUTPUT
}

void loop() {
  uint16_t a = random(3000, 10000);
  // a wird auf eine Zufallszahl zwischen 3000 und 10000 festgelegt
  Serial.println("Start");
  // den Kandidaten wird auf dem seriellen Monitor angezeigt, dass der Test startet
  uint32_t startMillis = millis();
  while (millis() - startMillis < a)
  {
    // frühstarts erkennen
    for (int i = 0; i < player; i++)
    {
      if (pressed[i] == false && digitalRead(pin[i]) == HIGH) {
        Serial.print("zu früh gedrückt hat Spieler "); Serial.println(playerName[i]);
        pressed[i] = true;
        reaktionszeit[i] = -1 ;  // Fehlstart
      }
    }
  }

  // es wird a Millisekunden lang gewartet
  Serial.println("Signal");
  digitalWrite(Piepser, HIGH);
  startMillis = millis();
  // der Piezo Speaker wird als Signal, dass man jetzt drücken soll angeschaltet
  while (pressed[0] == false ||  pressed[1] == false || pressed[2] == false)
    // bis einer der Taster gedrückt wird, werden sie ausgelesen und jede ms werden alle Reaktionszeiten um 1 erweitert
  {
    uint32_t currentMillis = millis();
    for (int i = 0; i < player; i++)
    {
      if (pressed[i] == false && digitalRead(pin[i]) == HIGH) {
        Serial.print("gedrückt hat Spieler "); Serial.println(playerName[i]);
        pressed[i] = true;
        previousMillis[i] = currentMillis;
        reaktionszeit[i] = currentMillis - startMillis;
      }
    }
  }
  digitalWrite(Piepser, LOW); // nachdem alle  Kandidaten auf einen Taster drückt haben , geht der Speaker wieder aus

  // Ausgabe
  for (int i = 0; i < player; i++)
  {
    Serial.print("Reaktionszeit von ");
    Serial.print(playerName[i]);
    Serial.print(" ist ");
    Serial.print(reaktionszeit[i]);
    // warnhinweis fehlt noch - finde ich aber ungerecht
    Serial.println();
  }

  delay(10000);
  //Nach 10 s werden alle relevanten Werte zurückgesetzt und eine neue Runde wird gestartet
  for (int i = 0; i < player; i++)
  {
    reaktionszeit[i] = -1;
    pressed[i] = false;
  }
}

gibt so was aus:

Start
zu früh gedrückt hat Spieler Berta
Signal
gedrückt hat Spieler Anton
gedrückt hat Spieler Cäsar
Reaktionszeit von Anton ist 1427
Reaktionszeit von Berta ist 4294967295
Reaktionszeit von Cäsar ist 2640

Was funktioniert da denn nicht? 'funktioniert nicht' ist eine recht nichtssagene Aussage.

while(Tasterstatus!=HIGH||Tasterstatusx!=HIGH||Tasterstatusy!=HIGH)                     

Deine while-Bedingung scheint mir falsch. Die while-Schleife wird erst beendet, wenn alle Bedingung falsch sind ( ODER Verknüpfung ). Das ist erst der Fall, wenn alle Tasten gedrückt sind. Ist das so gewollt? Die Reaktionszeiten kannst Du so nicht bestimmen.

Beschäftige dich mal mit millis(). Das ist die richtige Funktion, um solche Reaktionszeiten zu messen. Edit: wie im Beispiel von @noiasca :wink:

Danke für Ihre Hilfe, das erscheint mir logisch. Mit nichts meine ich, dass der Piepser weiter piepst und nichts weiteres passiert, das würde also passen.
Was würden Sie denn als Lösung der While Schleife vorschlagen, oder ist der gesamte Ansatz falsch?

Danke, das probiere ich am Donnerstag aus, bis dahin habe ich leider keinen Zugriff auf den Arduino. Nachdem ich es ausprobiert habe, werde ich Ihnen rückmelden, ob es funktioniert hat.

das Portal https://wokwi.com/ ermöglicht dir einen Sketch auf simulierter Hardware ausprobieren zu können.

Danke :+1:, das ist wirklich SEHR hilfreich!