8.0 Communication Protocols
A standalone microcontroller is powerful, but its true potential is realized when it can exchange data with computers, sensors, and other microcontrollers. Communication protocols are the established rules that govern this data exchange. This section provides a reference for the three primary serial protocols available on the Arduino platform: UART, I2C, and SPI.
8.1 Serial Communication (UART)
While parallel communication transfers multiple bits at once over many wires, serial communication sends data one bit at a time over a single wire, making it ideal for longer distances. The most common form is asynchronous serial communication, used by the Arduino’s Serial library.
The protocol relies on several built-in rules to ensure reliable data transfer without a shared clock signal:
- Synchronization bits: A start bit signals the beginning of a data packet, and one or two stop bits signal the end.
- Data bits: The data packet size, typically 8 bits (one byte).
- Parity bits: An optional bit used for basic error checking.
- Baud rate: The speed of communication, measured in bits per second (bps). Both devices must be configured to the same baud rate.
The Arduino Serial library provides functions for UART communication:
- Serial.begin(speed): Initializes serial communication and sets the baud rate.
- Serial.println(data): Prints data to the serial port, followed by a carriage return and newline.
- Serial.available(): Returns the number of bytes available for reading from the serial port.
- Serial.read(): Reads incoming serial data.
- Serial.write(data): Writes binary data to the serial port.
8.2 Inter-Integrated Circuit (I2C)
I2C is a two-wire serial system designed for short-distance communication between a single master device and multiple slave devices on the same bus.
- SCL (Serial Clock): The clock line, driven by the master.
- SDA (Serial Data): The data line.
I2C pins vary by board:
- Uno: A4 (SDA), A5 (SCL)
- Mega: 20 (SDA), 21 (SCL)
- Leonardo: 2 (SDA), 3 (SCL)
The Wire library provides functions for I2C communication:
- Master Transmitter:
- Wire.begin(): Joins the bus as a master.
- Wire.beginTransmission(address): Begins transmission to a slave.
- Wire.write(data): Queues data to be sent.
- Wire.endTransmission(): Ends the transmission.
- Slave Receiver:
- Wire.begin(address): Joins the bus as a slave with a specific address.
- Wire.onReceive(handler): Specifies a function to run when data is received.
- Wire.available(): Returns the number of bytes received.
- Master Receiver:
- Wire.requestFrom(address, bytes): Requests a specific number of bytes from a slave.
- Slave Transmitter:
- Wire.onRequest(handler): Specifies a function to run when a master requests data.
8.3 Serial Peripheral Interface (SPI)
SPI is a full-duplex serial system that is generally faster than I2C. It uses four conductors:
- SCK (Serial Clock): Clock signal from the master.
- MOSI (Master Out, Slave In): Data from the master to the slave.
- MISO (Master In, Slave Out): Data from the slave to the master.
- SS (Slave Select): Used by the master to select which slave device to communicate with.
The SPI library includes several key functions:
- SPI.begin(): Initializes the SPI bus.
- SPI.setClockDivider(divider): Sets the SPI clock speed relative to the system clock.
- SPI.transfer(value): Sends and receives one byte of data simultaneously.
- SPI.beginTransaction(settings): Begins an SPI transaction with specified settings.
- SPI.attachInterrupt(handler): Attaches an interrupt handler for when a slave receives data.
SPI supports four data modes (Mode 0, 1, 2, 3), which define the clock polarity and phase. Both master and slave must be configured to use the same mode.
These communication protocols are foundational for interfacing with a vast array of modern sensors and modules, including those used by more advanced Arduino boards.