How to auto jump from CASE 1 to CASE 2

Hi,

I need some help with my code. In my code the "default" case shows the battery level and lights up LED13. I have a push button for jumping from case 1 to case 2 and so on.
The thing I would like to happen is the default case to only stay on for 5 seconds, then the code automaticly jumps to case 1.

I could use delays for this, but that would not work with the push button (if the code is in the delay part, the button doesnt work).

Any ideas on how to put a delay and a jump in my default case, without using "delay"?

Thanks!

void loop() {


 buttonPoll = analogRead(button) > 500 ? 1 : 0;     //For using A7 as button input
  if(buttonPoll == 1){
    delay(30);                                      //For debounce 30ms should be enough
    unsigned long chrono = millis();
    while (buttonPoll == 1) 
 buttonPoll = analogRead(button) > 500 ? 1 : 0;
  if (millis()-chrono < 500) state = old + 1;       //Short press under 0.5 second
    else state = 0;                                 //Long press is over 0.5 second
  } 
    else {
    delay(50);
  }


long currentVoltage;
currentVoltage = readVcc();


//  ----- SWITCH CASE ------   

  switch (state) {
    
    case 1:    //NL
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(NL, HIGH);
  old = state;
      break;
      
    case 2:    //25%
  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(X1A, HIGH);
  old = state;
      break;
      
    case 3:    //100%
  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(X1A, HIGH);
  digitalWrite(X1B, HIGH);
  digitalWrite(X1C, HIGH);
  old = state;
      break;
      
    case 4:    //UV
  digitalWrite(NL,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(UV, HIGH);
  old = state;
      break;
      
    case 5:    //R
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(UV,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(RED, HIGH);
  old = state;
      break;
      
    case 6:    //G
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(GREEN, HIGH);
  old = state;
      break;
      
    case 7:    //B
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(NL,LOW);
  
  digitalWrite(BLUE, HIGH);
  old = state;
      break;

    default:   //
  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);

  digitalWrite(LED13, HIGH);

//  Batteridisplay

  //Serial.println( readVcc(), DEC );
  //delay(30);

  if ((currentVoltage > 3000) && (currentVoltage < 3250)) {
  digitalWrite(B20, HIGH);
  }
  else {
    digitalWrite(B20, LOW);
  }

  if ((currentVoltage > 3250) && (currentVoltage < 3500)) {
  digitalWrite(B40, HIGH);
  }
  else {
    digitalWrite(B40, LOW);
  }
  
  if ((currentVoltage > 3500) && (currentVoltage < 3750)) {
  digitalWrite(B60, HIGH);
  }
  else {
    digitalWrite(B60, LOW);
  }
  
  if ((currentVoltage > 3750) && (currentVoltage < 4000)) {
  digitalWrite(B80, HIGH);
  }
  else {
    digitalWrite(B80, LOW);
  }
  
  if (currentVoltage > 4000) {
  digitalWrite(B99, HIGH);
  }
  else {
    digitalWrite(B99, LOW);
  }

  

  old = 0;
      break;




  }
  delay(1);        // delay in between reads for stability

}

I think all you need to do is add a delay(5000) to the end of case 1 and remove the statement break; so that it automatically goes from the end of case 1 to the start of case 2.
between case 1 and case 2, like so:

switch (state) {

case 1: //NL
digitalWrite(UV,LOW);
digitalWrite(LED13,LOW);
digitalWrite(X1A,LOW);
digitalWrite(X1B,LOW);
digitalWrite(X1C,LOW);
digitalWrite(B20,LOW);
digitalWrite(B40,LOW);
digitalWrite(B60,LOW);
digitalWrite(B80,LOW);
digitalWrite(B99,LOW);
digitalWrite(RED,LOW);
digitalWrite(GREEN,LOW);
digitalWrite(BLUE,LOW);

digitalWrite(NL, HIGH);
old = state;

delay(5000);

case 2:

As for doing a 5 second delay without using delay(5000), i don't know..

Hi,
Look up "Blink without delay" example in the Arduino IDE Examples.

Using delay() will block your code and nothing will change.

Tom.... :slight_smile:

Save the value of millis() before you enter the case that needs to be maintained for 5 seconds. Using the default case is not a good choice for this.

Each time through loop() when in the timed case check whether the current value of millis() minus the case start time previously saved is greater than the required period. If not then do nothing but go round loop() again, perhaps reading inputs but do not prevent loop() running freely. Once the period has elapsed set the switch variable to the case that you want to move to.

TomGeorge:
Hi,
Look up "Blink without delay" example in the Arduino IDE Examples.

Using delay() will block your code and nothing will change.

Tom.... :slight_smile:

UKHeliBob:
Save the value of millis() before you enter the case that needs to be maintained for 5 seconds. Using the default case is not a good choice for this.

Each time through loop() when in the timed case check whether the current value of millis() minus the case start time previously saved is greater than the required period. If not then do nothing but go round loop() again, perhaps reading inputs but do not prevent loop() running freely. Once the period has elapsed set the switch variable to the case that you want to move to.

Thanks!

I see that using millis is a good way to go, but Im not quite shure on how to implement that in my code.
I have the millis part already used for the push button short and long press function. Can I still use millis for the case jump then?

You say that the default case is not a good choise for this? Could you describe why for me? Should I put all the "default stuff" in Case 1 insted (and move all the other cases to case x+1)? If so, I need a way to skip the default case

Can I still use millis for the case jump then?

Yes. The timing periods will of course be different but so will the start time variables but the current value of millis() will be common to both

You say that the default case is not a good choise for this? Could you describe why for me?

Because the default case is intended to catch invalid entries. As it stands your code enters the default case if none of the values of state are matched. That may well be OK but in my opinion (others may disagree) it would be better to have an explicit state for the code currently in default. One reason is that if the program is to run the code in your default case for a timed period then you need to save the value of millis() on entry to that state. In practice it is easier to save this before leaving the previous state.

An example may make it clearer

unsigned periodStartTime;
unsigned long currentTime;
unsigned long period;
byte state = 0; //initial state

void setup()
{
  Serial.begin(115200);
  period = 2000;  //initial period
  Serial.println("starting in state 0");
}
void loop()
{
  currentTime = millis();
  switch (state)
  {
    case 0:
      if (currentTime - periodStartTime >= period)
      {
        state = 1;
        periodStartTime = currentTime;
        period = 5000;
        Serial.println("switching to state 1");
      }
      break;
    case 1:
      if (currentTime - periodStartTime >= period)
      {
        state = 0;
        periodStartTime = currentTime;
        period = 2000;
        Serial.println("switching to state 0");
      }
      break;
  }
}

UKHeliBob:
Yes. The timing periods will of course be different but so will the start time variables but the current value of millis() will be common to both
Because the default case is intended to catch invalid entries. As it stands your code enters the default case if none of the values of state are matched. That may well be OK but in my opinion (others may disagree) it would be better to have an explicit state for the code currently in default. One reason is that if the program is to run the code in your default case for a timed period then you need to save the value of millis() on entry to that state. In practice it is easier to save this before leaving the previous state.

Okey, thanks!
So mabye a bit like this:

void loop() {


 buttonPoll = analogRead(button) > 500 ? 1 : 0;     //For using A7 as button input
  if(buttonPoll == 1){
    delay(30);                                      //For debounce 30ms should be enough
    unsigned long chrono = millis();
    while (buttonPoll == 1) 
 buttonPoll = analogRead(button) > 500 ? 1 : 0;
  if (millis()-chrono < 500) state = old + 1;       //Short press under 0.5 second
    else state = 0;                                 //Long press is over 0.5 second
  } 
    else {
    delay(50);
  }


long currentVoltage;
currentVoltage = readVcc();


//  ----- SWITCH CASE ------   


  switch (state) {


   case 0:    //"DEFAULT"

if (currentTime - periodStartTime >= period) {
        state = 1;
        periodStartTime = currentTime;
        period = 5000;
    }

  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);

  digitalWrite(LED13, HIGH);


//  Batterydisplay

  if ((currentVoltage > 3000) && (currentVoltage < 3250)) {
  digitalWrite(B20, HIGH);
  }
  else {
    digitalWrite(B20, LOW);
  }

  if ((currentVoltage > 3250) && (currentVoltage < 3500)) {
  digitalWrite(B40, HIGH);
  }
  else {
    digitalWrite(B40, LOW);
  }
  
  if ((currentVoltage > 3500) && (currentVoltage < 3750)) {
  digitalWrite(B60, HIGH);
  }
  else {
    digitalWrite(B60, LOW);
  }
  
  if ((currentVoltage > 3750) && (currentVoltage < 4000)) {
  digitalWrite(B80, HIGH);
  }
  else {
    digitalWrite(B80, LOW);
  }
  
  if (currentVoltage > 4000) {
  digitalWrite(B99, HIGH);
  }
  else {
    digitalWrite(B99, LOW);
  }


  old = state;
      break;

    
    case 1:    //NL
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(NL, HIGH);
  old = state;
      break;
      
    case 2:    //25%
  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(X1A, HIGH);
  old = state;
      break;
      

    case 3....
    case 4....
    and so on....
 

  delay(1);        // delay in between reads for stability

}

I would like to happen is the default case to only stay on for 5 seconds, then the code automaticly jumps to case 1.

As written periodStartTime is not declared but you know how to put that right I am sure.

When state is set to 0 you need to set periodStartTime to the current time in order to start the timing period. It is pointless doing it inside case 0, neither does period need to be set at that point unless you want to use more than one timing period

UKHeliBob:
As written periodStartTime is not declared but you know how to put that right I am sure.

When state is set to 0 you need to set periodStartTime to the current time in order to start the timing period. It is pointless doing it inside case 0, neither does period need to be set at that point unless you want to use more than one timing period

Okey, thanks.
I tried to fill this into my code. It kind of works, but first time I power on the circuit (or reset the board) the Case 0 stays on for about 3 seconds (not 5?), then after I jump from the last case (case 7 and back to start) the code skips Case 0 and goes to Case 1 insted. Only when I hold my button for more than 0.5 seconds (from any case) the code goes to Case 0, but only for mabye half a second...

Do you see any obvious mistakes in my code?

//    V01.Q119 Rev 03  Hodelykt
//    By H-M.B


const int UV = 7;
const int NL = 8;
const int X1A = 9;
const int X1B = 10;
const int X1C = 11;
const int LED13 = 13;
const int B20 = 6;
const int B40 = 5;
const int B60 = 4;
const int B80 = 3;
const int B99 = 2;
const int RED = A0;
const int GREEN = A1;
const int BLUE = A2;

const int button = A7;  //A7

int state = 0;
int old = 0;
int buttonPoll = 0;

//  1.1v Battery monitor START

long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}


//  1.1V Battery monitor END

//  Millis for case auto jump
unsigned periodStartTime;
unsigned long currentTime;
unsigned long period;
//  Millis for case auto jump

void setup() {

Serial.begin(9600);
period = 5000;  //Periode for Case 0 to stay on before jumping to Case 1

  pinMode(UV, OUTPUT);
  pinMode(NL, OUTPUT);
  pinMode(X1A, OUTPUT);
  pinMode(X1B, OUTPUT);
  pinMode(X1C, OUTPUT);
  pinMode(LED13, OUTPUT);
  pinMode(B20, OUTPUT);
  pinMode(B40, OUTPUT);
  pinMode(B60, OUTPUT);
  pinMode(B80, OUTPUT);
  pinMode(B99, OUTPUT);
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  
  pinMode(button, INPUT);

  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  digitalWrite(NL, LOW);
  
  
}

void loop() {


 currentTime = millis();                            //For case auto jump

 buttonPoll = analogRead(button) > 500 ? 1 : 0;     //For using A7 as button input
  if(buttonPoll == 1){
    delay(30);                                      //For debounce 30ms should be enough
    unsigned long chrono = millis();
    while (buttonPoll == 1) 
 buttonPoll = analogRead(button) > 500 ? 1 : 0;
  if (millis()-chrono < 500) state = old + 1;       //Short press under 0.5 second
    else state = 0;                                 //Long press is over 0.5 second
  } 
    else {
    delay(50);
  }


long currentVoltage;
currentVoltage = readVcc();


//  ----- SWITCH CASE ------   

  if (currentVoltage >= 3000) {
  
  switch (state) {


    case 0:    //LED13 with batteri indication. After 5 seconds, go to Case 1
  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);

  digitalWrite(LED13, HIGH);


//  Batterydisplay

  if ((currentVoltage > 3200) && (currentVoltage < 3250)) {
  digitalWrite(B20, HIGH);}
  else {
  digitalWrite(B20, LOW);}
  
  if ((currentVoltage > 3400) && (currentVoltage < 3500)) {
  digitalWrite(B40, HIGH);}
  else {
  digitalWrite(B40, LOW);}
  
  if ((currentVoltage > 3600) && (currentVoltage < 3750)) {
  digitalWrite(B60, HIGH);}
  else {
  digitalWrite(B60, LOW);}
  
  if ((currentVoltage > 3800) && (currentVoltage < 4000)) {
  digitalWrite(B80, HIGH);}
  else {
  digitalWrite(B80, LOW);}
  
  if (currentVoltage > 4000) {
  digitalWrite(B99, HIGH);}
  else {
  digitalWrite(B99, LOW);}


  if (currentTime - periodStartTime >= period) {
        state = 1;
        periodStartTime = currentTime;
        period = 5000;
    }


  old = state;
      break;
    
    case 1:    //LED13 without battery indication
  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(LED13, HIGH);
  old = state;
      break;

    
    case 2:    //NL
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(NL, HIGH);
  old = state;
      break;
      
    case 3:    //25%
  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(X1A, HIGH);
  old = state;
      break;
      
    case 4:    //100%
  digitalWrite(UV,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(X1A, HIGH);
  digitalWrite(X1B, HIGH);
  digitalWrite(X1C, HIGH);
  old = state;
      break;
      
    case 5:    //UV
  digitalWrite(NL,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(UV, HIGH);
  old = state;
      break;
      
    case 6:    //R
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(UV,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(RED, HIGH);
  old = state;
      break;
      
    case 7:    //G
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(NL,LOW);
  digitalWrite(BLUE,LOW);
  
  digitalWrite(GREEN, HIGH);
  old = state;
      break;
      
    case 8:    //B
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(NL,LOW);
  
  digitalWrite(BLUE, HIGH);
  old = 1;
      break;

  }   //Switch case
  
  }   //If voltage is over...

  
  else {        //For low battery, only use NL
  digitalWrite(NL, HIGH);
  
  digitalWrite(UV,LOW);
  digitalWrite(LED13,LOW);
  digitalWrite(X1A,LOW);
  digitalWrite(X1B,LOW);
  digitalWrite(X1C,LOW);
  digitalWrite(B20,LOW);
  digitalWrite(B40,LOW);
  digitalWrite(B60,LOW);
  digitalWrite(B80,LOW);
  digitalWrite(B99,LOW);
  digitalWrite(RED,LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(BLUE,LOW);

  //Add code that makes LED B20 to blink slowly for 10 seconds
  
  //old = 1;
  }
 
  delay(1);        // delay in between reads for stability

}

irst time I power on the circuit (or reset the board) the Case 0 stays on for about 3 seconds (not 5?),

If you want the timing to be more accurate you must get rid of the delay()s in your program

after I jump from the last case (case 7 and back to start) the code skips Case 0

Did you set periodStartTime to the current time before entering case 0 ?

UKHeliBob:
If you want the timing to be more accurate you must get rid of the delay()s in your program

Did you set periodStartTime to the current time before entering case 0 ?

Okey. I will take a look.

Just to ask, would it be better to drop the "case jump" part, and insted just stay in one case, but make the battery LEDs only stay on for the 5 seconds there?

Because all I really want is to show the batteri level for a short time. Now the LED13 and the battery LEDs all stay on until I go to the next case

Personally I would stick with switch/case even if it means having more cases, each one with the system in a particular state. If find that by doing that debugging becomes easier. I am also a fan of named states so that you can have code in the form

switch(state)
{
  case WAITING_5_SECONDS:
    //code here
    break;
  case WAITING_BUTTON_PRESS:
    //code here
    break;
  case BLINK_RED_LED_5_TIMES:
    //code here
    break;
  case BLINK_GREEN_LED:
    //code here
    break;
etc
etc
}
}

Having said that, whatever works for you is, of course, OK

Thanks again UKHeliBob.

I've been looking around and found this code part:

   int runXTimes = 0; 

void setup() {
}

void loop() {

  switch (state) {
  
  case 0:
 if (runXTimes < 1) {
    // MY BATTERY CODE HERE
    runXTimes = runXTimes + 1;
  }
    // THE REST OF THE CASE HERE
  break;

  case 1:
   int runXTimes = 0;  //After I go out of case 0, the counter goes back to 0
   // THE REST OF CASE 1
   break;

   case 2:
   ... and so on
}
}

If I go back to my original code, and then add this part to my first/defalut case, mabye that should do the trick? I will give it a go later today.. just curious what you think

Edit: I then still need the battery code to stay on for 5 seconds...
I could put in the millis code part somehow? :

  if (currentTime - periodStartTime >= period) {
        state = 1;
        periodStartTime = currentTime;
        period = 5000;
  case 0:
 if (runXTimes < 1) {
    // MY BATTERY CODE HERE
    runXTimes = runXTimes + 1;
  }
    // THE REST OF THE CASE HERE
  break;

As posted this will, of course, never leave the case but I assume that the case code will take care of that

  case 1:
   int runXTimes = 0;  //After I go out of case 0, the counter goes back to 0
   // THE REST OF CASE 1
   break;

This won't work because each time the case code is executed runXTimes will be reset to zero. You must set any variables needing an initial value in a state before you enter the state.

I suggest that you list each state that the program can be in, giving each a unique name, list which variables are used within each state and their initial values and the target state(s) from the current state and the conditions that need to be met in order to change to the new state.

I find I have to add a lot of states to something that is very easy to describe. Usually that is in the form of a "beginning" state in front of the real "action" state.

For example, pressing a button to start a long-running process has a "start command received" state.