Hi folks. New guy here and in need of some explanation on switch case. In the example code provided for learners, the code seems to run the case and then skips out to do the default. Is this how it is supposed to work? How would I get the pin turned on by case 'a' ,for example, to stay on until 'b' is input. Right now case 'a' , (or b or c for that matter) only flashes on and then it's immediately shut off.
Many Thanks!
/*
Switch statement with serial input
Demonstrates the use of a switch statement. The switch
statement allows you to choose from among a set of discrete values
of a variable. It's like a series of if statements.
To see this sketch in action, open the Serial monitor and send any character.
The characters a, b, c, d, and e, will turn on LEDs. Any other character will turn
the LEDs off.
The circuit:
* 5 LEDs attached to digital pins 2 through 6 through 220-ohm resistors
created 1 Jul 2009
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/SwitchCase2
*/
void setup() {
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pins:
for (int thisPin = 9; thisPin < 12; thisPin++) {
pinMode(thisPin, OUTPUT);
}
}
void loop() {
// read the sensor:
if (Serial.available() > 0) {
int inByte = Serial.read();
// do something different depending on the character received.
// The switch statement expects single number values for each case;
// in this exmaple, though, you're using single quotes to tell
// the controller to get the ASCII value for the character. For
// example 'a' = 97, 'b' = 98, and so forth:
switch (inByte) {
case 'a':
digitalWrite(9, LOW);
break;
case 'b':
digitalWrite(10, LOW);
break;
case 'c':
digitalWrite(11, LOW);
break;
default:
// turn all the LEDs off:
for (int thisPin =9; thisPin < 12; thisPin++) {
digitalWrite(thisPin, HIGH);
}
}
}
}
The only difference is readability. At the end of the compilation they both produce the same code. It is easier for most folks to read a chain of case statements than it is to weed through all the if esle-if statements. But there is zero performance difference.
Delta_G:
The only difference is readability. At the end of the compilation they both produce the same code. It is easier for most folks to read a chain of case statements than it is to weed through all the if esle-if statements. But there is zero performance difference.
No the code implementation is different ( significantly switch uses ..jump tables if then else ... indirect pointer transfer ).. if the switch case resolves logically to a simple two stage process then generally the compiler will revert the code to reflect this, and generate if then else ... in this case obviously the switch case should not have neen used in the first place
A switch case compiled to a jump table is a far more efficient solution for a multiple values selection than the comparable if then else chain.
Just a bit of history for you ... Switch case was originaly proposed by Worth the designer of 'Pascal' but he mainrtained that all cases should be defined, so for a 16 bit unsigned integer you would have had a table with entries 0 to 65535 not very practical, solution other language development defined the 'default' sometimes refered to as the 'Otherwise clause' thus limiting the size of the jump table.
The switch case in C / C++ does have limtations on combinatorial based selection which ...if then else does not.
However equally the asbility to define
case n:
case n+1:
{...... break;}
i.e multiple selection using same code without the need for combinatorial equations which would the case in if then else chains..
Coding Badly had the correct answer to your problem. If you put in a Serial.println() in each of the case statements, you can see it strobe the default case unless you have "No line ending" set in the Serial monitor. One minor change:
int inByte = tolower(Serial.read());
and you don't have to worry about the person who runs their keyboard with the Caps Lock on.
Thanks! Setting the serial monitor to "No line ending" fixed the issue. Now it works like the examples on the YouTubes. No trouble in the code at all! Now to try the extra suggestions concerning capital letter input.
I am also interested in using the Switch Case, but in relation to time. Therefore, how can I use two different intervals, such as fast and slow when I am pressing the button?
For example, when I press the button quickly (0.5sec) the Red led will turn on, but if I press the button slowly (2 sec.) then the Green led will be on, etc.
Any ideas, if this can be implemented with the Switch case? It seems obvious, but
Any ideas, if this can be implemented with the Switch case?
Possibly, but why? There are only three states. The switch was pressed for less than 1/2 a second, the switch was pressed for 1/2 second or more but less than 2 seconds, or the switch was pressed for more than 2 seconds.
The switch statement is not designed to be used with ranges. The if statement is. Use the appropriate tool for the job.
KenF:
NO.
Default only runs if none of the other cases apply.
Nope, it will happily run if there is no break (or return() or other statement that changes the control flow) between the cases.
For real abuse of a case, check out duff's device
Duff himself said that "This code forms some sort of argument in that debate ["fall through" in a case], but I'm not sure whether it's for or against."
void loop() {
static unsigned long downAt;
if (Taste.update()) {
if (Taste.fell()) {
downAt = millis();
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
} else {
switch (millis() - downAt) {
case 500 ... 1999:
digitalWrite(redLedPin, HIGH);
break;
case 2000 ... 2999:
digitalWrite(greenLedPin, HIGH);
break;
}
}
}
}
Wandhal thank you for your input! It looks useful, however, I am wondering how to set the level of the fell() and rose()? For example, I am using a sensor, not a button anymore Values are in a respective window (eg. between 22k 30k) and I would like to follow the timing of the difference (e.g. if the input rises for 10% start counting time and do something after 0.5sec, of course if the value is above... etc). Hence I am thinking to have a custom settings for the low and high value of the fell, rose... and then start counting time!