Getting out of a cycle in a for loop

As already mentioned as long as you are inside the for-loop you are inside the for-loop and the lines of code

      for (int i = 8; i <= 12; i++) {
        digitalWrite(i, HIGH);
        delay(500);
      }
      for (int i = 12; i >= 8; i--) {
        digitalWrite(i, LOW);
        delay(500);
      }

etc.

You are asking for a functionality that requires pretty complex coding
The code postd below uses multiple things that all need their own time to learn

important:

button must be wired between IO-pin and GROUND

  • using arrays
  • using functions with and without parameters
  • using serial printing for debugging / observing / explaining what the code is doing
  • using flags
  • using non-blocking timing based on millis()
/*
  const byte led1 = 8;
  const byte led2 = 9;
  const byte led3 = 10;
  const byte led4 = 11;
  const byte led5 = 12;
*/

//           IO-pin-numbers 8  9  10  11  12
const byte myLEDs1to5[5] = {8, 9, 10, 11, 12};

const byte StartButton = A5;
boolean runMySequence = false;
boolean sequenceSwitchOn = true;

byte buttonState;
byte lastButtonState;
int  IndexNr = 0;

void setup() {
  Serial.begin(115200);
  Serial.println( F("Setup-Start") );

  for (byte IndexNr = 0; IndexNr < 5; IndexNr++) {
    explainArrayUse1(IndexNr);
    pinMode (myLEDs1to5[IndexNr], OUTPUT);
  }

  pinMode (StartButton, INPUT_PULLUP);
}


void loop() {
  buttonState = digitalRead(StartButton);

  // check if buttonstate has CHANGED
  if (lastButtonState != buttonState) {

    if (buttonState == LOW) {
      Serial.println( F("Button pressed starting sequence") );
      IndexNr = 0;
      runMySequence = true;
      //ELIMINATE BOUNCING
      delay(30);
      //wait to release the pushbutton
      while (!digitalRead (StartButton));
      delay(30);
    }
  }

  //algoritmmo principal
  if (runMySequence) {
      switchLedsOn();
  }

  lastButtonState = buttonState;
}



void explainArrayUse1(int myParameter) {

  int myArrayElementNr = myParameter;

  Serial.print( F("using array-element with IndexNr ") );
  Serial.print( myArrayElementNr );
  Serial.print( F(" which contains value ") );
  Serial.print( myLEDs1to5[myArrayElementNr] );
  Serial.println( F(" as OUTPUT") );
  Serial.print( F("") );
  Serial.print( F("pinMode(") );
  Serial.print( myLEDs1to5[myArrayElementNr] );
  Serial.println( F(", OUTPUT);") );
}


void explainArrayUse2(int myParameter) {

  int myArrayElementNr = myParameter;

  Serial.print( F("using array-element with IndexNr ") );
  Serial.print( myArrayElementNr );
  Serial.print( F(" which contains value ") );
  Serial.print( myLEDs1to5[myArrayElementNr] );
  Serial.println( F(" and switch IO-pin HIGH") );
  Serial.print( F("") );
  Serial.print( F("digitalWrite(") );
  Serial.print( myLEDs1to5[myArrayElementNr] );
  Serial.println( F(", HIGH);") );
}


void explainArrayUse3(int myParameter) {

  int myArrayElementNr = myParameter;

  Serial.print( F("using array-element with IndexNr ") );
  Serial.print( myArrayElementNr );
  Serial.print( F(" which contains value ") );
  Serial.print( myLEDs1to5[myArrayElementNr] );
  Serial.println( F(" and switch IO-pin LOW") );
  Serial.print( F("") );
  Serial.print( F("digitalWrite(") );
  Serial.print( myLEDs1to5[myArrayElementNr] );
  Serial.println( F(", LOW);") );
}


void switchLedsOn() {
  static unsigned long myTimer;

  // check if 500 milliseconds of time have passed by
  // if not do nothing
  if ( TimePeriodIsOver(myTimer, 500) ) {
    // when REALLY 500 milliseconds of time have passe by
    if (sequenceSwitchOn) {
      digitalWrite (myLEDs1to5[IndexNr], HIGH);
      explainArrayUse2(IndexNr);
      IndexNr++;

      if (IndexNr >= 5) {
        sequenceSwitchOn = false;
        IndexNr--;
      }
    }

    // if switching on LEDs 1,2,3,4,5 is done
    else {  // sequenceSwitchOn is false
      digitalWrite (myLEDs1to5[IndexNr], LOW);
      explainArrayUse3(IndexNr);
      IndexNr--;
      if (IndexNr <= -1) {
        runMySequence = false; // stop executing the sequence
        sequenceSwitchOn = true;
        Serial.println( F("sequence finished") );
        IndexNr = 0;
      }
    }
  }
}



void switchLedsOFF() {
  static unsigned long myTimer;

  // check if 500 milliseconds of time have passed by
  // if not do nothing
  if ( TimePeriodIsOver(myTimer, 500) ) {
    // when REALLY 500 milliseconds of time have passe by
    digitalWrite (myLEDs1to5[IndexNr], LOW);
    explainArrayUse3(IndexNr);
    IndexNr++;

    if (IndexNr >= 5) {
      runMySequence = false; // stop executing the sequence
      Serial.println( F("sequence finished") );
      IndexNr = 0;
    }
  }
}


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

understanding all this in detail requires learning different coding techniques
a tutorial about non-blocking timing that is used here

best regards Stefan

1 Like