This chapter introduces three common communication protocols in Arduino: SPI (Serial Peripheral Interface), I2C (Inter-Integrated Circuit), and UART (Universal Asynchronous Receiver-Transmitter). These protocols are essential for connecting external devices like sensors, displays, and modules to your Arduino. Each protocol has unique characteristics that make it suitable for specific types of communication tasks. We’ll explore how to set up and use each of these protocols with detailed code examples and explanations.
Syntax Table communication protocols in Arduino
Topic Name | Syntax | Simple Example |
SPI.begin() | SPI.begin(); | SPI.begin(); |
SPI.transfer() | SPI.transfer(byte); | byte data = SPI.transfer(0x42); |
Wire.begin() | Wire.begin(); | Wire.begin(); |
Wire.requestFrom() | Wire.requestFrom(address, quantity); | Wire.requestFrom(0x08, 1); |
Wire.write() | Wire.write(data); | Wire.write(0x42); |
Serial.begin() | Serial.begin(baudRate); | Serial.begin(9600); |
Serial.read() | Serial.read(); | char c = Serial.read(); |
SPI (Serial Peripheral Interface):
SPI (Serial Peripheral Interface) in Arduino
SPI (Serial Peripheral Interface)?
SPI (Serial Peripheral Interface) is a synchronous serial communication protocol used to transfer data between a microcontroller (such as an Arduino) and one or more peripheral devices, like sensors, SD cards, and displays. SPI is commonly used because of its fast data transfer rate and its ability to communicate with multiple devices using just four main communication lines. It is often preferred for applications where speed and simplicity are critical.
Use purpose
The SPI protocol is used for:
- High-speed communication: Fast data exchange between the microcontroller and external devices.
- Multiple device communication: Communicating with several peripheral devices using one master and multiple slaves.
- Efficient data transfer: Suitable for data-intensive applications such as reading data from SD cards, controlling displays, or working with sensors that require fast data acquisition.
Arduino SPI Pins
- MISO (Master In Slave Out): Data sent from the slave device to the master (typically pin 12 on Arduino Uno).
- MOSI (Master Out Slave In): Data sent from the master to the slave device (typically pin 11 on Arduino Uno).
- SCK (Serial Clock): The clock signal generated by the master device (typically pin 13 on Arduino Uno).
- SS (Slave Select): Selects the slave device to communicate with (typically pin 10 on Arduino Uno).
Arduino Syntax use SPI.begin();
SPI.transfer(byte);
SPI.end();
Arduino Syntax Explanation
- SPI.begin();: Initializes the SPI communication as a master device.
- SPI.transfer(byte);: Sends a byte of data via SPI and simultaneously receives a byte of data from the slave device.
- SPI.end();: Ends the SPI communication.
Arduino code Example
#include <SPI.h> // Include the SPI library
const int slaveSelectPin = 10; // Pin connected to the SS of the slave device
void setup() {
pinMode(slaveSelectPin, OUTPUT); // Set the SS pin as output
SPI.begin(); // Initialize SPI communication
Serial.begin(9600); // Start serial communication
}
void loop() {
digitalWrite(slaveSelectPin, LOW); // Select the slave device
byte data = SPI.transfer(0x42); // Send data (0x42) to the slave and receive data
digitalWrite(slaveSelectPin, HIGH); // Deselect the slave device
Serial.print("Received Data: ");
Serial.println(data); // Print the received data
delay(1000); // Wait for 1 second
}
Code Explanation
- SPI.begin();: Starts SPI communication in master mode, allowing the Arduino to communicate with external SPI devices.
- digitalWrite(slaveSelectPin, LOW);: Selects the slave device by setting the SS pin to LOW.
- SPI.transfer(0x42);: Sends the byte 0x42 to the slave device while simultaneously receiving data from the slave.
- digitalWrite(slaveSelectPin, HIGH);: Deselects the slave device by setting the SS pin back to HIGH.
- Serial.println(data);: Prints the data received from the slave to the serial monitor for observation.
Notes
- SPI is a full-duplex communication protocol, meaning data is sent and received simultaneously.
- Multiple devices can be connected to the same SPI bus, with each device having its own SS (Slave Select) pin to enable communication.
- SPI.begin() must be called in the setup() function to initialize the SPI communication.
- The SPI.transfer() function sends a byte of data to the slave while also receiving one byte of data from the slave in the same transaction.
- To communicate with multiple devices, each device needs its own SS pin, and you can select the device by pulling its SS pin LOW during communication.
I2C (Inter-Integrated Circuit) in Arduino
I2C (Inter-Integrated Circuit)?
I2C (Inter-Integrated Circuit) is a two-wire, synchronous serial communication protocol commonly used to connect multiple devices, such as sensors, displays, and other peripherals, to a microcontroller like Arduino. I2C allows communication between a master device (usually the microcontroller) and one or more slave devices using just two wires: SDA (data line) and SCL (clock line). It’s ideal for connecting multiple devices to the same bus with unique addresses.
Use purpose
The I2C protocol is used for:
- Communicating with multiple devices: Allows multiple devices to share the same bus using unique addresses.
- Interfacing sensors and displays: Commonly used to communicate with I2C-enabled sensors, EEPROMs, or displays (like OLED or LCD).
- Efficient data transfer: It is used for low-speed, short-distance communication, making it suitable for peripheral devices.
Arduino I2C Pins
- SDA (Serial Data Line): Carries the data to be transferred (usually pin A4 on Arduino Uno).
- SCL (Serial Clock Line): Carries the clock signal to synchronize communication (usually pin A5 on Arduino Uno).
Arduino Syntax use
Wire.begin();
Wire.requestFrom(address, quantity);
Wire.beginTransmission(address);
Wire.write(data);
Wire.endTransmission();
Arduino Syntax Explanation
- Wire.begin();: Initializes the I2C communication as a master.
- Wire.requestFrom(address, quantity);: Requests data from a slave device at the specified address.
- Wire.beginTransmission(address);: Starts communication with the slave device at the specified address.
- Wire.write(data);: Sends data to the slave device.
- Wire.endTransmission();: Ends communication with the slave device.
Arduino code Example
#include <Wire.h> // Include the Wire (I2C) library
const int slaveAddress = 0x08; // I2C address of the slave device
void setup() {
Wire.begin(); // Initialize I2C as master
Serial.begin(9600); // Start serial communication
}
void loop() {
Wire.beginTransmission(slaveAddress); // Start communication with the slave
Wire.write(0x42); // Send a byte of data (0x42)
Wire.endTransmission(); // End the transmission
Wire.requestFrom(slaveAddress, 1); // Request 1 byte of data from the slave
if (Wire.available()) { // If data is available from the slave
byte data = Wire.read(); // Read the byte
Serial.print("Received Data: ");
Serial.println(data); // Print the received data
}
delay(1000); // Wait for 1 second
}
Code Explanation
- Wire.begin();: Initializes the I2C bus, setting the Arduino as a master device.
- Wire.beginTransmission(slaveAddress);: Starts communication with the slave device at the I2C address 0x08.
- Wire.write(0x42);: Sends a byte of data (0x42) to the slave device.
- Wire.endTransmission();: Ends the transmission with the slave device.
- Wire.requestFrom(slaveAddress, 1);: Requests 1 byte of data from the slave device.
- Wire.available();: Checks if data is available to be read from the slave.
- Wire.read();: Reads the byte received from the slave and stores it in a variable.
- Serial.println(data);: Prints the received data to the serial monitor.
Notes
- I2C is a multi-master, multi-slave communication protocol, meaning multiple master and slave devices can share the same I2C bus.
- Each I2C device has a unique 7-bit address, allowing the master device to communicate with multiple slaves using the same two wires.
- The Wire.h library is used for I2C communication on Arduino. You must include this library to use I2C functions.
- Ensure that each I2C device connected to the bus has a unique address. Addresses can often be found in the device’s datasheet.
- Pull-up resistors (typically 4.7kΩ or 10kΩ) are usually required on the SDA and SCL lines for proper communication.
UART (Universal Asynchronous Receiver-Transmitter) in Arduino
UART (Universal Asynchronous Receiver-Transmitter)?
UART (Universal Asynchronous Receiver-Transmitter) is a communication protocol used in Arduino and other microcontrollers for serial communication between devices. It facilitates the exchange of data between the microcontroller (Arduino) and external devices, such as computers, sensors, or other microcontrollers. Unlike synchronous protocols like SPI or I2C, UART uses only two communication lines: TX (Transmit) and RX (Receive). It is a full-duplex communication method, meaning data can be sent and received simultaneously.
Use purpose
The UART protocol is used for:
- Serial communication: Allows sending and receiving data over a serial interface.
- Communication with computers: Used to send data from the Arduino to a PC or to receive data using the Serial Monitor in the Arduino IDE.
- Communication between microcontrollers: Enables communication between multiple microcontrollers or peripheral devices like Bluetooth or GPS modules.
UART Pins on Arduino
- TX (Transmit): Sends data from the Arduino to another device.
- RX (Receive): Receives data from another device to the Arduino.
- Arduino Uno: TX (Pin 1) and RX (Pin 0).
- SoftwareSerial: Allows using other digital pins as additional TX/RX pins.
Arduino Syntax use
Serial.begin(baudRate);
Serial.write(data);
Serial.read();
Arduino Syntax Explanation
- Serial.begin(baudRate);: Initializes the UART communication with a specific baud rate (speed of communication).
- Serial.write(data);: Sends binary data (bytes) via UART.
- Serial.read();: Reads the data received via UART.
Arduino code Example
void setup() {
Serial.begin(9600); // Start serial communication at a baud rate of 9600
}
void loop() {
if (Serial.available() > 0) { // Check if data is available to read
char receivedChar = Serial.read(); // Read the incoming data
Serial.print("Received: ");
Serial.println(receivedChar); // Print the received character
}
delay(1000); // Wait for 1 second
}
Code Explanation
- Serial.begin(9600);: Initializes UART communication at 9600 baud, which is a common data transfer rate for serial communication.
- Serial.available();: Checks if any data is available to read from the RX pin.
- Serial.read();: Reads one byte (character) of data from the RX pin.
- Serial.print();: Prints the received data to the Serial Monitor for observation.
Notes
- UART is asynchronous, meaning that data is sent and received without a clock signal, and both devices need to agree on a baud rate (communication speed) to exchange data correctly. Common baud rates include 9600, 14400, 19200, and 115200.
- The TX pin of one device should be connected to the RX pin of the other device, and vice versa, for correct communication.
- Serial Monitor in the Arduino IDE can be used to observe or send data through the UART interface.
- While the Arduino Uno has a single hardware UART port (on pins 0 and 1), you can use the SoftwareSerial library to create additional serial ports using other digital pins.
Common Problems and Solutions
- Problem: SPI communication not working.
- Solution: Ensure the correct Slave Select (SS) pin is used and properly managed by pulling it LOW when communicating with the slave device.
- Problem: I2C devices not responding.
- Solution: Verify that each device has a unique address. Pull-up resistors on the SDA and SCL lines may be required for proper communication.
- Problem: UART communication producing garbled output.
- Solution: Ensure that both devices are using the same baud rate. Check the wiring between TX and RX pins, and ensure they are connected correctly.
Chapter Summary
In this chapter, we learned about three popular communication protocols in Arduino: SPI, I2C, and UART. These protocols enable communication between the Arduino and external devices. We covered how to initialize and use these protocols for data transfer, including setting up SPI with SPI.begin(), communicating over I2C with Wire.begin(), and sending data via UART using Serial.begin(). Each protocol has its advantages depending on the type of project you’re working on, from fast data transfer (SPI) to multi-device communication (I2C) to simple serial communication (UART).
FAQ
- What is the difference between SPI and I2C?
- SPI is faster and uses four wires, while I2C uses only two wires but is slower. I2C is more suitable for connecting multiple devices using unique addresses.
- Why use UART over SPI or I2C?
- UART is simpler to set up and ideal for communicating with devices like computers or Bluetooth modules. It requires only two lines: TX and RX.
- Do I need pull-up resistors for I2C communication?
- Yes, pull-up resistors (typically 4.7kΩ or 10kΩ) are usually required on the SDA and SCL lines for I2C communication to work correctly.
Simple MCQ Questions and Answers
- Which protocol uses only two wires for communication?
- a) SPI
- b) I2C
- c) UART
- Answer: b) I2C
- What function is used to initialize UART communication in Arduino?
- a) SPI.begin()
- b) Wire.begin()
- c) Serial.begin()
- Answer: c) Serial.begin()
- Which pin is used for receiving data in UART communication on an Arduino Uno?
- a) Pin 1
- b) Pin 0
- c) Pin 13
Answer: b) Pin 0