Communications
Wired and wireless communication protocols: SPI, I2C, UART, CAN, and more.
1 subtopic · 17 pages
Digital communication protocols are the language that microcontrollers, sensors, displays, memory, and other ICs use to exchange data. Choosing the right protocol — and implementing it correctly — determines how fast data moves, how many devices can share a bus, and how reliably communication works in a noisy environment.
What Are Embedded Communication Protocols?
The communications topic covers the wired serial protocols used in embedded electronics:
- SPI (Serial Peripheral Interface) — a synchronous, full-duplex, multi-master-capable 4-wire protocol. Fast (typically 10–80 MHz) with simple hardware but limited to short-distance connections and requiring a separate chip-select for each peripheral.
- I2C (Inter-Integrated Circuit) — a synchronous, half-duplex, multi-master 2-wire protocol with 7-bit or 10-bit device addressing. Slower than SPI (typically 100 kHz, 400 kHz, 1 MHz) but able to connect many devices on two wires with no separate chip-selects.
- UART (Universal Asynchronous Receiver/Transmitter) — an asynchronous point-to-point 2-wire protocol with configurable baud rate. The simplest protocol to implement; used for console output, GPS modules, Bluetooth serial, and legacy serial peripherals.
For wireless protocols (Bluetooth, Wi-Fi, LoRa, Zigbee), see the RF topic and Wireless topic.
Why Protocol Selection Matters
The wrong protocol choice for a given sensor or peripheral creates problems that persist through the product's life:
- Speed — an SPI ADC sampling at 1 MSPS cannot be driven over I2C at 400 kHz; the data cannot be transferred fast enough.
- Bus loading — I2C bus capacitance limits the number of devices and the maximum trace length. At 400 kHz, I2C bus capacitance should typically be kept below 400 pF.
- Noise immunity — UART over long cables picks up noise; use RS-232 level converters or RS-485 differential signalling for longer runs.
- Address conflicts — I2C devices have fixed addresses; connecting two identical sensors to the same I2C bus may be impossible without hardware address-select pins.
Key Concepts
- Synchronous vs asynchronous — SPI and I2C use a shared clock line; the transmitter and receiver operate in lock-step. UART is asynchronous: transmitter and receiver each have their own clock; baud rate must match at both ends.
- Full-duplex vs half-duplex — SPI is full-duplex (data can move in both directions simultaneously). I2C is half-duplex (data flows in one direction at a time on the shared bus). UART is full-duplex (TX and RX are independent lines).
- Pull-up resistors — I2C uses open-drain output drivers; the bus lines must be pulled to VCC through resistors. The pull-up value affects bus speed and capacitance loading; typical values are 1 kΩ to 10 kΩ.
- Baud rate — the signalling rate of a UART, measured in bits per second. Transmitter and receiver must be configured to the same baud rate or communication will fail (or produce garbage data).
- ACK/NAK — I2C uses an acknowledge bit from the receiver after each byte. A NAK (no acknowledge) indicates the device did not respond; a common debugging symptom when a device is not present, is at the wrong address, or is in an error state.
- Chip select (CS) — SPI uses a separate active-low CS line per peripheral to select which device the master is communicating with. Multiple peripherals share MISO, MOSI, and SCLK; only the selected device drives MISO.
Related Technologies
- RS-232 — a single-ended serial standard (±12 V levels) used for PC-to-device communication and legacy instruments. UART with an RS-232 level converter (MAX232 or similar) provides RS-232 compatibility from a 3.3 V MCU.
- RS-485 — a differential, multi-drop serial bus capable of long cable runs (up to ~1200 m typically) and multi-point communication. Often used with a UART peripheral and a differential line driver IC (MAX485 or similar). The physical layer for Modbus RTU.
- CAN (Controller Area Network) — a differential, multi-master serial bus designed for robust communication in electrically noisy environments (originally developed for automotive). Suitable for longer runs and environments where RS-485 is marginal.
- USB — a point-to-point host/device protocol for high-speed PC-to-device communication and power delivery. More complex to implement in firmware than SPI/I2C/UART but provides higher throughput and native PC connectivity.
Common Mistakes
- Missing or wrong-value I2C pull-up resistors — I2C uses open-drain drivers; the bus lines must be pulled to VCC through resistors. Pull-up values that are too high cause slow rise times (device misses clock edges at high speeds); too low causes excessive current draw and potential drive strength violations. Typical values: 4.7 kΩ at 100 kHz, 2.2 kΩ at 400 kHz, check bus capacitance for Fast-mode Plus.
- Incorrect SPI clock polarity (CPOL) or clock phase (CPHA) — SPI has four clock modes (0–3) defined by CPOL and CPHA. Mismatching the firmware clock mode to the device's expected mode produces garbled or inverted data that can look like correct data at first glance. Always verify CPOL/CPHA against the sensor or peripheral datasheet before debugging at higher levels.
- I2C address conflicts — I2C devices have fixed 7-bit addresses, and many sensors share common addresses. Two identical devices on the same bus is often impossible without an address-select pin. Check device addresses at schematic review time, not after assembly.
- Relying on SPI or I2C for long-distance connections — both protocols are designed for short PCB traces (a few tens of centimetres typically). For inter-board communication over cable, use RS-485 differential signalling or CAN instead of running SPI or I2C between connectors.
- UART baud rate mismatch — UART is asynchronous; both devices must be configured to exactly the same baud rate, data bits, stop bits, and parity. A mismatch produces garbage data. When connecting to a device with an unknown baud rate, scan common rates (9600, 115200, 230400) rather than guessing.
Common Questions
How do I choose between SPI and I2C for a sensor?
If the sensor is available only with SPI or only with I2C, the choice is made for you. If both are available: choose SPI for high-speed sensors (IMUs, ADCs, high-rate data logging) or when minimum latency matters; choose I2C when you need to connect many different sensors on two wires without individual chip-selects. I2C simplifies wiring for low-speed sensor clusters; SPI is faster and more reliable over longer PCB traces.
Why is my I2C device not responding (address scanner returns no devices)?
Common causes: missing or wrong-value pull-up resistors on SDA and SCL; incorrect I2C address in firmware (verify against the datasheet and the address-select pin state); device not powered or powered from the wrong voltage (some I2C sensors are 3.3 V only and will not work at 5 V); SDA and SCL lines swapped; bus capacitance too high (long traces, many devices) causing slow rise times that violate setup time; firmware clock speed configured incorrectly. See the forum discussion I2C scanner no devices found for a debugging walkthrough.
What is the maximum length of an I2C or SPI bus?
Neither I2C nor SPI specifies a maximum cable length — they are both limited by bus capacitance and propagation delay. I2C at 400 kHz is typically limited to a few tens of centimetres on a PCB; SPI at 10 MHz or higher is limited to similarly short traces. For longer connections (between boards or across a chassis), consider using I2C over a buffered bus (PCA9517 style repeater), SPI with a lower clock frequency and carefully controlled impedance, or a more robust protocol (RS-485, CAN, or a differential LVDS link). Zeus Design implements firmware for all common embedded communication protocols.
Knowledge Base
Protocol Fundamentals
- What Is SPI (Serial Peripheral Interface)? — SPI bus operation, CPOL/CPHA clock modes, multi-slave wiring, and full-duplex data transfer
- What Is I2C (Inter-Integrated Circuit)? — I2C addressing, start/stop conditions, pull-up requirements, and multi-master arbitration
- What Is UART? — async serial framing (start bit, data bits, stop bit, parity), baud rate configuration, and RS-232/RS-485 variants
Protocol Comparison and Selection
- SPI vs I2C vs UART: Which Protocol Should You Use? — side-by-side comparison of all three protocols: speed, wiring, device count, and application fit
Differential and Multi-Drop Bus Protocols
- What Is CAN Bus? — differential multi-master bus, bit-level arbitration, CAN FD, automotive and industrial applications
- What Is RS-485? — differential multi-drop bus for long cable runs, half-duplex operation, fail-safe biasing, and Modbus RTU
- What Is RS-232? — EIA-232 single-ended serial standard, ±12 V levels, DB9 connector, and level converter ICs
Industrial Application Layer Protocols
- What Is Modbus? — Modbus RTU over RS-485: master/slave register model (coils, holding registers), function codes, CRC frame structure, inter-frame gap timing, and Modbus TCP/IP
Audio and Display Interfaces
- What Is I2S (Inter-IC Sound)? — three-wire synchronous audio bus, BCLK/LRCK/SD signals, master/slave roles, and DMA streaming
- What Is MIPI DSI? — high-speed differential display interface, D-PHY lanes, HS/LP modes, DCS command set, and embedded display integration
High-Speed and System Interconnect
- What Is USB? — host-device topology, descriptor hierarchy, USB classes (CDC-ACM, HID, DFU), Full Speed vs High Speed, and power delivery
- What Is Ethernet? — MAC/PHY split, RMII interface, TCP/IP stack selection, and PCB layout for embedded Ethernet
Software Protocol Implementation
- What Is Bit Banging? — implementing serial protocols in software via GPIO, timing constraints, and when to prefer hardware peripherals
Subtopics
Forum Discussions
STM32F401 UART printing garbage after switching to 84 MHz PLL — same 115200 baud in CubeMX and PuTTY
Got a WeAct Black Pill (STM32F401CCU6) project that's been running happily on the default HSI clock at 16 MHz. Using USART1 on PA9/PA10 thro
SPI reads all returning 0xFF — logic analyser shows MISO activity, W25Q32 not responding to commands
Been staring at this one for a day and a half. I'm trying to read the JEDEC ID from a W25Q32JV SPI flash chip on a custom STM32L432 board. T
I2C bus scan finding nothing — NACK on every address despite pull-ups
Working through my first proper I2C project — hooking up a BME280 temp/humidity sensor to an ESP32 devkit. Wired SDA to GPIO21 and SCL to GP
STM32 USB not detected by Windows after jumping to bootloader mode
Working on a custom STM32F411 board, trying to jump into the built-in USB DFU bootloader from application code instead of holding BOOT0 on p