Programm funktioniert nicht

Hi, zusammen ich versuche mich gerade an einem Projekt. Es soll ein Reaktionstester werden, der nach Betätigung des Tasters eine Sequenz abspielt. In einem bestimmten Takt leuchtet die rote und gelbe LED auf. Wenn die grüne LED aufleuchtet, soll man den Taster nochmal betätigen und die Reaktionszeit wird gemessen. Drückt der Anwender zu früh, wenn gelb oder rot noch leuchtet, dann wird Fehlversuch angezeigt. Die Reaktionszeit soll über ein LCD-Display sichtbar sein, welches über ein Schieberegister zuvor angeschlossen wurde. (Es sollen Anschlüsse am Arduino gespart werden.

Leider Funktioniert das Programm nicht richtig. Nur die rote LED leuchtet, wenn ich den Taster betätige.

Ich arbeite mit dem Arduino MEGA 2560.
Ich habe den Schaltplan mit wokwi erstellt, weil ich nicht andere Bibliothek-Elemente hochladen kann, wird natürlich das als Error ausgegeben.

Folgende Datei habe ich für den Liquid Crystal-Datensatz verwendet:
LiquidCrystal_74HC595 - Arduino Reference

Vielleicht könnt ihr mir helfen?

Vielen Dank im Voraus. :slightly_smiling_face:Reaktionstester

Hier ist der Programmcode:

#include <Wire.h>
#include <LiquidCrystal_74HC595.h>

#define DS 11
#define SHCP 13
#define STCP 12
#define RS 1
#define E 2
#define D4 3
#define D5 4
#define D6 5
#define D7 6

LiquidCrystal_74HC595 lcd(DS, SHCP, STCP, RS, E, D4, D5, D6, D7);

#define TASTER 7     // Taster-Pin
#define LEDROT 10    // RCB-LED Rot
#define LEDGELB 9   // RCB-LED Gelb
#define LEDGRUEN 8  // RCB-LED Grün
#define LEVEL 5       // Schwierigketis-Level

int taktPin = 13;    // SH_CP
int speicherPin = 12;  // ST_CP
int datenPin = 11;    // DS
byte phase = 0;       // 1 = Rot, 2 = Gelb, 3 = Grün
long startPunkt = 0;  // Wenn Taster gedrückt - > Startpunkt
byte anzeigeWert, stopZeit;
boolean taster = false, gestoppt = false;

void setup() {
  pinMode(taktPin, OUTPUT);
  pinMode(speicherPin, OUTPUT);
  pinMode(datenPin, OUTPUT);
  pinMode(TASTER, INPUT);
  pinMode(LEDROT, OUTPUT);

  // LCD-Setup
  lcd.setCursor(0, 0);
  lcd.print("Reaktionstest:");
}

void loop() {
  taster = digitalRead(TASTER);

  if (phase < 3) {
    zeigeWert(0);  // Zeige am Anfang 00 in der Anzeige
  }

  // Steuerung der Ampelphasen
  if ((taster) && (startPunkt == 0)) {
    phase = 1;  // Beginne mit Rot
    startPunkt = millis();
  }

  if ((phase == 1) && (millis() - startPunkt > 2000)) {
    digitalWrite(LEDROT, HIGH);
  }

  if ((phase == 1) && (millis() - startPunkt > 4000)) {
    digitalWrite(LEDGELB, HIGH);
    phase = 2;  // Gelb
  }

  if ((phase == 2) && (millis() - startPunkt > 6000)) {
    digitalWrite(LEDROT, LOW);
    digitalWrite(LEDGELB, LOW);
    digitalWrite(LEDGRUEN, HIGH);
    phase = 3;  // Grün
  }

  // Zähle hoch, wenn LED Grün und noch nicht gestoppt wurde
  if ((phase == 3) && (!gestoppt)) {
    zeigeWert(anzeigeWert++);
    delay(LEVEL);  // Schwierigkeits-Level
  }

  // Leuchtet LED Grün und der Taster wurde gedrückt
  if ((taster) && (phase == 3)) {
    gestoppt = true;         // Flag für gestoppt auf "wahr" setzen
    stopZeit = anzeigeWert;  // Stopzeit sichern
  }

  // Wenn gestoppt, dann Stopzeit anzeigen
  if (gestoppt) {
    zeigeWert(stopZeit);
  }

  // Wenn in Gelbphase Taster gedrückt -> zu früh
  if ((taster) && (phase == 2)) {
    fehlVersuchAnzeigen();
  }


  // Wenn überhaupt nicht reagiert wird -> Fehlversuch anzeigen
  if (anzeigeWert == 99) {
    fehlVersuchAnzeigen();
  }
}

// Funktion zur Anzeige auf dem LCD
void zeigeWert(byte wert) {
  lcd.setCursor(0, 1);
  lcd.print("Reaktionszeit: ");
  lcd.print(wert);
  lcd.print(" ms     ");
}

// Funktion zum Anzeigen eines Fehlversuchs und Zurücksetzen der Sequenz
void fehlVersuchAnzeigen() {
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Fehlversuch!");
  delay(2000);  // Anzeige für 2 Sekunden halten
  lcd.clear();  // Display löschen
  phase = 0;    // Sequenz zurücksetzen
  startPunkt = 0;
  gestoppt = false;
}


Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Du hast am 2560 doch genügend freie Pins. Warum willst Du das Display dann über Schieberegister ansteuern?
Für unbenutzte Pins bekommst Du kein Geld zurück :wink:

Funktioniert nicht richtig ist eine völlig unzureichende Fehlerbeschreibung.
Vorschlag: Teile Dein Projekt in Teilaufgaben, die Du zuerst einzeln funktionsfähig bringst. Z.B. erst mal nur eine Zahl (wie millis()) auf dem Display darstellen, dann die LEDS steuern, dann Beides verbinden.

Gruß Tommy

 pinMode(LEDROT, OUTPUT);

Das vermisse ich für die anderen beiden LEDs

An deinem Taster ist (zumindest in deinem wokwi-Link) kein pulldown-Widerstand.
Auch nach Wechsel der LCD - lib in Wokwi (<LiquidCrystal_I2C.h>) ist zwar der Fehler weg, aber es passiert erstmal nix.

Ich verstehe den Sketch so, dass nacheinander die LEDs ROT - ROT/GELB - GRÜN leuchten sollen.
Das wäre doch erstmal ein Ziel, das du schaffen können solltest. Danach kannst du einbauen, dass es erst auf Tasterdruck passiert. Wenn das geht, ist es früh genug, sich um deine Schieberegister-Anzeige zu kümmern, für die du wohl Mühe haben wirst, das in wokwi nachzubauen.
So schnell dass du die Anzeige im Microsekundenbereich aktualisierst, wird es aber sowieso nicht, warum diesen Teil nicht erstmal weglassen? Also ab da die Zeit bis zum nächsten Tastendruck messen und dann einmalig anzeigen? ( Serial Ausgabe in Wokwi ) Der nächste Tastendruck startet dann wieder die Startsequenz.

Ist leider Vorgabe. Ja okay dann teile ich die Aufgabe auf. :+1:

Danke für die Antwort. Wahrscheinlich gestaltet es sich besser raus die Aufgabe in Teilaufgaben einzuteilen.

Hallo,
Du solltest ein paar Serial.print () einbauen um das Program debuggen zu können. z.B an verschiedene Stellen die Variable "phase" anzeigen lassen.

So wie ich das sehe hängst Du derzeit in dem Teil für die rote LED fest und Du kommst, warum auch immer, nicht in die nächste if... Verzweigung um die gelbe LED einzuschalten. Mach doch für die gelbe LED eine separate phase. Mit enum () kannst Du den einzelnen phasen auch Namen geben .

Auch wäre es für den Reaktionstest sicher sinnvoll wenn die Wartezeit, bis von gelb auf grün gewechselt wird, nicht immer konstant wäre.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.