Hile, if schleifen und Multiplexing !

Hey leute,

ich will ein kleine Spiel bauen bei dem es um Reaktiongeschwindigkeit geht aber ich hab nun einen punkt erreicht an dem ich total stucked bin und nicht mehr weiter weiss :confused:

Um was geht es ?:

also ich habe insgesamt 8 LED's ( 4 Rote = R; 4 Grüne = G )
und einen Joystick.

( Jede LED hat ihren eignen Vorwiderstand )

Das Spielfeld von oben:

G

R

G R R G

R

G

Was ist das Ziel ?:

Wenn eine grüne LED leuchtet muss man schnell mit dem Joystick die dazugehörige rote zum leuchten bringen, also bevor die grüne halt wieder aus geht.

Und so geht das ganz immer weiter bin man es einmal nicht schaffen sollte rechtzeitig zu navigieren.

Was funktioniert bisher ?:

Ich kann mittlerweile alle roten LED's über den curser ansteuern.

Was funktioniert nicht ?:

Dieses Problem befasst sich ausschließlich mit dem äußeren ring, also den Grünen LED's!
Ich kann leider die grünen LED's nicht für eine bestimmte zeit in einer willkürlichen Reihenfolge aufleuchten lassen.

Da die delay() Funktion den Prozessor monopolisieren würde (und somit alles stillsteht bis das delay abgewartet ist) muss ich eine State Machine verwenden.

