Gelöst , Reaktionstester Taster

Hallo!
Ich bin neu im Forum und benötige daher auch Hilfe. Ich bin in der 10 Klasse. Dort haben wir gerade als Thema Arduino in Nwt. Wir sollen in Gruppen Reaktionstester bauen. Nun haben wir unsere Idee ansatzweise umgesetzt. Wir wollen 2 LEDs zufällig angehen lassen, dann muss man auf den jeweiligen Taster draufhauen und die Rekationszeit wird auf einem LCD Display angezeigt. Diese wird solange angezeigt, bis man auf den Knopf 'nächste Runde' drückt. Dann startet das Programm wieder neu. Das heißt es geht wieder zufällig eine Led an. Nun meine Frage : Wie bekomme ich es hin, dass ich das Programm einmal ablaufen lasse und dann erst wieder startet wenn ich den Knopf drücke. Muss ich dann alles in Setup reinschreiben und mit dem Taster dann mit if in loop oder wie ? 

Vielen Dank schon mal im Voraus! 

Sketch :

int led1=3;
int led2=4;
int r=0;

int taster3= 6;
//Weiter
int vt3;
void setup() {
Serial.begin(9600);
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
pinMode (taster3,INPUT_PULLUP);

}

void loop() {
  r=random (1,3);
    Serial.println(r);
  while (vt3=0){
  if (r==1) {
  digitalWrite(led1,HIGH);}
  else{
  digitalWrite(led1,LOW); }
  if (r==2) {
  digitalWrite(led2,HIGH);}
  else{
  digitalWrite(led2,LOW); 
  }
  digitalRead (6)=vt3;
}
}

nö musst nicht.

01 spiel beginnt
02 random Zeit warten
03 random LED einschalten und Zeitmessung starten
04 “warten” auf Tastendruck von der Testperson
05 wenn Taste gedrückt prüfen ob richtig, biepesen loben was auch immer
06 “warten” auf Rückstelltaste
07 bei Rückstellung weiter im loop und damit implizit wieder 01

Okay, und wie würde 'warten auf ...' als Code aussehen ?

(deleted)

banharsi06:
Muss ich dann alles in Setup reinschreiben und mit dem Taster dann mit if in loop oder wie ?

Nein.
setup() ist genau dafür da, für was es benannt ist.
Also initialisieren und Grundzustände herstellen.
Bestimmte Grundzustände brauchst auch im loop() - die kann man dann in Funktionen auslagern und "wiederverwenden".

Da das eine pädagogische Aufgabe ist, sei mir die Frage erlaubt, ob ihr PAP mit behandelt?

Nein, bei diesem Projekt nicht. Wir haben aber im Unterricht besprochen, wie man welche erstellt und worauf man achten muss.
Als Idee kommt mit für den Taster noch :
Eine for Schleife, die das Programm einmal ablaufen lässt und dann if Taster gedrückt starte Programm neu. Würde dies überhaupt gehen ?
Unseren Momentanen Sketch lade ich im Laufe des Tages noch hoch.

Grüße

banharsi06:
Okay, und wie würde ‘warten auf …’ als Code aussehen ?

Dazu gibt es doch if

Schau Dir doch die einfachen Beispiele aus der IDE an, da wird mit einem Taster eine LED eingeschaltete. Damit rennt der Arduino im Kreis herum und wartet dabei darauf das der Taster gedrückt wird.

Merke der Sketch wartet nicht auf etwas und macht dabei eine Pause, er rennt ständig weiter und und macht das was Du willlst wenn eine If Bedingung erfüllt ist.

Heinz

(deleted)

Hallo Peter, wir sind nun soweit gekommen :

int led1=3;
int led2=4;
int r=0;

int taster3= 6;
//Weiter
int vt3;
void setup() {
Serial.begin(9600);
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
pinMode (taster3,INPUT_PULLUP);

}

void loop() {
r=random (1,3);
Serial.println(r);
while (vt3=0){
if (r==1) {
digitalWrite(led1,HIGH);}
else{
digitalWrite(led1,LOW); }
if (r==2) {
digitalWrite(led2,HIGH);}
else{
digitalWrite(led2,LOW);
}
digitalRead (6)=vt3;
}
}

