Communication Protocols (developed Winter 2019 for 2018/2019 ICS3U)


6 Arduino-Compatible Communication Protocols


Bluetooth (Wireless UART) with the HC-05 Transceiver

We finish up our ICS3U look at Arduino-Compatible Communication protocols by returning to where we began weeks ago, with the Arduino's UART. However, this time, we're exploiting it wirelessly, under the Bluetooth (2.4GHz radio) banner.

Given the complexity of the pairing sequence of the Bluetooth protocol this introduction will limit itself to Arduino⇆Arduino communication. Motivated students are encouraged to explore ArduinoLaptop and ArduinoAndroid Phone pairings.

As is the custom of the Serial UART protocol between two devices, the roles of master and slave must be established. These roles, together with a few other parameters, must be written into the RAM of the devices prior to the pairing. This is accomplished by entering AT COMMAND Mode and entering the required values. AT Command References appear below.

Although there are a few blogs out there with plenty of detailed backround information, I found this terrific video got right to the point of successfully pairing up two HC-05s.

How to Pair HC-05 Bluetooth Modules

LED Flashing Patterns

Github: BT Confirmation sketches discussed in class

Additional References

IC Datasheet and AT Command Manual: EGBT-045MS/EGBT-046S

AT Command Set

Martyn Currey Tutorials

Self-Reflection (2019 02 18)


IR Communication with TSOP2138 (38kHz) and TSOP32240 (40kHz)

The graph (below, left) is of data a data signal modulated upon a carrier wave. Demodulation can separate the carrier frequency from the data (below, right) using mathematics (FFT). Source: Adafruit Learning- FFT Fun with Fourier Transforms

SBProjects: IR Control Theory (A Must Read)


Ken Shirriff:

  1. Arduino as Universal Remote
  2. Multi-Protocol IR Library For Arduino
  3. IRremote Library Code

Sparkfun: IR Communication (with Supporting Video Tutorial)

The majority of the IR protocols from NEC, Philips, Sharp, etc. center on 38kHz, far enough outside the frequency band of ambient IR sources like the sun, flames and other common light sources to avoid signal noise issues. Sony's SIRC protocol differs and is centered on 40kHz. For a project you may wish to pursue simply ask me for an IR Receiver for either frequency.


  1. Breadboard and test this simple 5V beambreaker circuit.
  2. Install the GP1UX511QS IR Detection device, along with a bicolor LED as appliances in your UNO as shown below,

  3. Pay close attention to our collective review of the sketch code contained in the handout, IRLEDControl.docx.
  4. Once Shirriff's IRremote library in installed, open the sketch IRLEDControl and upload it to your UNO.
  5. Open the Serial Monitor and start pressing buttons on your remote. Look for consistent patterns bwtween the data being displayed and the results data structure.
  6. With the knowledge gleaned from the previous step, explore make modifications such as swapping the Bicoloe LED with an RGB LED.

Possible Project Considerations:


