direkte Abfrage eines Tasters während delay?

Hallo.
Ich bin ziemlich neu in der Welt der Mikroprozessor. Als erstes richtiges Projekt habe ich mir vorgenommen ein Reaktionsspiel zu basteln, wie man es auch kennt.


Uploaded with ImageShack.us

Leuchtet eine LED soll eine Eingabe darauf erfolgen. Anfangs leuchten die LEDs noch lange auf, dann wird die Zeit immer geringer.

In der ersten Reihe sind die Schalter,
in der Reihe dahinter sind die Blink-LEDs
und in der letzten Reihe die Anzeige-LEDs für die Punkte. (1. LED = 10 Punkte, 2. LED = 20 Punkte, usw..)

Dies ganze Spiel soll nachher in einem Metallgehäuse verpackt werden..

Das mit dem Zufallsprinzip der Blink-LEDs ist kein Problem.

Jedoch stoße ich jetzt auf das Problem das der Arduino die LED leuchten lassen soll und währen die zufällige LED aufleuchtet schon die Abfrage gestartet werden soll.

Hat jemand eine Idee wie ich das realisieren könnte?

switch (ZUFALL){
  case 1 : 
  
  
  digitalWrite(BL1, HIGH);
  delay(ZEIT);  

  if (digitalRead(ROT1) == HIGH){
  PUNKTE = PUNKTE + 1;
  ZEIT = ZEIT - 30;
  }
}

Schau dir mal das Beispiel "BlinkWithoutDelay" an. Dort wird recht gut beschrieben, wie Zustände zeitlich abhängig gehalten werden, ohne die Programmausführung mittels Delay zu blockieren.

Hallo mmutantl

Während eines delay() wartet der Controller und macht nichts. Erst nach Ablauf der Zeit wird der folgende Code ausgeführt. Lösung des Problems ist die, die sth77 vorschlägt.
Auch pulsein() blockiert den Controller.

Grüße Uwe

Alle Hoch-Achtung vor deiner Bauwut @mmutantl !!!

Wie hast du ZUFALL vorher definiert ?

Du weißt aber schon das deine Maschine im End-Effekt nur die '42' ausgibt ? $)

MfG

ZUFALL habe ich wie folgt definiert:

void setup (void)
{
...
randomSeed(analogRead(0));
...
}

BL1...4 = BLINK LEDs, die LEDs die zufällig aufleuchten sollen
AL1...4 = Anzeige LEDs, die die Punkte darstellen sollen
ROT1...BLAU4 = Taster

void loop()     
{
  digitalWrite(ROT1, LOW);
  digitalWrite(GELB2, LOW);
  digitalWrite(GRUEN3, LOW);
  digitalWrite(BLAU4, LOW);

ZUFALL = random (1,5);
   
switch (ZUFALL){
  
  case 1 :
  
  unsigned long currentmillis = millis();
  if (currentmillis - previousmillis > interval){
  previousmillis = currentmillis;
  
  if (BL1state == LOW){
     tone (9,NOTE_C3,500);
     BL1state = HIGH;
  }
  else{
  BL1state = LOW;
  }
  
  digitalWrite (BL1, BL1state);
}
  }
  

if (PUNKTE == 10) {
  digitalWrite(AL1, HIGH);
}

} //ende programm

Die LEDs wurden bisher auch immer zufällig angesteuert, es kam zwar schon mal vor das eine LED 2-3 mal hintereinander geblinkt hat, jedoch ist da keine Folge erkennbar.

Das Problem was ich nun habe: wie im obigen Code habe ich die "Blink-without-delay"-Version reingeschrieben. Tasterabfrage lief auch super (jetzt nicht drin).
Nach 3-4 mal aufleuchten der LED geht das Programm in eine, ich nenn es mal "ungewollte Schleife" und die LED flackert die ganze Zeit... Ich habe aber keinen Schimmer weshalb es das jetzt macht :frowning:

Beitrag durch Moderator gelöscht.
Uwe Federer

mmutantl:
...
Das Problem was ich nun habe: wie im obigen Code habe ich die "Blink-without-delay"-Version reingeschrieben. Tasterabfrage lief auch super (jetzt nicht drin).
Nach 3-4 mal aufleuchten der LED geht das Programm in eine, ich nenn es mal "ungewollte Schleife" und die LED flackert die ganze Zeit... Ich habe aber keinen Schimmer weshalb es das jetzt macht :frowning:

Ohne Deinen Code ist es schwer Dir zuhelfen
Grüße Uwe

also den kompletten code?
kein problem :wink:

dieser code soll bisher nur led1(BL1) (rot) und led2 (BL2) (gelb) über die Taster "ROT1" und "GELB2" beinhalten... ich dachte mir das ich erstmal schritt für schritt aufbaue... was allerdings bisher schon nicht funktioniert :confused:
vorallem fehlt auch die abbruch-funktion, wenn ein falscher oder kein taster gedrückt wurde...

ich habe jetzt aber folgendes gefunden, das mir zeigt, das das was ich vorhabe auf jedenfall funktionieren muss: http://www.golf-4-cab.de/arduino/index.php?page=Thread&postID=26

morgen werde ich auf jedenfall mal aus diesem sketch einige ideen übernehmen und umsetzen, es ist in jedem fall plausibel :slight_smile:

  #include "pitches.h"

int BL1 = 0;
int BL1state = LOW;

int BL2 = 1;
int BL2state = LOW;

int BL3 = 2;
int BL3state = LOW;

int BL4 = 3;
int BL4state = LOW;

int AL1 = 5;
int AL2 = 6;
int AL3 = 7;
int AL4 = 8;

int LS = 9;

int ROT1 = 10;
int GELB2 = 11;
int GRUEN3 = 12;
int BLAU4 = 13;

int previousmillis = 0;
long interval = 1500;

int ZUFALL = 0; 
int ZEIT = 1500;
int PUNKTE = 1; 

//___________________
void setup (void)
{
  
  pinMode (BL1, OUTPUT);
  pinMode (BL2, OUTPUT);
  pinMode (BL3, OUTPUT);
  pinMode (BL4, OUTPUT);
  
  pinMode (AL1, OUTPUT);
  pinMode (AL2, OUTPUT);
  pinMode (AL3, OUTPUT);
  pinMode (AL4, OUTPUT);
  
  pinMode (ROT1, INPUT);
  pinMode (GELB2, INPUT);
  pinMode (GRUEN3, INPUT);
  pinMode (BLAU4, INPUT);
  
  randomSeed(analogRead(0));

}

//___________________

void loop()     
{
  
  digitalWrite(AL1, LOW);
  digitalWrite(AL2, LOW);
  digitalWrite(AL3, LOW);
  digitalWrite(AL4, LOW);
  
  digitalWrite(ROT1, LOW);
  digitalWrite(GELB2, LOW);
  digitalWrite(GRUEN3, LOW);
  digitalWrite(BLAU4, LOW);

ZUFALL = random (1,5);
unsigned long currentmillis = millis();   
   
switch (ZUFALL){
 
  case 1 :
    
  if (currentmillis - previousmillis > interval){
  previousmillis = currentmillis;
  
  if (BL1state == LOW){
     tone (9,NOTE_C3,500);
     BL1state = HIGH;
  }
  else{
  BL1state = LOW;
  }
  
  digitalWrite (BL1, BL1state);
  }
  if (digitalRead(ROT1) == HIGH){
    digitalWrite(ROT1, HIGH);
    interval = interval - 20;
    PUNKTE = PUNKTE + 1; 
  }
    digitalWrite(ROT1, LOW);

  case 2 :
  
  if (currentmillis - previousmillis > interval){
  previousmillis = currentmillis;
  
  if (BL2state == LOW){
     tone (9,NOTE_D3,500);
     BL2state = HIGH;
  }
  else{
  BL2state = LOW;
  }
  
  digitalWrite (BL2, BL1state);
  
  if (digitalRead(GELB2) == HIGH){
    digitalWrite(GELB2, HIGH);
    interval = interval - 20;
    PUNKTE = PUNKTE + 1; 
  }
    digitalWrite(GELB2, LOW);

}
  }
  

if (PUNKTE == 10) {
  digitalWrite(AL1, HIGH);
}
if (PUNKTE == 20) {
  digitalWrite(AL2, HIGH);
}
if (PUNKTE == 30) {
  digitalWrite(AL3, HIGH);
}
if (PUNKTE == 40) {
  digitalWrite(AL4, HIGH);
}


} //ende programm

Die Frage ist warum das überhaupt funktioniert.

Deine Hauptschleife enthält keine weiteren Schleifen, dafür aber das hier

ZUFALL = random (1,5);
unsigned long currentmillis = millis();   
   