Leider meckert der Arduino bei digitalRead (6)=vt3; . Nun wissen wir momentan nicht weiter. Wir fragen uns im Moment, ob es nur einen kleinen Fehler ist oder ein größerer. Wenn der Fehler behoben wäre, würde dann das Programm 1mal ablaufen und dann erst wieder neustarten, wenn der Taster gedrückt ist ?

Grüße

banharsi06:
wir sind nun soweit gekommen :

Leider meckert der Arduino bei digitalRead (6)=vt3; . Nun wissen wir momentan nicht weiter.

ALSO!
Als erstes feheln Euch Grundlagen. Ganz viele. Vielleicht auch alle. Das kann und will ich nicht beurteilen.
Lektüre für heute Abend das pdf, was sich hier hinter versteckt:
https://www.arduinoforum.de/code-referenz
(deutsch und von jemandem geschrieben, der auch User ist)

und zwar:
digitalRead, random, randomseed

Dann zusätzlich suchen nach entprellen von Tastern.
Nachtwächterschaltung, BlinkwithoutDelay
(wirst es noch brauchen)

(deleted)

Danke für die Rückmeldung, wir haben die Programmierungen nochmal neu gestartet und haben es nun hinbekommen, die Taster einzubinden. Nun widmen wir uns dem Display. Werde die Tage berichten...
Grüße

Hallo,
wir sind nun zu 99% fertig mit dem Reaktionstester. Eine zufällige Led blinkt, man haut auf den jeweiligen Taster und die Zeit wird auf dem LCD Display angezeigt. Nun gibt es aber ein kleines Problem. Wenn die 2. Led blinkt und ich auf den Taster schlage kommt eine ganz komische Zahl auf dem Display , z.B. 11049ms. Mancmal auch hohe negative Zahlen. Die Zeit stimmt auch nicht, habe es manuell gemessen und hatte eine Zeit von max. 300 ms und nicht von 10000. Woran kann das liegen ?
Grüße

Sketch :

// Biblotheken \/
#include <LiquidCrystal_I2C.h>              
#include <Wire.h> 
LiquidCrystal_I2C lcd(0x27, 16, 2);    // Display wird definiert 

//Variablen \/
int r; //Zufallszahl
int step = 0; //Schrittnummer
int t; //Zeitmessung
int buttonValue1; //Knopf 1 Wert
int buttonValue2; //Knopf 2 Wert
int buttonValue3; //Knopf 3 Wert

//Pins \/
int led1 = 3;    // Es werden den Leds und den Tastern Namen gegeben, um nicht immer den Pin hinschreiben zu müssen und alles ist übersichtlicher 
int led2 = 4;
int taster1 = 11;         
int taster2 = 12;
int taster3 = 13;


void setup() {
pinMode(led1, OUTPUT);  // Es werden die Pins ( Ausgänge und Eingänge ) definiert, sodass der Arduino weiß, wo er z.B. 5V herausgeben muss. 
pinMode(led2, OUTPUT);
pinMode(taster1, INPUT_PULLUP);
pinMode(taster2, INPUT_PULLUP);
pinMode(taster3, INPUT_PULLUP);
lcd.clear();
lcd.init();
lcd.backlight();
Serial.begin(9600);
}

void loop() {
if (step == 0) {
  firstS();  //Erster Schritt
}
if (step == 1) {
  secondS(); //Zweiter Schritt
}
if (step == 2) {
  thirdS();  //Dritter Schritt
}
if (step == 3) {
  fourthS();  //Dritter Schritt
}  
}

void firstS() {                //ERSTER SCHRITT (Naechste Runde)
lcd.setCursor(1, 0);      // Setze den Cursor vom Display auf die 1. Zeile, ganz nach links 
lcd.print("Naechste Runde");  // Schreibe in die 1 Zeile "Naechste Runde"
lcd.setCursor(4, 1);      // Setze den Cursor vom Display auf die 2. Zeile, mittig 
lcd.print("druecken");    // Schreibe in die 2 Zeile "druecken"
Serial.print(buttonValue1);
buttonValue3 = digitalRead(taster3);    //Taster auslesen
if (buttonValue3 == 0) {
  step = 1; //Zum 2. Schritt
  lcd.clear();           // Display von den voherigen Texten leeren 
}
}

