Logical Operators

Created on: 26 November 2014
Updated on: 14 February 2017

Part 12 of the Arduino Programming Course

Logical operators can be used with if and if-else to simplify and extend decision making.

The three logical operators are OR (||), AND (&&) and NOT (!) which are explained and demonstrated in this part of the course.

The OR Logical Operator (||)

The OR logical operator is written in sketches as two vertical pipe symbols (||) found on the same key as the backslash (\) on USA and other keyboards. Pressing Shift + \ (Shift and back slash keys) will type the vertical pipe character.

The following sketch demonstrates the use of the OR logical operator to check for the upper and lower-case versions of an alphabet character.

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

void loop() {
  char rx_byte;
  
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();
    if (rx_byte == 'a' || rx_byte == 'A') {
      digitalWrite(13, HIGH);
    }
    else {
      digitalWrite(13, LOW);
    }
  }
}

The sketch will switch the LED on the Arduino Uno board on if the lower-case character 'a' or the upper-case character 'A' is sent from the serial monitor window. If any other character is sent, the LED is switched off.

How the Logical OR Operator Works

The code below is taken from the above sketch and shows the logical OR operator.

if (rx_byte == 'a' || rx_byte == 'A') {
  digitalWrite(13, HIGH);
}

The code in the body of the if statement will run if the variable rx_byte contains 'a' OR (||) if it contains 'A'. The OR operator has been used to test for one or the other character (A OR a).

The code can be modified to switch the LED on if the character 'a' or the character 'b' or the character 'c' is received, as this next code demonstrates.

if ((rx_byte == 'a') || (rx_byte == 'b') || (rx_byte == 'c')) {
  digitalWrite(13, HIGH);
}

In the above code, each equal to relational operator comparison has been put in parentheses () to make the code easier to read. This also avoids any misunderstanding about which operator is evaluated first (does the == or the || get evaluated first?).

The == has a higher precedence than the || which means that == is evaluated first. Parentheses have the highest precedence, so anything placed in parentheses will be evaluated first. In this case it is not necessary to place the parentheses, but makes it easier to read.

The AND Logical Operator (&&)

The next sketch demonstrates the use of the logical AND operator. The sketch tests to see that a sequence of two characters has been received before turning the LED on.

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

char first_char = 0;

void loop() {
  char rx_byte;
  
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // read the character
    if ((first_char == 'c') && (rx_byte == 'd')) {
      digitalWrite(13, HIGH);
    }
    else {
      first_char = rx_byte;        // save the character for next comparison
      digitalWrite(13, LOW);
    }
  }
}

In this sketch, two characters must be sent in the right order to switch the LED on. First 'c' must be sent, followed by 'd'.

How the Logical AND Operator Works

The AND operator from the above sketch is shown below.

if ((first_char == 'c') && (rx_byte == 'd')) {
  digitalWrite(13, HIGH);
}

The LED will only switch on when the variable first_char contains 'c' AND the variable rx_byte contains 'd'.

The variable first_char is used to store the current character received so that the next time the if statement is evaluated, we can see if it was followed by 'd' and if it contains 'c'.

The Logical NOT Operator (!)

The NOT operator can be used to check if a variable contains the value 0 – in other words it can be used to check if a variable evaluates to false.

int x = 0;
if(!x) {
	// if not x - if x evaluates to false, code here will run
}

// this code is another way of writing the above code
if (x == 0) {
}

NOT Operator Example

The following example shows the logical NOT operator being used in a sketch. Although this sketch is not a very practical application of the NOT operator, it does demonstrate how it works.

In the sketch, every character sent to the Arduino from the Serial Monitor window will switch the LED on, except the character 'a'.

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

void loop() {
  char rx_byte;
  
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // read the character
    if (!(rx_byte == 'a')) {
      digitalWrite(13, HIGH);
    }
    else {
      digitalWrite(13, LOW);
    }
  }
}

The not operator inverts the logic in the second if statement as shown below.

if (!(rx_byte == 'a')) {
  digitalWrite(13, HIGH);
}

If the variable rx_byte contains the character 'a', the expression in the if statement would then evaluate to true, however the NOT operator changes the result to false so that when 'a' is received the LED is switched off.

Similarly if the variable rx_byte contains any character except 'a', the expression would normally evaluate to false, but the NOT operator inverts the false result to true.

The above code could more easily be written using the not equal to (!=) relational operator as follows.

if (rx_byte != 'a') {
  digitalWrite(13, HIGH);
}

The logical NOT operator does have practical application in more complex sketches. Just remember that if the result of a comparison ever needs to be inverted, the logical NOT operator can be used. It can be used to force an if statement to evaluate to true when it would normally evaluate to false, thus executing the code in the body of the if statement instead of having to have an empty if statement and the code run in a corresponding else block.