switch (ZUFALL){

D.h. in jedem Durchlauf geht er in irgendeinen Zweig der Switch Anweisung. Das ist doch sicher so nicht gewollt, oder?

mittlerweile sieht es so aus. was mich schon einiges weiter gebracht hat.
allerdings muss ich den LEDs jetzt noch erklären das die nach einer bestimmten zeit (ZEIT--) auch direkt wieder ausgehen sollen und die Schleife nach dieser zeit weiterlaufen soll...

##include "pitches.h" // TOENE

//EIN UND AUSGAENGE FESTLEGEN
const int BL1 = 0;
const int BL2 = 1;
const int BL3 = 2;
const int BL4 = 3;

const int AL1 = 5;
const int AL2 = 6;
const int AL3 = 7;
const int AL4 = 8;

const int ROT1 = 10;
const int GELB2 = 11;
const int GRUEN3 = 12;
const int BLAU4 = 13;

//NOTENDAUER
int achtel = 1000/8;
int viertel = 1000/4;

// ARDUINO SETUP
void setup(){
   
    //BL = BLINK LED ZUFALL
  pinMode (BL1, OUTPUT);
  pinMode (BL2, OUTPUT);
  pinMode (BL3, OUTPUT);
  pinMode (BL4, OUTPUT);
   
    //AL = ANZEIGE LED PUNKTE
  pinMode (AL1, OUTPUT);
  pinMode (AL2, OUTPUT);
  pinMode (AL3, OUTPUT);
  pinMode (AL4, OUTPUT);
    
    //TASTER IN DEN FARBEN
  pinMode (ROT1, INPUT);
  pinMode (GELB2, INPUT);
  pinMode (GRUEN3, INPUT);
  pinMode (BLAU4, INPUT);
  
  randomSeed(analogRead(0)); //ZUFALLSZAHL GENERIEREN

// LAUFLICHT
digitalWrite(AL1, HIGH);
delay(110);
digitalWrite(AL1, LOW);
digitalWrite(AL2, HIGH);
delay(110);
digitalWrite(AL2, LOW);
digitalWrite(AL3, HIGH);
delay(110);
digitalWrite(AL3, LOW);
digitalWrite(AL4, HIGH);
delay(110);
digitalWrite(AL4, LOW);
digitalWrite(AL3, HIGH);
delay(110);
digitalWrite(AL3, LOW);
digitalWrite(AL2, HIGH);
delay(110);
digitalWrite(AL2, LOW);
digitalWrite(BL1, HIGH);
delay(110);
digitalWrite(BL1, LOW);
digitalWrite(BL1, HIGH);
delay(110);
digitalWrite(BL1, LOW);
digitalWrite(BL2, HIGH);
delay(110);
digitalWrite(BL2, LOW);
digitalWrite(BL3, HIGH);
delay(110);
digitalWrite(BL3, LOW);
digitalWrite(BL4, HIGH);
delay(110);
digitalWrite(BL4, LOW);
digitalWrite(BL3, HIGH);
delay(110);
digitalWrite(BL3, LOW);
digitalWrite(BL2, HIGH);
delay(110);
digitalWrite(BL2, LOW);
digitalWrite(BL1, HIGH);
delay(110);
digitalWrite(BL1, LOW);  
  
     delay(1500); //BEREITMACHEN UND START
 
}

// VAR INIT
int PUNKTE = 1;
int ZEIT;
int ZUFALL;

//TASTERZUSTAENDE AUF FALSE SETZEN
boolean ROT1STATE = false;
boolean GELB2STATE = false;
boolean GRUEN3STATE = false;
boolean BLAU4STATE = false;

// EIGENTLICHES PROGRAMM
void loop()
{

  ZUFALL = random(1, 5);                                //ZUFALLSZAHL ZUFALL
  if (ZUFALL == 1) {
    digitalWrite (BL1, HIGH);
    tone(9,NOTE_A3,500);
  }
    
  if (ZUFALL == 2){
    digitalWrite (BL2, HIGH);     
    tone(9,NOTE_B3,500);
  }
  
  if (ZUFALL == 3) {
    digitalWrite (BL3, HIGH);
    tone(9,NOTE_C3,500);
  }
  
  if (ZUFALL == 4) {
    digitalWrite (BL4, HIGH);  
    tone(9,NOTE_D3,500);
  }
  
  ZEIT = 1000;                          

  while (ZEIT > 0)                                    //SCHLEIFE WAEHREND LED LEUTCHTET 
  {
    buttonReader();                                         //TASTERSTELLUNGEN ABFRAGEN

    if (ZUFALL==1)                                      
    {
      if (ROT1STATE==true) {PUNKTE++; break;}             
      if (GELB2STATE==true) {FALSCH(); break;}         
      if (GRUEN3STATE==true) {FALSCH(); break;}        
      if (BLAU4STATE==true) {FALSCH(); break;}        
    }
    
        if (ZUFALL==2)                                      
    {
      if (ROT1STATE==true) {FALSCH(); break;}           
      if (GELB2STATE==true) {PUNKTE++; break;} 
      if (GRUEN3STATE==true) {FALSCH(); break;}        
      if (BLAU4STATE==true) {FALSCH(); break;}         
    }
   
        if (ZUFALL==3)                                      
    {
      if (ROT1STATE==true) {FALSCH(); break;}        
      if (GELB2STATE==true) {FALSCH(); break;}    
      if (GRUEN3STATE==true){PUNKTE++; break;}   
      if (BLAU4STATE==true) {FALSCH(); break;}      
    }
   
        if (ZUFALL==4)                                      
    {
      if (ROT1STATE==true) {FALSCH(); break;}         
      if (GELB2STATE==true) {FALSCH(); break;}         
      if (GRUEN3STATE==true) {FALSCH(); break;}        
      if (BLAU4STATE==true) {PUNKTE++; break;} 
    }
   
    
    delay(1);                                       

  }
   
  digitalWrite(BL1, LOW);                    
  digitalWrite(BL2, LOW); 
  digitalWrite(BL3, LOW); 
  digitalWrite(BL4, LOW); 
  delay(150);                                               //PRELLSCHUTZ
  
  //_________________________________________________________________________________________________________
  while (ZEIT > 1)                                     // WARTESCHLEIFE BIS LED WIEDER LEUCHTEN DARF
  {
    buttonReader();                                         //TASTERABFRAGE
    delay(1);
    ZEIT--;
  }

//_________________________________________________________________________________________________________
  
// SETZE EIN FÜR AL 1-4 (PUNKTE 10-40)
  if (PUNKTE == 10) {digitalWrite(AL1, HIGH);}   
  if (PUNKTE == 20) {digitalWrite(AL2, HIGH);}  
  if (PUNKTE == 30) {digitalWrite(AL3, HIGH);}  
  if (PUNKTE == 40) {digitalWrite(AL4, HIGH);}  
    
}
// ABBRUCH // FALSCHER TASTENDRUCK // FALSCHE TASTE
void FALSCH()
  {
    
tone(9, NOTE_C4, viertel); delay(viertel*1.30);
tone(9, NOTE_G3, achtel); delay(achtel*1.30);
tone(9, NOTE_G3, achtel); delay(achtel*1.30);
tone(9, NOTE_A3, viertel); delay(viertel*1.30);
tone(9, NOTE_G3, viertel); delay(viertel*1.30);
noTone(9); delay(viertel*1.30);
tone(9, NOTE_B3, viertel); delay(viertel*1.30);
tone(9, NOTE_C4, viertel);delay(viertel*1.30);

//LAUFLICHT
digitalWrite(AL1, HIGH); 
delay(200);
digitalWrite(AL1, LOW);
digitalWrite(AL2, HIGH);
delay(200);
digitalWrite(AL2, LOW);
digitalWrite(AL3, HIGH);
delay(200);
digitalWrite(AL3, LOW);
digitalWrite(AL4, HIGH);
delay(200);
digitalWrite(AL4, LOW);
digitalWrite(AL3, HIGH);
delay(200);
digitalWrite(AL3, LOW);
digitalWrite(AL2, HIGH);
delay(200);
digitalWrite(AL2, LOW);
digitalWrite(AL1, HIGH);
delay(200);
digitalWrite(AL4, LOW);

//RESET DRUECKEN BITTE.
digitalWrite(AL1, HIGH);
digitalWrite(AL4, HIGH);
delay(1500000); 


  }
  
// FUNKTION BUTTONREADER (AUSGABE STATUS TASTER)
void buttonReader()
  {
    ROT1STATE = digitalRead(ROT1);
    GELB2STATE = digitalRead(GELB2);
    GRUEN3STATE = digitalRead(GRUEN3);
    BLAU4STATE = digitalRead(BLAU4);
  }