void secondS() {              //ZWEITER SCHRITT (Random Led geht an)
r = random(3, 5);          //Zufallszahl zwichen 3 und 4,  zwischen Rot/Grün
delay(random(500, 5000));  //Zufällige Zeit zwischen 500 und 4999 ms 
digitalWrite(r, HIGH);    //Die random Led einschalten 
t=0;
while (step == 1) {
  if (r == 3) {
    buttonValue2 = digitalRead(taster2);
    t = t + 1;          // Die Reaktionszeit des ersten Tasters und der ersten Led wird ausgerechnet
    if (buttonValue2 == 0) {
      step = 2;         //Zum 3. Schritt
    }
  } else if (r == 4) {
    buttonValue1 = digitalRead(taster1);
    Serial.println(buttonValue1);
    t = t + 1;       // Die Reaktionszeit des zweiten Tasters und der zweiten Led wird ausgerechnet
    if (buttonValue1 == 0) {
      step = 3;         //Zum 4. Schritt
    }
  }
}
}

void thirdS() {              //DRITTER SCHRITT (Zeitanzeige ROT)
digitalWrite(led1, LOW);
lcd.setCursor(1, 0);
lcd.print("Deine Zeit:");
lcd.setCursor(3, 1);         // Die oben ausgerechnete Zeit der ersten Led wird nun auf das Lcd Display geschrieben
lcd.print(t);
lcd.print("ms");
buttonValue3 = digitalRead(taster3);
if(buttonValue3 == 0) step = 0;
}

void fourthS() {              //DRITTER SCHRITT (Zeitanzeige GRÜN)
digitalWrite(led2, LOW);
lcd.setCursor(1, 0);
lcd.print("Deine Zeit:");
lcd.setCursor(3, 1);         // Die oben ausgerechnete Zeit der zweiten Led wird nun auf das Lcd Display geschrieben
lcd.print(t);
lcd.print("ms");
buttonValue3 = digitalRead(taster3);
if(buttonValue3 == 0) step = 0;
}

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Ich verstehe an dem Sketch nicht so ganz, wie ihr da die Zeit bestimmen wollt.
Zur Bestimmung der Reaktionszeit müsst ihr die millis() Funktion verwenden.
statt 'int t;' verwendet ihr eine Variable vom Typ unsigend long ( das ist das, was die millis Funktion zurückgibt) :

unsigned long rTime;

Da wo ihr t zu 0 setzt, merkt ihr euch die aktuelle Zeit:

rTime = millis();

Und erst wenn der Taster gedrückt wurde, berechnet ihr die Reaktionszeit ( das t= t+1 fällt weg):

rTime = millis()-rTime;

Und der Wert wird dann ausgegeben:

lcd.print(rTime);

(deleted)

Hallo Franz-Peter,
ich habe nun den Sketch so abgeändert, dass er mit millis funktioniert. Es werden mir zwar keine negativen Zahlen mehr angezeigt jedoch kommen jedes 3 mal Zahlen im 1000 Bereich, was ja nicht stimmt wenn ich den Taster direkt drücke.
Grüße

// Biblotheken \/
#include <LiquidCrystal_I2C.h>              
#include <Wire.h> 
LiquidCrystal_I2C lcd(0x27, 16, 2);    // Display wird definiert 

//Variablen \/
int r; //Zufallszahl
int step = 0; //Schrittnummer
unsigned long rTime; //Zeitmessung
int buttonValue1; //Knopf 1 Wert
int buttonValue2; //Knopf 2 Wert
int buttonValue3; //Knopf 3 Wert

//Pins \/
int led1 = 3;    // Es werden den Leds und den Tastern Namen gegeben, um nicht immer den Pin hinschreiben zu müssen und alles ist übersichtlicher 
int led2 = 4;
int taster1 = 11;         
int taster2 = 12;
int taster3 = 13;


void setup() {
  pinMode(led1, OUTPUT);  // Es werden die Pins ( Ausgänge und Eingänge ) definiert, sodass der Arduino weiß, wo er z.B. 5V herausgeben muss. 
  pinMode(led2, OUTPUT);
  pinMode(taster1, INPUT_PULLUP);
  pinMode(taster2, INPUT_PULLUP);
  pinMode(taster3, INPUT_PULLUP);
  lcd.clear();
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
}

