# Arduino Language Learning: Switch-Case Statements
## **🎯 What is a Switch-Case Statement?**
A **Switch-Case** statement is a control structure that allows you to execute different blocks of code based on the value of a variable. Think of it like a smart traffic controller that directs different cars to different lanes based on their destination.
### **🚦 Simple Analogy**
Think of switch-case like a menu at a restaurant:
- **Customer orders "Pizza"** → Kitchen makes pizza
- **Customer orders "Burger"** → Kitchen makes burger
- **Customer orders "Salad"** → Kitchen makes salad
- **Customer orders something else** → Kitchen makes default dish
### **📝 Basic Concept**
Switch-case helps you:
- **Replace multiple if-else statements** with cleaner code
- **Handle multiple conditions** efficiently
- **Make code more readable** and organized
- **Execute different actions** based on a single value
## **🔧 Basic Switch-Case Syntax**
### **Simple Switch-Case Structure**
```cpp
switch (variable) {
case value1:
// Code to execute when variable equals value1
break;
case value2:
// Code to execute when variable equals value2
break;
default:
// Code to execute when variable doesn't match any case
break;
}
```
### **Complete Example**
```cpp
int day = 3;
switch (day) {
case 1:
Serial.println("Monday");
break;
case 2:
Serial.println("Tuesday");
break;
case 3:
Serial.println("Wednesday");
break;
default:
Serial.println("Other day");
break;
}
```
## **📊 How Switch-Case Works**
### **Step-by-Step Process**
1. **Evaluate the expression** in the switch statement
2. **Compare the result** with each case value
3. **Execute the matching case** (and all cases below it unless break is used)
4. **Execute default** if no case matches
### **Important Rules**
- **Break statement**: Stops execution and exits switch
- **Without break**: Execution continues to next case (fall-through)
- **Default case**: Executes when no other case matches
- **Case values**: Must be constants (numbers, characters, enums)
## **💡 Basic Switch-Case Examples**
### **Example 1: Simple Number Matching**
```cpp
int number = 5;
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case Number Example");
}
void loop() {
switch (number) {
case 1:
Serial.println("Number is 1");
break;
case 2:
Serial.println("Number is 2");
break;
case 3:
Serial.println("Number is 3");
break;
case 4:
Serial.println("Number is 4");
break;
case 5:
Serial.println("Number is 5");
break;
default:
Serial.println("Number is something else");
break;
}
delay(2000);
}
```
### **Example 2: Character Matching**
```cpp
char grade = 'B';
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case Character Example");
}
void loop() {
switch (grade) {
case 'A':
Serial.println("Excellent!");
break;
case 'B':
Serial.println("Good job!");
break;
case 'C':
Serial.println("Average");
break;
case 'D':
Serial.println("Needs improvement");
break;
case 'F':
Serial.println("Failed");
break;
default:
Serial.println("Invalid grade");
break;
}
delay(2000);
}
```
### **Example 3: Menu System**
```cpp
int menuChoice = 2;
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case Menu Example");
}
void loop() {
Serial.println("=== MENU ===");
Serial.println("1. Start");
Serial.println("2. Settings");
Serial.println("3. Help");
Serial.println("4. Exit");
Serial.print("Current choice: ");
Serial.println(menuChoice);
switch (menuChoice) {
case 1:
Serial.println("Starting application...");
break;
case 2:
Serial.println("Opening settings...");
break;
case 3:
Serial.println("Showing help...");
break;
case 4:
Serial.println("Exiting...");
break;
default:
Serial.println("Invalid menu choice");
break;
}
delay(3000);
}
```
## **🎮 Advanced Switch-Case Examples**
### **Example 1: State Machine**
```cpp
enum State {
IDLE,
RUNNING,
PAUSED,
STOPPED
};
State currentState = IDLE;
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case State Machine");
}
void loop() {
switch (currentState) {
case IDLE:
Serial.println("State: IDLE - Waiting for command");
currentState = RUNNING;
break;
case RUNNING:
Serial.println("State: RUNNING - Processing data");
currentState = PAUSED;
break;
case PAUSED:
Serial.println("State: PAUSED - Temporarily stopped");
currentState = STOPPED;
break;
case STOPPED:
Serial.println("State: STOPPED - Process completed");
currentState = IDLE;
break;
default:
Serial.println("State: UNKNOWN - Error state");
currentState = IDLE;
break;
}
delay(2000);
}
```
### **Example 2: Calculator**
```cpp
enum Operation {
ADD,
SUBTRACT,
MULTIPLY,
DIVIDE
};
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case Calculator");
int a = 10;
int b = 5;
Operation op = MULTIPLY;
Serial.print(a);
switch (op) {
case ADD:
Serial.print(" + ");
Serial.print(b);
Serial.print(" = ");
Serial.println(a + b);
break;
case SUBTRACT:
Serial.print(" - ");
Serial.print(b);
Serial.print(" = ");
Serial.println(a - b);
break;
case MULTIPLY:
Serial.print(" * ");
Serial.print(b);
Serial.print(" = ");
Serial.println(a * b);
break;
case DIVIDE:
Serial.print(" / ");
Serial.print(b);
Serial.print(" = ");
Serial.println(a / b);
break;
default:
Serial.println("Unknown operation");
break;
}
}
void loop() {
// Empty loop
}
```
### **Example 3: Error Code Handler**
```cpp
enum ErrorCode {
SUCCESS = 0,
INVALID_INPUT = 100,
NETWORK_ERROR = 200,
TIMEOUT_ERROR = 300,
MEMORY_ERROR = 400
};
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case Error Handler");
ErrorCode error = NETWORK_ERROR;
handleError(error);
}
void loop() {
// Empty loop
}
void handleError(ErrorCode error) {
switch (error) {
case SUCCESS:
Serial.println("Operation completed successfully");
break;
case INVALID_INPUT:
Serial.println("Error: Invalid input provided");
Serial.println("Action: Please check your input data");
break;
case NETWORK_ERROR:
Serial.println("Error: Network connection failed");
Serial.println("Action: Check your internet connection");
break;
case TIMEOUT_ERROR:
Serial.println("Error: Operation timed out");
Serial.println("Action: Try again later");
break;
case MEMORY_ERROR:
Serial.println("Error: Insufficient memory");
Serial.println("Action: Free up some memory");
break;
default:
Serial.println("Error: Unknown error occurred");
Serial.println("Action: Contact support");
break;
}
}
```
## **🔧 Switch-Case with Functions**
### **Example 1: Function with Switch-Case**
```cpp
enum Direction {
NORTH,
EAST,
SOUTH,
WEST
};
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case with Functions");
Direction dir = EAST;
moveInDirection(dir);
}
void loop() {
// Empty loop
}
void moveInDirection(Direction direction) {
switch (direction) {
case NORTH:
Serial.println("Moving NORTH");
Serial.println("Action: Go forward");
break;
case EAST:
Serial.println("Moving EAST");
Serial.println("Action: Turn right and go forward");
break;
case SOUTH:
Serial.println("Moving SOUTH");
Serial.println("Action: Turn around and go forward");
break;
case WEST:
Serial.println("Moving WEST");
Serial.println("Action: Turn left and go forward");
break;
default:
Serial.println("Invalid direction");
break;
}
}
```
### **Example 2: Switch-Case Returning Values**
```cpp
enum Season {
SPRING,
SUMMER,
AUTUMN,
WINTER
};
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case Returning Values");
Season currentSeason = SUMMER;
String seasonInfo = getSeasonInfo(currentSeason);
Serial.println(seasonInfo);
}
void loop() {
// Empty loop
}
String getSeasonInfo(Season season) {
switch (season) {
case SPRING:
return "Spring: Flowers bloom, temperature rises";
case SUMMER:
return "Summer: Hot weather, long days";
case AUTUMN:
return "Autumn: Leaves fall, temperature drops";
case WINTER:
return "Winter: Cold weather, short days";
default:
return "Unknown season";
}
}
```
## **📊 Switch-Case with Arrays and Loops**
### **Example 1: Processing Array Elements**
```cpp
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case with Arrays");
int numbers[] = {1, 3, 5, 2, 4};
int size = 5;
for (int i = 0; i < size; i++) {
Serial.print("Processing number ");
Serial.print(numbers[i]);
Serial.print(": ");
switch (numbers[i]) {
case 1:
Serial.println("One");
break;
case 2:
Serial.println("Two");
break;
case 3:
Serial.println("Three");
break;
case 4:
Serial.println("Four");
break;
case 5:
Serial.println("Five");
break;
default:
Serial.println("Other number");
break;
}
}
}
void loop() {
// Empty loop
}
```
### **Example 2: Switch-Case in Loop with Counter**
```cpp
int counter = 0;
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case in Loop");
}
void loop() {
int cycle = counter % 4; // Cycles through 0, 1, 2, 3
switch (cycle) {
case 0:
Serial.println("Cycle 0: Initialization");
break;
case 1:
Serial.println("Cycle 1: Processing");
break;
case 2:
Serial.println("Cycle 2: Verification");
break;
case 3:
Serial.println("Cycle 3: Completion");
break;
default:
Serial.println("Unexpected cycle");
break;
}
counter++;
delay(1000);
}
```
## **⚠️ Common Mistakes and Tips**
### **Mistake 1: Missing Break Statements**
```cpp
// Wrong - missing break statements
switch (value) {
case 1:
Serial.println("One");
// Missing break!
case 2:
Serial.println("Two");
break;
}
// Result: When value is 1, both "One" and "Two" are printed
// Correct - with break statements
switch (value) {
case 1:
Serial.println("One");
break;
case 2:
Serial.println("Two");
break;
}
```
### **Mistake 2: Using Variables in Case Values**
```cpp
// Wrong - variables in case values
int x = 5;
switch (value) {
case x: // Error! Case values must be constants
Serial.println("Five");
break;
}
// Correct - use constants
switch (value) {
case 5:
Serial.println("Five");
break;
}
```
### **Mistake 3: Forgetting Default Case**
```cpp
// Wrong - no default case
switch (value) {
case 1:
Serial.println("One");
break;
case 2:
Serial.println("Two");
break;
// What happens if value is 3, 4, 5, etc.?
}
// Better - with default case
switch (value) {
case 1:
Serial.println("One");
break;
case 2:
Serial.println("Two");
break;
default:
Serial.println("Other value");
break;
}
```
### **Mistake 4: Complex Expressions in Switch**
```cpp
// Wrong - complex expression
switch (a + b * c) { // Avoid complex expressions
case 10:
Serial.println("Result is 10");
break;
}
// Better - simplify the expression
int result = a + b * c;
switch (result) {
case 10:
Serial.println("Result is 10");
break;
}
```
## **🎯 Best Practices**
### **1. Always Use Break Statements**
```cpp
// Good - explicit break statements
switch (value) {
case 1:
Serial.println("One");
break;
case 2:
Serial.println("Two");
break;
default:
Serial.println("Other");
break;
}
// Only omit break when you want fall-through behavior
switch (value) {
case 1:
case 2:
case 3:
Serial.println("Small number");
break;
case 4:
case 5:
case 6:
Serial.println("Medium number");
break;
}
```
### **2. Use Default Case**
```cpp
// Good - always include default
switch (value) {
case 1:
Serial.println("One");
break;
case 2:
Serial.println("Two");
break;
default:
Serial.println("Unexpected value");
break;
}
```
### **3. Keep Cases Simple**
```cpp
// Good - simple case logic
switch (value) {
case 1:
Serial.println("One");
break;
case 2:
Serial.println("Two");
break;
}
// Avoid - complex logic in cases
switch (value) {
case 1:
// 50 lines of complex logic
break;
case 2:
// Another 50 lines
break;
}
```
### **4. Use Enums for Better Readability**
```cpp
// Good - using enums
enum Color { RED, GREEN, BLUE };
Color color = GREEN;
switch (color) {
case RED:
Serial.println("Red color");
break;
case GREEN:
Serial.println("Green color");
break;
case BLUE:
Serial.println("Blue color");
break;
}
// Avoid - using magic numbers
int color = 1;
switch (color) {
case 0: Serial.println("Red color"); break;
case 1: Serial.println("Green color"); break;
case 2: Serial.println("Blue color"); break;
}
```
## **🚀 Advanced Switch-Case Techniques**
### **Example 1: Nested Switch-Case**
```cpp
enum Category {
ANIMAL,
VEGETABLE,
MINERAL
};
enum Animal {
DOG,
CAT,
BIRD
};
void setup() {
Serial.begin(9600);
Serial.println("Nested Switch-Case");
Category category = ANIMAL;
int subType = 1; // CAT
switch (category) {
case ANIMAL:
Serial.println("Category: Animal");
switch (subType) {
case 0:
Serial.println("Subtype: Dog");
break;
case 1:
Serial.println("Subtype: Cat");
break;
case 2:
Serial.println("Subtype: Bird");
break;
default:
Serial.println("Unknown animal");
break;
}
break;
case VEGETABLE:
Serial.println("Category: Vegetable");
// Handle vegetable subtypes
break;
case MINERAL:
Serial.println("Category: Mineral");
// Handle mineral subtypes
break;
default:
Serial.println("Unknown category");
break;
}
}
void loop() {
// Empty loop
}
```
### **Example 2: Switch-Case with Range Checking**
```cpp
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case with Range Checking");
int score = 85;
processScore(score);
}
void loop() {
// Empty loop
}
void processScore(int score) {
// Convert score to range
int range = score / 10;
switch (range) {
case 10:
case 9:
Serial.println("Grade: A (Excellent)");
break;
case 8:
Serial.println("Grade: B (Good)");
break;
case 7:
Serial.println("Grade: C (Average)");
break;
case 6:
Serial.println("Grade: D (Below Average)");
break;
default:
Serial.println("Grade: F (Failed)");
break;
}
}
```
### **Example 3: Switch-Case with Multiple Variables**
```cpp
enum Mode {
NORMAL,
FAST,
SLOW
};
enum Direction {
FORWARD,
BACKWARD,
LEFT,
RIGHT
};
void setup() {
Serial.begin(9600);
Serial.println("Switch-Case with Multiple Variables");
Mode mode = FAST;
Direction direction = FORWARD;
processMovement(mode, direction);
}
void loop() {
// Empty loop
}
void processMovement(Mode mode, Direction direction) {
// Combine mode and direction into a single value
int action = mode * 4 + direction;
switch (action) {
case 0: // NORMAL + FORWARD
Serial.println("Moving forward at normal speed");
break;
case 1: // NORMAL + BACKWARD
Serial.println("Moving backward at normal speed");
break;
case 4: // FAST + FORWARD
Serial.println("Moving forward at fast speed");
break;
case 5: // FAST + BACKWARD
Serial.println("Moving backward at fast speed");
break;
case 8: // SLOW + FORWARD
Serial.println("Moving forward at slow speed");
break;
case 9: // SLOW + BACKWARD
Serial.println("Moving backward at slow speed");
break;
default:
Serial.println("Unknown movement combination");
break;
}
}
```
## **📚 Summary**
### **Key Points:**
1. **Switch-case** executes different code based on a variable's value
2. **Break statements** prevent fall-through to next case
3. **Default case** handles unmatched values
4. **Case values** must be constants
5. **Switch-case** is more efficient than multiple if-else statements
### **When to Use Switch-Case:**
- **Multiple conditions** based on a single variable
- **Menu systems** and user interfaces
- **State machines** and game logic
- **Error handling** with error codes
- **Replacing long if-else chains**
### **Benefits:**
- **More readable** than multiple if-else statements
- **More efficient** execution
- **Better organization** of related code
- **Easier to maintain** and modify
- **Clearer logic flow**
### **Next Steps:**
- **Practice**: Create switch-case statements for your projects
- **Experiment**: Combine with enums and functions
- **Combine**: Use with loops and arrays
- **Explore**: Learn about nested switch-case and advanced techniques
**Switch-case statements are a powerful way to handle multiple conditions efficiently. Use them to make your Arduino code cleaner and more organized!** 🚀🔀✨
TinkerBlock UNO R3 Starter Kit
Dive into the world of electronics, Arduino programming, and STEM projects with the Lonely Binary TinkerBlock Series Starter Kit.
- Choosing a selection results in a full page refresh.