Question about Blink Program Using Switch Case

I am trying to learn about the switch function so I made a simple blink program:

const int ledPin =  2;      // the number of the LED pin


int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
long interval = 1000;  

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);      
}
void loop()
{
  unsigned long currentMillis = millis();
  unsigned long elapsed = currentMillis - previousMillis;  // elapsed is the time since the end of the last cycle
  
  switch (elapsed){
    case 0:                                        // at time = 0 the LED is turned on
    ledState = HIGH;
    digitalWrite(ledPin, ledState);
    break;
    case 1000:                                     // at time = 1000 the LED is turned off
    ledState = LOW;
    digitalWrite(ledPin, ledState);
    break;
    case 2000:                                    // at time = 2000 the cycle starts over again
    previousMillis = currentMillis;
    break;
  }
  }

I would like to alter this code so that instead of it turning on when the time is 0 and turning off when the time is 1000 it will turn on at 0 then turn off at the time stored in the variable 'interval' then reset at '2*interval'. Does anyone know how I can best modify this code?

Does anyone know a reason not to use switch instead of if statements like were used in the blink without delay example? I am assuming this program will run at similar speeds and thought it might be a little easier to use in a program I am planning which will have dozens of state changes based on elapsed time.

How short a time period is this likely to work for? if I do case changes every 1ms is it likely to accurately reproduce the blink pattern? what about 0.1 ms?

That’s not a good use of “switch” - what if you happen to miss a tick?

Switch statements require an exact match and act like the ‘==’ operator. They are good if you can guarantee (or conspire to create) this situation.

In your case, you probably want to trigger if the time is >2000, as it is highly unlikelythat the millis() value will exactly be 2000 unless you are lucky.

Also, you cannot create complex boolean statements in the switch statement, so ‘if’ will live for a long time …

If that is the case, I am a bit surprised that the program I made worked at all. It did seem to be blinking the LED as expected though. It probably is that the program is simple enough and slow enough it never misses a tick. I will try inserting this into a complex program to see if I can break it.

One more question. I notice that the switch case example http://arduino.cc/en/Tutorial/SwitchCase is using an analog input then mapping it to one of four cases. So in that program they similarly face a situation where the variable might not be exactly one particular value, but instead could be a range of values. Could I improve this program by doing similar and mapping all values between 0 and 1000 to case 1, then all values from 1000 to 2000 to case 2?

Could I improve this program by doing similar and mapping all values between 0 and 1000 to case 1, then all values from 1000 to 2000 to case 2?

Yes.

And a 16 MHz Arduino is pretty fast. An empty ( just counting ) loop takes about 5 µs ( ~200 rounds per millisecond )

Thanks.I tried to make that change. This code seems to be producing the same output as the previous code but hopefully in a more robust way since I use the map function instead of millis directly.

const int ledPin =  2;      // the number of the LED pin


int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
long interval = 1000;  

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);      
}
void loop()
{
  unsigned long currentMillis = millis();
  unsigned long elapsed = currentMillis - previousMillis;  // elapsed is the time since the end of the last cycle
  int mapped =map(elapsed, 0, 2*interval, 1, 3);
  
  switch (mapped){
    case 1:                                        // at time = 0 the LED is turned on
    ledState = HIGH;
    digitalWrite(ledPin, ledState);
    break;
    case 2:                                     // at time = 1000 the LED is turned off
    ledState = LOW;
    digitalWrite(ledPin, ledState);
    break;
    case 3:                                    // at time = 2000 the cycle starts over again
    previousMillis = currentMillis;
    break;
  }
  }