void loop() {
  if (step == 0) {
    firstS();  //Erster Schritt
  }
  if (step == 1) {
    secondS(); //Zweiter Schritt
  }
  if (step == 2) {
    thirdS();  //Dritter Schritt
  }
  if (step == 3) {
    fourthS();  //Dritter Schritt
  }  
}

void firstS() {                //ERSTER SCHRITT (Naechste Runde)
  lcd.setCursor(1, 0);      // Setze den Cursor vom Display auf die 1. Zeile, ganz nach links 
  lcd.print("Naechste Runde");  // Schreibe in die 1 Zeile "Naechste Runde"
  lcd.setCursor(4, 1);      // Setze den Cursor vom Display auf die 2. Zeile, mittig 
  lcd.print("druecken");    // Schreibe in die 2 Zeile "druecken"
  Serial.print(buttonValue1);
  buttonValue3 = digitalRead(taster3);    //Taster auslesen
  if (buttonValue3 == 0) {
    step = 1; //Zum 2. Schritt
    lcd.clear();           // Display von den voherigen Texten leeren 
  }
}

void secondS() {              //ZWEITER SCHRITT (Random Led geht an)
  r = random(3, 5);          //Zufallszahl zwichen 3 und 4,  zwischen Rot/Grün
  delay(random(500, 5000));  //Zufällige Zeit zwischen 500 und 4999 ms 
  digitalWrite(r, HIGH);    //Die random Led einschalten 
  rTime = millis();
  while (step == 1) {
    if (r == 3) {
      buttonValue2 = digitalRead(taster2);
      rTime = millis()-rTime;       // Die Reaktionszeit des ersten Tasters und der ersten Led wird ausgerechnet
      if (buttonValue2 == 0) {
        step = 2;         //Zum 3. Schritt
      }
    } else if (r == 4) {
      buttonValue1 = digitalRead(taster1);
      Serial.println(buttonValue1);
      rTime = millis()-rTime;     // Die Reaktionszeit des zweiten Tasters und der zweiten Led wird ausgerechnet
      if (buttonValue1 == 0) {
        step = 3;         //Zum 4. Schritt
      }
    }
  }
}

void thirdS() {              //DRITTER SCHRITT (Zeitanzeige ROT)
digitalWrite(led1, LOW);
lcd.setCursor(1, 0);
lcd.print("Deine Zeit:");
lcd.setCursor(3, 1);         // Die oben ausgerechnete Zeit der ersten Led wird nun auf das Lcd Display geschrieben
lcd.print(rTime);
lcd.print("ms");
buttonValue3 = digitalRead(taster3);
if(buttonValue3 == 0) step = 0;
}

void fourthS() {              //DRITTER SCHRITT (Zeitanzeige GRÜN)
digitalWrite(led2, LOW);
lcd.setCursor(1, 0);
lcd.print("Deine Zeit:");
lcd.setCursor(3, 1);         // Die oben ausgerechnete Zeit der zweiten Led wird nun auf das Lcd Display geschrieben
lcd.print(rTime);
lcd.print("ms");
buttonValue3 = digitalRead(taster3);
if(buttonValue3 == 0) step = 0;
}

Du darfst die Reaktionszeit erst berechnen, wenn der Taster gedrückt wurde, nicht schon nach dem Abfragen des Tasters. Also erst, wenn Du zum 3. bzw. 4 Schritt gehst:

      buttonValue2 = digitalRead(taster2);
     if (buttonValue2 == 0) {
        step = 2;         //Zum 3. Schritt
        rTime = millis()-rTime;       // Die Reaktionszeit des ersten Tasters und der ersten Led wird ausgerechnet

Was soll ich sagen ??? :slight_smile: :slight_smile: :slight_smile: Vielen vielen Dank für die Hilfe ! Der Reaktionstester funktioniert 1a und ist hiermit fertig. Video dazu findet ihr bald auf YT : Simba 06.
Grüße und nochmals vielen Dank

P.S. habe viel dazugelernt und habe auch gelernt, bei Fehlern eine Lösung zu suchen und nicht gleich aufzugeben. :slight_smile:

Super! Danke für die Rückmeldung und viel Spaß weiterhin.

banharsi06:
P.S. habe viel dazugelernt und habe auch gelernt, bei Fehlern eine Lösung zu suchen und nicht gleich aufzugeben. :slight_smile:

Dann hat sich das Ganze doch auf jeden Fall gelohnt 8)