RF: Radio Frequency Communication (with Nordic's nRF24L01)

AVR Foundations: pp. 84-87
Web Reference: Arduino Wireless Communication
Kevin Darrah: nRF24L01+ Arduino Communication
Video Review: nRF24L01+ Options
Inspiring Project: DIY Arduino RC Transmitter

So here's what I've learned from my research and preparation for this introduction to RF (presented in an order that should make sense)

  1. The unlicensed radio frequency band open to the Industrial, Scientific and Medical (ISM) Communities operates within the 2.400GHz to 2.525GHz range of the electromagnetic spectrum. (This 4G technology is about to be supplanted by 5G in which the next generation of devices will exploit the 6GHz frequency band)
  2. For the orderly and reliable transmission of data, a separation of 0.001GHz is required, leading to 126 possible avenues (referred to as channels).
  3. Since cell phones, bluetooth devices, near field communication (NFC) devices, and wireless computer networks (WiFi) all use the ISM frequencies this frequency band can get very crowded.
  4. For a few dollars Nordic's NRF24L01+ Transceiver offers Arduino users simple communication access to ISM devices over a range as high as 800m, consuming lower current than a typical LED (12mA), selectable data rates up to 10Mbps, and a STRICT VCC requirement of 3.3V, with other pins being 5V tolerant.
  5. The nrf24L01+ communicates with your Arduino through the SPI protocol (MOSI-11, MISO,-12 SCK-13).
  6. An ACES Appliance PCB Breakout board has been designed to facilitate efficient insertion of the nRF24L01+ directly into your Arduino's PORTB. The only wire required connects the appliance to the 3.3V supply pin on the other side of the Arduino as shown below.
  7. I've written a matched pair of CHANNEL numbers on the backs of the breakout boards. Insert your nRF Appliance into your Arduino and find your partner Designate one partner as the Transmitter (Tx) and place a trim pot in PC0 to PC2 as shown below. The other platform is the Receiver (Rx) and should have a Morland Bargraph inserted in PC0-PC4 as shown.
  8. For the code aspect of this project you will rely on the well established library with the documentation found at,
  9. Transmitter: Create the Arduino Project TxTest and replace the template code with this sketch code.
  10. Receiver: Create the Arduino Project RxTest and replace the template code with this sketch code.
  11. Both the Transmitter and Receiver sketches will edit the CHANNEL definition to match the number on the back of their appliance.
  12. Upload the sketches to their respective platforms and confirm that analog readings from the transmitter is sent and received across the DES and displayed on the receiver's bargraph.

I2C: Inter-integrated Communication

AVR Foundations: pp. 90-93
Reference: Arduino Wire Library
Gammon: Two-Wire Peripheral interface
Video Tutorial Example: TC74 (Start at 54s)

Whereas the SPI protocol requires an extra SS pin for every additional slave device, the I2C protocol only requires two pins (in total) to communicate to up to 128 devices. Imagine an 8-pin ATtiny85 controlling up to128 other devices! One pin is a clock line for synchronous support and the other pin is the data line. These two pins are Serial Clock (SCL) and Serial Data (SDA), respectively. Conveniently, the pins are broken out on the UNO on both sides of the Arduino. SCL and SDA share the Analog A5 and A4 pins and the two pins closest to the Reset button if the analog pins are required for other purposes.

Philips Semiconductor (now NXP of the Netherlands) developed the technology in 1982. Since I2C is a trademark, manufacturers of devices must pay a license fee to use the term. Microchip (formerly ATMEL) and other manufacturers get around the fee by calling their devices TWI (Two-Wire Interface) but they're 100% compatible.

The key to this highly-leveraged, efficient strategy is that the I2C bus acts like a street with devices having addresses on that street. Addresses are set by the manufacturer and impressed within the device. Let's focus on one such I2C/TWI device: The TC74 Digital Thermal Sensor. Open the TC74 datasheet and look at the ordering information on page 13, presented as an excerpt below. Embedded systems designers have the responsibility of ensuring their shared devices have unique addresses on the I2C bus. The TC74 device you have been provided with is the TC74A0-5.0VAT in the TO-220-5 package so it has an I2C bus address of B1001 000 or 0x48.

In the previous investigation of SPI, you were introduced to the concept of digital sensors having internal RAM, typically organized into byte-sized registers. For example, to set the wiper position of Potentiometer 0 of the MCP4231 you write a specific value to RAM address 0x00. Similarly, I2C/TWI devices have internal RAM storage that requires programming skill to manipulate. Grade 11 ACES are free to use the Wire Library to make this programming easy. Grade 12 ACES will program these devices directly in Assembly.

Chapter 4.0 of the TC74 Datasheet (p. 8) discusses the device's RAM organization. From the excerpt below, it can be seen that (read-only) address 0x00 holds the temperature data to be read. Read/Write Register 1 can be programmed to configure the device for certain optimized performance capabilities.

  1. Using the key provided in the image of the TC74 depicted to the right, wire the device to your Arduino.
  2. Create the Arduino project TC74ReadTemp and replace the template code with this sketch code.
  3. Examine and upload the code, confirming the (reasonable) accuracy of the data in the Serial Monitor.
  4. J. Blum offers an inspiring video outlining Processing's visualization of captured TC74 data.
  5. You'll find a couple of other I2C devices (EEPROM, digital potentiometer, and RTC) discussion in our workbook on pp. 93-94.


SPI: Serial Peripheral Interface

AVR Foundations: pp. 82-83
Reference: Nick Gammon on SPI

The ATmega328p MCU's built in SPI device offers extremely fast, full duplex, wired communication between similarly-compatible components. As the image to the right depicts, four wires are required to connect the master to a slave (if response from the slave is not required, the MISO wire can be eliminated). Should your MCU master wish to communicate with multiple slave devices, and extra SS line is required for each. Te master pulls only one SS low at a time to exchange data.

At this point in the course, you have, likely unknowingly, used the SPI concept, twice. The most direct use of the actual SPI hardware was invoked when you used your Pocket AVR programmer to reflash the bootloader to your Arduino using the ISP header (the ISP pins are 1-MISO, 2-5V, 3-SCK, 4-MOSI, 5-RESET, 6-GND). The second (simulated) SPI concept is invoked whenever you use the shiftOut() function. This activity employs clock (SCK), data (MOSI), and latch (SS) pins.

Finally, if you find value in video explanations of Arduino concepts, here's a decent one: Serial Programming Interface and here's its Supporting Tutorial.

SPI with Morland Bargraph V3 SPI with MCP4231 (Dual) Digital Potentiometer

We're going to explore SPI on two different prototypes depicted above. You have a Morland Bargraph V3 for the first investigation and have been given an MCP4231 digital potentiometer for the second.

You've been provided with a hard copy of the code for both projects in the Word document, SPILibraryExamples.docx. The code is also available on our GitHub:

Task 1.

  1. Insert your Morland Bargraph V3 appliance into your Arduino as shown. The SPI-compatible pin arrangement makes this connection the easiest ever.
  2. Look at the silk screening of the pin labels. These with two labels serve to associate the hardware SPI functionality with the software shiftOut functionality.
  3. Create the project SPIShiftOut and replace the default code with this sketch code. We'll review the code in class.
  4. If you upload the code to your prototype you'll see the results of the use of the hardware SPI transfer in that the rightmost two LEDs are lit.
  5. Returning to your code, swap the comment bars in lines 23 and 24. Uploading this version, invokes the software shiftOut yielding the identical result.
  6. To conclude, the advantage of the hardware SPI is that it is typically 100× faster that the software alternative. The advantage of the software shiftOut is that it can be undertaken on any trio of pins. Note that this choice parallels our previous investigation of UART: Serial Communications. You can use the hardware UART in pins 0 and 1 only, but SoftwareSerial can be undertaken on any two digital pins.

Task 2.

  1. The goal of this investigation is to capture and confirm the varying voltage on Potentiometer 0's Wiper pin (P0W). We won't be using Potentiometer 1.
  2. Create the hardware prototype depicted in the Fritzing diagram above right, wiring the SPI pins from your Arduino to the MCP4231 as shown. Required pin interpretations are shown in RED. IF you have access to a DMM wire it in as shown. If you do not, wire a resisted LED to P0W.
  3. Open the MCP4231 datasheet and turn to page 47, Device Commands. Read this intently to get a first-hand appreciation of how this device is to be programmed.
  4. Create the project MCP4231 and replace the default code with this sketch code. We'll review the code in class.
  5. If you upload the code to your prototype the DMM Voltmeter should oscillate between roughly 0V and 5V and back to 0V in 128 increments. Open the Serial Monitor to compare the data written (MOSI>SDI) to the device vs the value read (SDO>MISO).

UART: Universal Asynchronous Receiver/Transmitter (Serial Rx/Tx)

AVR Foundations: pp. 10-11
Reference: UART: Universal Asynchronous Receiver/Transmitter


Basic Concept

  1. Serial Communication involves the timed exchange of single bits, in sequence, between two parties.
  2. Two wires are required, one for the transmission of data (Tx) and one for the receiving (Rx). The Tx wire of one party is the Rx wire of the other.
  3. The coordinated timing can be agreed upon ahead of time (setting a common baud rate-UART) or done with the assistance a separate clock line (USART).

On Your Arduino (ATmega328p)

  1. The ATmega328P has only 1 UART system onboard. The Arduino Mega2560 has 4!
  2. The Rx/Tx pins can be found broken out to digital pins 0 and 1 and surface mount LEDs also appear on the Arduino board.
  3. If you use the standard USB A-USB B cable to program your Arduino you are employing the services of the MCU's Serial UART communication and you can observe the activity on the flashing LEDs.
  4. If you place an LED or any other device in digital pins 0 and 1 and try to flash new code, the signals are interfered with and your program (and IDE) will very likely hang :(
  5. On the other hand, AFTER your code is flashed, and your code refrains from employing the services of the Serial Monitor (Serial.begin(9600));) feel free to place an LED in pins 0 and 1 and develop code to demonstrate blinking. We'll do this later in this lesson.
  6. It's certainly a hassle disconnecting and reconnecting a component from pins 0 and 1 every time you want to flash new code. So, if you want to use pins 0 and 1 for normal digital use, consider using your Pocket AVR Programmer to flash new code. It does NOT use the UART, but rather the ISP header, a different communication protocol similar to SPI, that we will get to in the classes ahead.

Using the Serial Monitor

  1. The Serial Monitor (referred to as the terminal window on other systems) is a simple utility that allows you, the user, to interact directly with the ATmega328p's UART, by receiving data bits representing 7-bit ASCII characters, and allowing you to transmit ASCII characters back through the one-line text box at the top.
  2. The statement Serial.begin(9600, SERIAL_8N1); you've used many times already is simply a request for the MCU to enable its UART for communication. This action does disable pins 0 and 1 for digital use, so do not invoke the UART if you want those pins for other uses.
  3. The second parameter shown above is the the default value that establishes the rules for the exchange of bits. In this case, we're saying 8 bits are required to form a full byte, no parity-checking will be enforced, and 1 bit is used to mark the end of the frame (stop bit). The other preconfigured constants can be found here.

The Serial and SoftwareSerial Classes

  1. The hardware UART device onboard the ATmega328p is supported in software through the resources of the Serial Class.
  2. Once the UART has been enabled and ready for service, common functions include, available(), read(), write() and print(). Understand their use by reading the class documentation.
  3. The shortcoming of the single UART on the ATmega328p is mitigated to some extent through the use of the SoftwareSerial Class that emulates serial communication on ANY two digital pins.


  1. SerialEchoTest.ino
  2. SerialPrintModifiers.ino (activate displayBinary() function for full 8-bit binary presentation)
  3. DigitalPins0and1.ino(remove bicolor LED while uploading)
  4. Processing: File > Examples > Serial > SimpleRead.pde
  5. Processing Support: Serial1HzSquareWave.ino (see p. 72 of your workbook for a Rover-type project using Processing)
  6. TicTacToeAutonomousRandom.ino (this sets us Part 2's inter-Arduino game next week) (Word Version)


This stage opens the door to a wide-ranging array of projects involving MCU communication. We start with the simplest form of information exchange between two Arduino UNOs using their builtin UART peripherals that you have, perhaps unknowingly, been exploiting from the beginning. In this introductory confirmation of the 328p's serial communication capabilities you and your partner will set up a client/server (more PC than master/slave) platform in which the client simply sends commands to the server requesting the server turn it's onboard LED on and off over intervals determined by the client.

Task 1.

  1. Devices can be acquired that use serial communication to exchange data with a host. One such device is Adafruit's V3 Ultimate GPS Breakout (antenna sold separately). In this exercise we'll just follow the direct wiring example found here, bypassing the MCU, using the minimal BlankGPSEcho.ino code.

    Adafruit's V3 Ultimate GPS Breakout GPS Output: Online Decoder

  2. Review the File>Examples>Communication>PhysicalPixel sketch. Upload it to your own Arduino confirm that it responds as expected as you issue the single-character commands H and L from your Serial Monitor.
  3. Download the client (transmitter) sketch, SerialClient, and review its contents.
  4. Grab a partner and identify between the two of you, the roles of CLIENT and SERVER. (Do NOT wire the platform shown below until instructed to do so in Step 5)
  5. The SERVER is asked to have the PhysicalPixel host sketch on his Arduino, with the LED spanning pin 13 and ground.
  6. Now, wire up the Serial Communication platform as shown below. Note the common ground and that the Rx pin of one device is connected to the Tx pin of the other.
  7. The CLIENT will use his AVR Pocket Programmer as shown to upload the SerialClient code using Sketch>Upload Using Programmer (programming through the ISP header avoids the Rx/Tx interference caused by the USB-Serial cable)
  8. As is, confirm the SerialClient code simply flashes the SERVER's pin 13 LED with a 66.6% duty cycle. Enhanced CLIENT code would enable the CLIENT to command the SERVER by entering an H or L through his own serial monitor. Unfortunately, there is only ONE serial UART on the ATmega328p and it's already taken up communicating with the SERVER Arduino. The solution is to employ a software emulation of the UART, which we do in the next stage through the use of the SoftwareSerial library.
  9. Remaining in your pairs, place a Morland ShiftBar device in the SERVER Arduino, facing inwards, using pins 13,12,11,10, & 9. On the SERVER-side, save the PhysicalPixel sketch to ServerEchoShiftBar and modify it shift out the incomingByte to the device, using LSBFIRST (the CLIENT code can remain as is, transmitting H, L, H, L , ...). If all is well, you should see the binary ASCII values of H and L alternating on the display (other displays you might eventually consider are your Reed Matrix appliance or even a 7-segment display).

The first task restricted itself to one-way serial communication from client to server. In this second stage, we'll confirm full two-way communication.


The ATmega328p has only one hardware UART peripheral. This poses a challenge if two ACES want to have a chat through their respective Arduino IDE's Serial Monitor. Fortunately, a software solution comes to the rescue in the form of the SoftwareSerial Library that can turn any pair of unused digital pins into Rx/Tx serial communication lines. In the configuration below, the hardware serial UART on pins 0 and 1 are crossed with the partner's software serial UART on pins 11 and 10. A common ground is maintained.

Task 2.

  1. Review the Arduino's Software Serial Example. Another informative instructable is here.
  2. Full, two-way serial communication between you and your Arduino UNO partner can be achieved by downloading this similar sketch, Chat.ino.
  3. A review of the code requires a cross-wiring of pins 10 and 11 between each UNO and the comments explain how the hardware and software serial communication lines function.
  4. After each partner uploads the identical sketch and launches his serial monitor, they (should be) free to have a conversation.