Monday, February 13, 2017

Decisions with if-else-if

The if-else-if construct allows further conditional expressions to be evaluated than the if-else construct covered previously.
What this means is that we can add even more decision making capability to our Arduino sketches. A single variable can be checked to see if it contains any one of a number of different values and a decision can be made depending on which value the variable contains.

Using the if-else-if Construct

The if-else-if construct is shown below.

if (conditional expression 1) {
}
else if (conditional expression 2) {
}
As can be seen, the if-else-if construct allows a second conditional expression to be evaluated after the first if.
If the first conditional expression evaluates to true, then the code in the body of the if statement will be run and the code in the body of the else-if statement will not be run.
Only if the first conditional expression evaluates to false, will the second conditional expression be evaluated. If the second conditional expression evaluates to true, the the code in the block below the else-if statement will run. If the second conditional expression evaluates to false, program execution will continue below the closing brace of the body of the else-if statement.

if-else-if Example Sketch

The sketch below demonstrates the use of the if-else-if construct. If the character 'a' is sent from the serial monitor window, then the LED will blink at a certain rate. If the character 'b' is sent, the LED will blink at a faster rate.
void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

char rx_byte = 0;

void loop() {
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();
  }
  if (rx_byte == 'a') {
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
    delay(500);
  }
  else if (rx_byte == 'b') {
    digitalWrite(13, HIGH);
    delay(200);
    digitalWrite(13, LOW);
    delay(200);
  }
}
The video below shows the sketch running.
The first if statement gets a character from the serial port if one is available. The if-else-if construct follows this (shown below).
if (rx_byte == 'a') {
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  delay(500);
}
else if (rx_byte == 'b') {
  digitalWrite(13, HIGH);
  delay(200);
  digitalWrite(13, LOW);
  delay(200);
}

Deciding the Rate at which to Blink the LED

This code simply checks which character the rx_byte variable holds. If this variable contains 'a', then the code in the if block will run which will blink the LED with a 500ms delay. This switches the LED on for 500ms using the delay() function and then off for 500ms.
If the variable holds the value 'b', then the LED will be blinked at a faster rate by changing the on and off times of the LED to 200ms.

Stopping the LED from Blinking

If any character besides 'a' or 'b' is sent, then the LED will stop flashing because neither of the conditional expressions will evaluate to true.

When the Expression is Evaluated

Note that this code is in the main Arduino loop, so the conditional expression(s) will be evaluated each time through the loop. If a character is received that causes a conditional expression to be true, then this condition will be true each time through the loop until a new character is received. This is because the character is stored in the variable and does not change until it is overwritten by a new character.

The if-else-if-else Construct

In the same way that we could add an else statement below an if statement, we can add an else statement below the if-else-if construct as the sketch below shows.
This sketch works in the same way as the previous sketch, except that when any character except 'a' or 'b' is sent, the else block is run which flashes the LED even faster than the previous two blink rates
void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

char rx_byte = 0;

void loop() {
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();
  }
  if (rx_byte == 'a') {
    // the character 'a' was received, blink the LED once per second
    digitalWrite(13, HIGH);  // switch the LED on
    delay(500);              // leave the LED on for 500ms
    digitalWrite(13, LOW);   // switch the LED off
    delay(500);              // leave the LED off for 500ms
  }
  else if (rx_byte == 'b') {
    // the character 'b' was received, blink the LED every 400ms
    digitalWrite(13, HIGH);  // switch the LED on
    delay(200);              // leave the LED on for 200ms
    digitalWrite(13, LOW);   // switch the LED off
    delay(200);              // leave the LED off for 200ms
  }
  else {
    // any character except 'a' or 'b' was received
    digitalWrite(13, HIGH);  // switch the LED on
    delay(100);              // leave the LED on for 100ms
    digitalWrite(13, LOW);   // switch the LED off
    delay(100);              // leave the LED off for 100ms
  }
}
When the sketch starts running, the LED immediately blinks at the fastest rate by running the code in the else block. This is because the variable rx_byte is initialized to 0 which of course is not 'a' or 'b'.
If you want the sketch to blink the LED at the slowest rate when the sketch starts running, then initialize the variable to 'a' as shown here.
char rx_byte = 'a';

Evaluating More Conditional Expressions

Even more conditional expressions can be evaluated by adding more else if statements after the first if statement as shown here.
if (conditional expression 1) {
}
else if (conditional expression 2) {
}
else if (conditional expression 3) {
}
else if (conditional expression 4) {
}
etc. ...
To perform a task only if none of the the conditional expressions evaluate to true, an else condition can be added at the end as shown below.
if (conditional expression 1) {
}
else if (conditional expression 2) {
}
else if (conditional expression 3) {
}
else if (conditional expression 4) {
}
else {
}

No comments: