Hobby Electronics Projects & More

Arduino Nano test circuit.Fig. 1 Arduino Test Setup

Arduino XOR Blinks LED

by Lewis Loflin

This is part of a series on code snippets for Arduino. Many visitors to my You Tube Channel and this website are beginners. They have limited knowledge of programming or hardware. This requires learning both.

Think of a micro-controller as a box full of basic logic circuits, gates, etc. To control the "box" we have to tell it what hardware to use. We must tell the "box" how to manipulate the gates and hardware. that is what machine code does.

I am using compiler Arduino-1.6.3. Results may vary with other compilers or a non-Nano Arduino board.

Fig. 1 shows the test setup for this series, in this case an Arduino Nano. I'll assume one can program their Arduino board. The Nano and most Arduino boards today have an LED on digital pin 13 (DP13).

Arduino uses a variation of C/C++ a complied language. That means the written code usually as a text file. This text file is "compiled" etc. to machine code that is written to the hardware. While C/C++ are much the same across most micro-controllers, the machine code is not.

The sequence is 1) write code text file (.ino for Arduino), 2) it is checked and compiled, 3) machine code uploaded to Arduino.

A few notes on this. "HIGH" can be replaced with "1"; "LOW" can be replaced with "0". So digitalWrite(LED, HIGH) is the same as digitalWrtie(LED, 1). Same with LOW and 0.

In the electrical sense a HIGH or 1 is 5-volts; a LOW or 0 is 0-volts or ground.

And "true" can be replaced by "1" or any non-zero number; "false" can be replaced by "0". I'll look at code for that as well.




#define LED 13 // 13 is on board LED
void setup() {
  pinMode(LED, OUTPUT);
}
void loop() {
  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
  delay(500);
} // end loop

Test 1

Above is the typical first code many programmers write. It simply blinks the DP13 LED ON and OFF. Half second ON (500mS), half second OFF (500mS).

Note an oddity. With digitalWrite(LED, HIGH) I can substitute true, 1, 2, -1, etc. will compile as "HIGH" with no errors. It works just fine.

That will make more sense when we explore control, decisions, and loop code.

The above code uses 1030 bytes and 4 lines of code to blink an LED. There is a better way.



#define LED 9 // 13 is on board LED
// can also be char, unsigned char, int
byte num = 0;

void setup() {
  pinMode(LED, OUTPUT);
}

void loop() {
  num = num ^ 1; // XOR with 1 inverts bit
  digitalWrite(LED, num);
  delay(500);
} // end loop

Test 2

Above I have replaced 2 lines of code with num = num ^ 1. XOR uses the "^" symbol and is a bitwise function. Any bit XORed with 1 is inverted. 1 becomes 0, 0 becomes 1. In this case the variable num holds the result. I saved a line of code and ~10 bytes.



  num = num ^ 1; // XOR with 1 inverts bit
  // num = 0
  // 0b00000000 ^ 0b00000001 = 0b00000001 = num = 1

  // num = 1
  // 0b00000001 ^ 0b00000001 = 0b00000000 = num = 0

This is what happens written in binary. Variable num is treated as any other non-zero variable by the digitalWrite() function. While num can be a char or int variable, int uses 2 bytes and waste one byte. Let's look at another variation of the above code.



void loop() {
  // num = num ^ 1; // XOR with 1 inverts bit
  digitalWrite(LED, num ^= 1);
  delay(500); 
} // end loop

Test 3

Here I have inserted the "num = num ^ 1" (same as num ^= num) into the digitalWrite() function. The compiler performs the XOR function then executes the digitalWrite() function. This can be very useful for "if" functions, etc.



void loop() {
  byte temp = digitalRead(LED) ^ 1;
  digitalWrite(LED, temp);
  delay(500); 
} // end loop

Test 4

When we program an Arduino pin direction with pinMode() as an output we can still use digitalRead() to determine the state of the corresponding latch bit. DigitalWrite() writes a 1 or 0 to a "latch". The latch state switches the pin to +5 volts if HIGH (LED ON), or to ground if LOW (LED OFF).

Above line 1 reads the latch state of LED pin, does an XOR to invert the bit state, then stores the inverted bit into temp. Line 2 writes temp back to the latch. The LED should blink at 1 Hz - 500mS ON, 500mS OFF.

But there is more.



void loop() {
  byte temp = !digitalRead(LED);
  digitalWrite(LED, temp);
  delay(500); 
} // end loop

Test 5

Notice line 1 uses a "!". I removed "^ 1". The "!" is a logical NOT function another version of XOR in my opinion.


void loop() {
  byte temp = digitalRead(LED);
  digitalWrite(LED, temp = !temp);
  delay(500); 
} // end loop

In fact I can insert the NOT within the digitalWrite(LED, !temp) function (line 2) if I leave it out of line 1.



Videos:
My YouTube Videos on Electronics
Introduction to the Arduino Microcontroller
Part 1: Programming Arduino Output
Part 2: Programming Arduino Input
Part 3: Arduino Analog to Digital Conversion
Part 4: Using Arduino Pulse-Width-Modulation
Repost Arduino AC Power Control