I2C, SPI, UART Connection Diagram
So exactly what do these cryptic acronyms mean?
- UART = Universal Asynchronous Receiver / Transmitter
- SPI = Serial Peripheral Interface
- I2C = Inter-Integrated Circuit
All represent standard communications protocols that are available through the Raspberry Pi GPIO (General Purpose Input/Output) pins. Each has characteristics that may be better for a particular project. This article will contrast the three methods and highlight some of their advantages/disadvantages.
Data communications is important for devices, like the Raspberry Pi, to communicate and exchange "data" with other devices. Examples of devices that the RPi may communicate include: display devices, sensors, robotics, other computers, input devices, industrial controls, scientific instruments, . . .
I2C, SPI and UART are all digital, serial communications methods.
|I2C||Inter-Integrated Circuit||Half duplex, serial data transmission used for short-distance between boards, modules and peripherals. Uses 2 pins.|
|SPI||Serial Peripheral Interface bus||Full-duplex, serial data transmission used for short-distance between devices. Uses 4 pins.|
|UART||Universal Asynchronous Receiver-Transmitter||Asynchronous, serial data transmission between devices. Uses 2 pins.|
*Note: The CSI and DSI connectors on the Pi also offer data communications to camera and display devices, but this article covers the general purpose communications buses on the RPi GPIO.
Before we discuss the features and differences between these methods, let's review a few common communications terms and definitions.
|Data Communications||Electronic transfer of information via wired and wireless mediums.|
|Communications Protocols||The established methods or rules used between devices to send or receive data communications.|
|Bus||The electro-physical connections (pins, cables, circuit board connectors) between devices that support data communications.|
|Serial / Parallel||Serial: data communications using few connections, typically 2 or 4, that send/receive 1 bit of information per cycle.
Parallel: data communications using multiple connections, typically 8 or more, in parallel to transfer whole bytes (or more) of information per cycle.
|Synchronous / Asynchronous||Synchronous: communications using a common "clock" signal to synchronize the transfer of data between devices.
Asynchronous: transmission of data without the need of a clock signal to synchronize transmission.
|Half Duplex / Full Duplex||Half Duplex: limited to data transfer between devices in one direction at a time.
Full Duplex: capable of data transfer in both directions simultaneously.
|Data Rate||Data communications transfer rate expressed in bits per second (bps), kilobits / second (kbps) or megabits / second (Mbps).|
I2C is bidirectional, synchronous, serial communications interface. If operates on two lines in a half-duplex mode. It was originally created by Philips Semiconductor which later became NXP Semiconductors. A single master (the RPi) can communicate with one or more slave devices. Each connected device is selected via a 7 bit address (10 or more bit addressing is possible, but more complex). Originally limited to 100 kbits per second, it now supports faster transmission rates. The Pi can support 100 kbits standard mode as well as 400 kbits "fast mode", with some reports citing higher speeds depending on cable length, board model and software processing.
With its 7 bit addressing, I2C can support up to 127 devices (or nodes). The two lines are called SCL and SDA. SCL is the clock line for synchronizing transmission. SDA is the data line through which bits of data are sent or received. During transmission, the first byte includes the 7 bit address plus a read / write bit. Subsequent bits represent the actual data.
I2C connection to the RPi is made using GPIO board pins 3 for SDA and 5 for SCL (BCM mode GPIO 2 and GPIO 3). The RPi GPIO operates at 3.3v so care must be taken to ensure connections to slave devices are also 3.3v. A voltage level converter can be used if necessary to interface to other devices, i.e. 5v Arduino to RPi 3.3v.
I2C wiring distance is considered relatively short, typically from inches to a few meters. Distance is affected by data speed, wire quality and external noise.
SPI is a bidirectional, synchronous, serial communications interface - like I2C. Also like I2C, it is used for relatively short distances. Unlike I2C, however, SPI operates at full duplex, meaning data can be sent and received simultaneously. Additionally, it can operate at faster data transmission rates, with rates upwards of 8 Mbits or more possible on the RPi.
SPI can communicate with multiple devices through two ways. The first is by selecting each device with a Chip Select line. A separate Chip Select line is required for each device. This is the most common way RPi's currently use SPI. The second is through daisy chaining where each device is connected to the other through its data out to the data in line of the next. The image at the top of this article illustrates the first method.
There is no defined limit to the number of SPI devices that can be connected. However, practical limits exist due to constrains by the number of hardware select lines available on the master in the first method, or the complexity of passing data through devices in the second daisy chain method.
The RPi has two Chip Select (CE0 & CE1) lines readily available. More can be defined by configuring other GPIO pins and through software programming.
|Board Pin||BCM Number||Function|
|19||GPIO 10||MOSI - Master Out Slave In|
|21||GPIO 9||MISO - Master In Slave Out|
|23||GPIO 11||SCLK - Serial Clock|
|24||GPIO 8||CE0 - Chip Select 0|
|26||GPIO 7||CE1 - Chip Select 1|
Origins of the UART go back decades making this the granddaddy of communications hardware / protocols. Its simplicity and wide application has stood the test of time and is still a popular method for data communications.
UART is a hardware implementation that supports bidirectional, asynchronous, serial communications. It requires two data lines - one for transmit and one for receive. The transmit line of one device is connected to the receive line of the second device, and vice versa for transmission in both directions.
A UART can only connect between two devices. It can operate between devices in: 1) Simplex - data transmission in one direction only; 2) Half Duplex - data transmission in either direction, but not simultaneously; or, 3) Full Duplex - data transmission in both directions simultaneously.
NOTE: RPi has two UARTs. A fully functional UART and a second one called a "mini" UART with less capability. Prior to RPi 3, the full UART was available on GPIO pins 8 and 10. However, to support Bluetooth on the RPi 3, the full UART was moved from the GPIO to the Bluetooth chip and the mini UART was made available on GPIO pins 8 and 10.
It is possible to redirect the full UART to the GPIO, but requires configuration changes. For more detail about this topic, see Raspberry Pi's UART documentation.
Either UART uses GPIO pin 8 (BCM GPIO 14) for transmit and pin 10 (BCM GPIO 15) for receive.
UART data transmission speed is referred to as BAUD Rate and is set to 115,200 by default (BAUD rate is based on symbol transmission rate, but is similar to bit rate). Rates approaching 1 Mbps have been successful with the RPi.
As with any interface to the RPi GPIO, voltage must be considered. RPi pins operate at 3.3v while other devices may operate at 5v or even higher. Voltage level converters are required to interface the RPi to such devices.
So, which to choose - I2C, SPI, or UART?
Fortunately, the Raspberry Pi supports all three and implementation is relatively easy (Pi 3 UART notwithstanding). Some advantages / disadvantages to consider:
- An obvious first consideration is what is supported by device(s) planned. This may limit or even dictate your choice.
- Speed: UART is the slowest, with I2C faster and SPI as the fastest. If speed is not important, then any are good. Otherwise, align device speed requirement with solution.
- Number of devices required: UART - only two (RPi + 1 device); SPI - many, but beyond two devices (+ Pi) gets more complicated with the Pi due to required CS line for each device; I2C - up to 127 without undue complexity.
- Duplex: UART and SPI can be Full Duplex; I2C is only Half Duplex.
- Number of wires: UART uses 1 (one-way only) or 2 (bidirectional); I2C use 2 wires; SPI uses 4. (Plus a ground wire for all).
- Distance: none of these are long distance solutions - a few inches to a few meters depending on transmission speed, cable quality and external noise. Faster speeds will go shorter distances.
- Transmission confirmation: I2C is the only protocol among these three that ensures that the data sent was received by device. However, this can lead to a "locked" up state by one device under adverse conditions.
- UART - simple; not high speed; no clock needed; limited to one device connected to the Pi.
- I2C - faster than UART, but not as fast as SPI; easier to chain many devices; RPi drives the clock so no sync issues.
- SPI - fastest of the three; Pi drives the clock so no sync issues; practical limit to number of devices on the Pi.