Hier mein Code: (dessen Ziel es ist die Grünen LED's random ein und aus zu schalten, es soll immer nur eine led leuchten.)

int UP_O = 8;
int RIGHT_O = 9;
int DOWN_O = 10;
int LEFT_O = 11;


int UP_O_STATE = LOW; 
int RIGHT_O_STATE = LOW;
int DOWN_O_STATE = LOW;
int LEFT_O_STATE = LOW;


unsigned long previousMillis_UP_O = 0;
unsigned long previousMillis_RIGHT_O = 0;
unsigned long previousMillis_DOWN_O = 0;
unsigned long previousMillis_LEFT_O = 0;


long OnTime = 300;
long OffTime = 300;


int counter = 100;
int count = 100;
int random_position = 1;



void setup() {
  
     pinMode(UP_O, OUTPUT);   
     pinMode(RIGHT_O, OUTPUT);
     pinMode(DOWN_O, OUTPUT);
     pinMode(LEFT_O, OUTPUT);

Serial.begin(9600);

}

void loop() {

  if(count == 0)
  {
   count = 1000;
   random_position = random(4); 
   return random_position;  
  }
  
    else
    {
     count = count -1; 
    }
 

  if (random_position == 0) 
  {
    int counter = 1000;
    
    while (counter > 0)
    {
     OUTSIDE_UP();   
     counter = counter -1; 
    }
  }

  else if (random_position == 1) 
  {
    int counter = 1000;
    
    while (counter > 0)
    {
    OUTSIDE_RIGHT(); 
    counter = counter -1;    
    }
  }
  
  else if (random_position == 2) 
  {
    int counter = 1000;
    while (counter > 0)
    {
     OUTSIDE_DOWN();
     counter = counter -1;   
    }
  }

  else if (random_position == 3) 
  {
    int counter = 1000;
    while (counter > 0)
    {
     OUTSIDE_LEFT();  
     counter = counter -1; 
    }
 }
 
}

void OUTSIDE_UP(){
  
  unsigned long currentMillis = millis();
 
 if((UP_O_STATE == HIGH) && (currentMillis - previousMillis_UP_O >= OnTime))
  {
    UP_O_STATE = LOW;  // Turn it off
    return UP_O_STATE;
    previousMillis_UP_O = currentMillis;  // Remember the time
    digitalWrite(UP_O, UP_O_STATE);  // Update the actual LED
  }
  else if ((UP_O_STATE == LOW) && (currentMillis - previousMillis_UP_O >= OffTime))
  {
    UP_O_STATE = HIGH;  // turn it on
    return UP_O_STATE;
    previousMillis_UP_O = currentMillis;   // Remember the time
    digitalWrite(UP_O, UP_O_STATE);   // Update the actual LED
  }
     
}


void OUTSIDE_RIGHT(){
  
  unsigned long currentMillis = millis();
 
 if((RIGHT_O_STATE == HIGH) && (currentMillis - previousMillis_RIGHT_O >= OnTime))
  {
    RIGHT_O_STATE = LOW;  // Turn it off
    previousMillis_RIGHT_O = currentMillis;  // Remember the time
    digitalWrite(RIGHT_O, RIGHT_O_STATE);  // Update the actual LED
  }
  else if ((RIGHT_O_STATE == LOW) && (currentMillis - previousMillis_RIGHT_O >= OffTime))
  {
    RIGHT_O_STATE = HIGH;  // turn it on
    previousMillis_RIGHT_O = currentMillis;   // Remember the time
    digitalWrite(RIGHT_O, RIGHT_O_STATE);   // Update the actual LED
  }
 
}

void OUTSIDE_DOWN(){
  
  unsigned long currentMillis = millis();
 
 if((DOWN_O_STATE == HIGH) && (currentMillis - previousMillis_DOWN_O >= OnTime))
  {
    DOWN_O_STATE = LOW;  // Turn it off
    previousMillis_DOWN_O = currentMillis;  // Remember the time
    digitalWrite(DOWN_O, DOWN_O_STATE);  // Update the actual LED
  }
  else if ((DOWN_O_STATE == LOW) && (currentMillis - previousMillis_DOWN_O >= OffTime))
  {
    DOWN_O_STATE = HIGH;  // turn it on
    previousMillis_DOWN_O = currentMillis;   // Remember the time
    digitalWrite(DOWN_O, DOWN_O_STATE);   // Update the actual LED
  }
 
}


void OUTSIDE_LEFT(){
  
  unsigned long currentMillis = millis();
 
 if((LEFT_O_STATE == HIGH) && (currentMillis - previousMillis_LEFT_O >= OnTime))
  {
    LEFT_O_STATE = LOW;  // Turn it off
    previousMillis_LEFT_O = currentMillis;  // Remember the time
    digitalWrite(LEFT_O, LEFT_O_STATE);  // Update the actual LED
  }
  else if ((LEFT_O_STATE == LOW) && (currentMillis - previousMillis_LEFT_O >= OffTime))
  {
    LEFT_O_STATE = HIGH;  // turn it on
    previousMillis_LEFT_O = currentMillis;   // Remember the time
    digitalWrite(LEFT_O, LEFT_O_STATE);   // Update the actual LED
  }
 
}

Dann gehe doch einfach einen Schritt zurück und schreibe einen Sketch, der eine der 4 grünen Led für eine bestimmte Zeit leuchten läßt.

Schritt 2: Eine zufällige LED leuchtet für eine Sekunde (Tipp: Array und random), millis hast Du ja schon gefunden
Schritt 3: Die Leuchtdauer wird zufällig in einem Bereich
Schritt 4: Die Zufälligkeit "zufälliger" machen (randomSeed)

Da immer nur 1 LED leuchtet, brauchst Du auch nur 1 Zeitsteuerung.

Gruß Tommy

Edit: Es gibt übrigens keine if-Schleifen, sondern Abfragen/Verzweigungen

Alles klar, dann geh ichs mal so an :slight_smile:

und wo wird der Joystick abgefragt?

uwefed:
und wo wird der Joystick abgefragt?

Das frage ich mich auch. Weit und breit nicht der Hauch eines digitalRead() oder wenigstens eines als Eingang konfigurierten Pins.

@OP: Was soll das?

Gruß

Gregor

Das klingt jetzt wahrscheinlich totaaal langweilig, aber trotzdem: Mach dir einen Programm-Ablauflpan. Lies vorher mal was das ist und wie man es verwendet, ist keine Hexerei.

Man setzt sich (ausser vlt. bei 5-Zeilern) nicht einfach hin und programmiert drauf los. Logische Probleme löst bzw. veranschaulicht man mit einem Programm-Ablaufplan.

Ausserdem schreibt man nicht 4 quasi identische Methoden, in denen dann die versch. Parameter fest verdrahtet sind. Man schreibt eine parametierbare Methode, die dann mit versch. Parametern aufgerufen wird. So muss man auch Korrekturen/Änderungen nur an einer Stelle machen und kann sich sicher sein, dass der Code nicht "auseinander läuft" ...

Der code der sich mit dem curser befasst ist in einem anderen sketch da dieser einwandfrei funktioniert ^^

Ich hab die Parts die zum Joystick gehören aus diesem sketch entfernt weil ich mich so besser mit meinem eigentlichen Problem befassen konnte.

Wenn du ein Problem mit 4 LED und random hast, dann beschreib doch nur das.
Und lass aus deinem Sketch auch alles weg, was nicht dazu gehört.
z.B. int UP_O = 8; ?

Es wird auf jeden Fall erstmal übersichtlicher. Für alle Beteiligten.