if
constructs for making decisions
if
constructs allow the running program to respond to changes in data stored in the program. In a microcontroller application, the change could be a increase or decrease in a sensor reading, the state of a button press or voltage caused by rotation of a control knob, or it could simple be due to the passing of time. These and other changes in the environment are a source of stimulus that can trigger a response by the running program.. For example, if a sensor value exceeds a threshold, an LED may be turned on.
The notes on this page provide a brief overview of basic if
structures. More detailed notes are available.
Mike Likes Science has an if-else rap and a longer review video on if-else structures.
Table of contents
- Simple
if
construct - The
if
-else
construct - The
if
-else
-if
construct - The
if
-else
-if
-else
construct - Further Reading
Simple if
construct
The basic if
structure allows a single block of code to be executed when a logical expression is True
. The following diagram shows the syntax and flow chart for a basic if
structure. The test represents logical expression that results in a True
or False
value. The conditional execution block can be one or more lines of code that are evaluated only if the test expression is True
. Whether or not the test expression is True
, the program continues execution immediately after the closing brace, }
.
Example: Warning for a floating point error
In standard numerical computation, attempting to take the square root of a negative number causes an error. On an Arduino board, evaluating y = sqrt(x);
when causes a value of NaN
(not a number) to be store in x
. The following code snippet shows how an if
statement could be used to generate a warning message when x
becomes negative.
x = ... // some code to store a value in x
if ( x<0 ) {
Serial.println("WARNING: x is negative");
}
Blink when input is below a threshold
Suppose you wanted a warning indicator when a voltage level on your system fell below a threshold value. Perhaps the voltage was the output of a temperature sensor and the warning light was used to show that the system temperature was too cold. The following code snippet shows how an if
statement could be used to blink an LED when the reading is lower than a threshold. In this example, nothing happens when the reading is above the threshold.
threshold = ... // Set equal to a reasonable value
reading = analogRead(inputPin);
if ( reading < threshold ) {
digitalWrite(warningPin, HIGH);
delay(500);
digitalWrite(warningPin, LOW);
delay(500);
}
The if
-else
construct
The if-else
structure implements and either-or kind of decision. Each of two outcomes has its own block of code. If the test is true, code block 1 is executed. Otherwise, code block 2 is executed.
Compare the flow charts for the basic if
(above) and the if-else
construct below. The flow chart for the if-else
structure makes it clear that when conditional block 1 (if
-is-true block) is chosen, the code skips over conditional block 2 (the else
block).
Example: Warning for a floating point error – version 2
We expand on the previous example of warning about negative x
by adding and \texttt{else} block that allows the square root operation to proceed, and to supply a default value for the case when x
is negative.
x = ... // some code to store a value in x
if ( x<0 ) {
Serial.println("WARNING: x is negative");
y = 0.0;
} else {
y = sqrt(x);
}
Example: Turn on a warning light when input is below a threshold
In the preceding example of blinking an LED when an analog reading is below a threshold an LED blinks once when a voltage level falls below a threshold value. Instead of quickly blinking an LED, it may be more effective to leave a warning light on constantly as long as the voltage is too low. The following code snippet shows one way to implement that feature.
threshold = ...
reading = analogRead(inputPin);
if ( reading < threshold ) {
digitalWrite(warningPin, HIGH);
} else {
digitalWrite(warningPin, LOW);
}
The if
-else
-if
construct
A second if
can immediately follow an else statement. This gives two closely related structures: the if-else-if
and the if-else-if-else
. The difference is subtle, but important.
The if-else-if
structure creates two choices as depicted in the following image. Note that if both tests are False
, neither code block is executed. Compare this flowchart to the flowchart for the if-else
construct (above) to see the important difference.
The following example of a furnace control (a thermostat) shows how an if-else-if
structure could be used.
Example: Furnace control with an if-else-if
Consider the logical decision-making used to turn on a furnace. The thermostat has a lower temperature setting, say 18 C, that determines whether heat needs to be added. The thermostat also has an upper temperature setting, say 22 C, that determines whether the room temperature is warm enough that the furnace should turn off. Here is the logic for the thermostat expressed in words.
If the temperature is less than 18C, turn on the furnace.
If the temperature is greater than 22C, turn off the furnace.
Otherwise, do nothing.
Here an incomplete Arduino sketch and the corresponding flowchart for implementing the thermostat control with an if-else-if
structure.
float Tlow = 18.0;
float Thigh = 22.0;
void loop() {
// Read temperature; details elsewhere
float T = getTemperatureReading();
if ( T<Tlow ) {
// Turn the furnace on
digitalWrite(heaterCircuitControl, HIGH);
} else if ( T>Thigh ) {
// Turn the furnace off
digitalWrite(heaterCircuitControl, LOW);
}
}
The if
-else
-if
-else
construct
The if-else-if-else
structure adds an important default condition to the the if-else-if
structure. The default condition handles cases when none of the if
conditions are true.
Notice that in the preceding furnace example, no special action is taken when the temperature is between the limits of Tlow
and Thigh
. For the furnace example, that either-or choice is OK. However, in many (if not most) cases it is a good idea to also include an else block when if-else-if
is used. The following diagram shows the skeleton code and flow chart for an if-else-if-else
structure.
The following code extends the furnace control logic from by adding indicator lights to display the status of the furnace. In this case three states of the furnace are of interest: cooling on, heating on, and furnace off. The furnace off condition is the goldilocks case of the temperature being neither too hot or too cold.
float Tlow = 18.0;
float Thigh = 22.0;
void loop() {
float T = getTemperatureReading(); // Read temperature; details elsewhere
if ( T<Tlow ) {
digitalWrite(heaterCircuitControl, HIGH); // Turn the furnace on
digitalWrite(blueLED, HIGH) // Turn on the blue LED
digitalWrite(redLED, LOW) // Make sure the red LED is off
digitalWrite(greenLED, LOW) // Make sure the green LED is off
} else if ( T>Thigh ) {
digitalWrite(heaterCircuitControl, LOW); // Turn the furnace off
digitalWrite(redLED, HIGH) // Turn on the red LED
digitalWrite(blueLED, LOW) // Make sure the blue LED is off
digitalWrite(greenLED, LOW) // Make sure the green LED is off
} else {
digitalWrite(greenLED, HIGH) // Turn on the green LED
digitalWrite(redLED, LOW) // Make sure the red LED is off
digitalWrite(blueLED, LOW) // Make sure the blue LED is off
}
}
Further Reading
More detailed notes are available at this link.
Also check out the Mike Likes Science YouTube Channel. Mike has an if-else rap and a longer review video on if-else structures.