I2C vs SPI vs UART on PCB: Layout Routing Best Practices
I2C, SPI, and UART are the three most common communication protocols used to connect microcontrollers to sensors, displays, memory, and peripheral ICs. While their operation is thoroughly documented in software terms, their PCB layout requirements are less frequently discussed — and layout mistakes can cause communication failures that look like firmware bugs. Getting the routing right prevents hours of debugging.
This guide covers the key PCB layout differences between I2C, SPI, and UART, with specific routing rules, trace length recommendations, pull-up resistor placement, and signal integrity considerations for each protocol.
Protocol Overview: I2C, SPI, UART
I2C (Inter-Integrated Circuit)
Two wires: SDA (data) and SCL (clock). Multi-master capable, up to 127 devices on one bus with addresses. Open-drain bus — requires pull-up resistors on both lines. Speeds: 100 kHz (Standard), 400 kHz (Fast), 1 MHz (Fast Plus), 3.4 MHz (High Speed). Used for: sensors (BME280, MPU-6050, SHT31), EEPROMs, I/O expanders, RTC modules, ADCs.
SPI (Serial Peripheral Interface)
Four wires minimum: MOSI, MISO, SCLK, CS. Full-duplex, push-pull (no pull-ups needed). Separate CS line per device (or daisy chain). Speeds: 1-80 MHz typical (protocol-limited by device). Used for: Flash memory, SD cards, ADCs/DACs, OLED/LCD displays, RF modules, IMU sensors in high-speed mode.
UART (Universal Asynchronous Receiver Transmitter)
Two wires: TX and RX (plus optional RTS/CTS for flow control). Point-to-point, no shared bus. Asynchronous — no clock line. Speeds: 9600 to 921600 bps typical (up to 3+ Mbps in some cases). Used for: GPS modules, Bluetooth modules, debug ports, WiFi modules (AT commands), inter-board communication.
Common PCB Trace Basics
What Makes a Communication Trace “Good”?
- Continuous reference plane beneath the trace (return current path)
- No unnecessary stubs or branches
- Proper trace width for signal impedance
- Minimal vias in the critical signal path
- Separation from high-frequency noise sources (oscillators, switchers, RF)
Trace Width for Communication Lines
For I2C, SPI, and UART signals at typical speeds (below 50 MHz), the primary concern is avoiding antenna behavior and crosstalk rather than impedance control. Use a minimum trace width of 0.15-0.25mm. For high-speed SPI above 20 MHz or over long traces (above 50mm), use controlled impedance (50 ohm microstrip — approximately 0.2-0.3mm width depending on stackup).
I2C PCB Layout
Why I2C Layout Matters
I2C uses open-drain signaling: the SDA and SCL lines are normally pulled high by external resistors. Devices pull the line low to communicate — they never drive high. This means:
- Line capacitance directly limits maximum speed — every picofarad added by trace length or vias extends the rise time
- Rise time is set by the RC time constant: t_rise = 0.8473 * R_pullup * C_bus
- I2C 400 kHz requires rise time below 300ns; 1 MHz requires below 120ns
I2C Layout Rules
- Minimize trace length: Each cm of trace adds approximately 1-2 pF of capacitance. Keep the I2C bus traces as short as possible. For boards with multiple I2C devices, place them close to each other and to the master controller.
- Avoid stubs: Route the bus in a daisy-chain topology from device to device. Do not use star topology (one trace from master with branches to each device) — branches create stubs with reflections above 400 kHz.
- Keep SDA and SCL together: Route them as a parallel pair, spaced 3-5x trace width apart. They are immune to crosstalk between each other (both are I2C signals), and routing them together simplifies the layout and shortens trace length.
- Avoid routing near switchers: Keep I2C traces away from switching power supplies, crystal oscillators, and PWM lines. Noise coupling on SDA can cause bit errors that are very hard to debug.
- Pull-up resistors near the master: Place pull-up resistors close to the master device (not at the end of the bus). This ensures the shortest pull-up path and minimizes bus capacitance.
I2C Trace Length Limits (Rule of Thumb)
| I2C Speed | Max Bus Capacitance | Approx Max Trace Length (PCB) |
|---|---|---|
| 100 kHz | 400 pF | ~200mm |
| 400 kHz | 400 pF | ~200mm (limited by rise time, R dependent) |
| 1 MHz | 400 pF | ~100mm max practical |
SPI PCB Layout
SPI Signal Types and Routing
SPI has four signal types with different layout requirements:
- SCLK: Clock line. Must reach all devices with minimal skew. Route first in multi-device SPI. Keep trace lengths equal between master and each device.
- MOSI: Master output, slave input. Source-terminated (optional 33-47 ohm series resistor at the master output).
- MISO: Master input, slave output. Potentially weakest signal (long return path). Route on a low-noise layer.
- CS (Chip Select): One per device. Relatively low speed (toggles once per transaction). Less layout-critical than SCLK/MOSI/MISO.
SPI Layout Rules
- Match trace lengths for high-speed SPI: For SPI above 10 MHz or traces over 50mm, match MOSI and MISO lengths within 5mm of the SCLK trace length to minimize setup/hold time violations.
- Add series resistors at source: Place 33-47 ohm series resistors at the master output pins (on MOSI, SCLK) within 5mm of the pin. This damps ringing on fast-edge signals without slowing the data rate.
- Short stub on MISO: The MISO line is especially sensitive to ringing (the slave drives back to master). Keep MISO trace as short as practical.
- Ground reference: Ensure the SPI signal traces run over a continuous ground plane. Never route SPI signals across a plane gap.
- Keep SPI bus traces parallel and close: Routing MOSI, MISO, SCLK as a tight bundle (with ground trace between them if crosstalk is a concern) looks clean and minimizes layout area.
- CS lines are more flexible: CS lines can be longer and less tightly routed than the data lines.
SPI Length Matching for Flash Memory and SD Cards
For SPI at 20-40 MHz (SD card, Flash memory), keep all SPI traces under 50mm. Match MOSI/MISO/SCLK to within 3-5mm. Add 22-33 ohm series termination on SCLK and MOSI. Place a 100nF decoupling capacitor on the VCC of the Flash/SD card IC, within 1mm of the pin.
UART PCB Layout
UART is the Most Forgiving
UART’s asynchronous nature and moderate speeds (up to ~1 Mbps typical) make it the most layout-tolerant of the three protocols. The main requirements are:
- No crosstalk from high-frequency sources that could be interpreted as extra start bits or framing errors
- No excessive cable length without level conversion (RS-232 for long runs, or RS-485 for very long multi-drop)
UART Layout Rules
- Keep TX and RX together: Route TX and RX as a pair on the same layer, parallel, with 3x trace width spacing. This is more for neatness than electrical necessity at UART speeds.
- Separate from clock and power traces: UART lines near crystal oscillators or switching regulators pick up noise that corrupts data. Maintain 5mm separation.
- Level shifting near the controller: If UART must cross from 3.3V domain to 5V (Arduino to 3.3V module), place the level shifter IC close to the MCU, with short traces on both sides.
- External connector ESD protection: Any UART line that exits the PCB to external connectors or cables needs TVS diodes or ESD protection ICs near the connector. UART TX/RX pins are often directly connected to the MCU and are vulnerable to ESD.
- RS-232 for long lines: For UART over cables longer than 1-2m, use RS-232 level conversion (MAX232, SP3232) or RS-485 conversion (MAX485). RS-232 extends to 15m; RS-485 to 1200m.
Pull-Up Resistors: Placement and Values
I2C Pull-Up Placement
Place I2C pull-up resistors within 10-15mm of the master device (usually the MCU). The resistor should connect to the same VCC rail that powers the I2C devices. Resistor value selection:
I2C Pull-up Value Formula:
R_min = (VCC - V_low_max) / I_sink_max = (3.3 - 0.4) / 3 mA = 967 ohm minimum
R_max = (tr) / (0.8473 * C_bus) = 300ns / (0.8473 * 100 pF) = 3535 ohm
Typical selections:
- 100 kHz, 100pF bus: 4.7 kohm
- 400 kHz, 100pF bus: 2.2 kohm
- 1 MHz, 50pF bus: 1 kohm
SPI Pull-Ups and Pull-Downs
SPI does not inherently require pull-ups (push-pull outputs). However:
- CS lines often need a pull-up resistor (10k) to ensure devices stay deselected during power-up (before the MCU initializes)
- MISO lines can be left floating when no device is selected — add a pull-up or pull-down to define the MISO state during CS deassert
- Place these resistors near the controlled device, not near the master
Decoupling for Communication Interfaces
Every IC that communicates via I2C, SPI, or UART needs proper power decoupling. Rules for digital interface ICs:
- 100nF (0402) decoupling capacitor on each VCC/VDD pin, within 1mm of the pin
- Bulk 10uF capacitor per IC cluster, within 10mm of the VCC/VDD pins
- The decoupling capacitor via connects directly to the power plane — keep via close to the capacitor pad (between capacitor and power plane, not between capacitor and IC)
- For high-speed SPI devices (Flash, SRAM): add a ferrite bead on the VCC trace between the main power plane and the device VCC pin. Use a 600-ohm ferrite (at 100 MHz) in series with the VCC. Place the 100nF capacitor between the ferrite bead output and the device VCC pin.
ESD Protection on External Lines
Any communication line that exits the PCB through a connector is vulnerable to ESD. One ESD event can destroy an MCU GPIO pin (typically rated 2kV HBM on most modern MCUs — lower than common ESD events from human touch at 15-30kV).
ESD Protection Components
- TVS diode arrays: PRTR5V0U2X (2-line), PRTR5V0U4X (4-line), ESD5Z3.3 — small SOT-363 or SOD-323 packages. Place within 3mm of the connector, on the shield ground side of the signal path.
- ESD protection ICs: USBLC6-2SC6 for USB, TPD4E1B06 for general-purpose I/O. These have integrated back-to-back Zener configuration optimized for specific interfaces.
- Routing rule: The ESD protection component must be between the external connector and the MCU pin — never on the MCU side of the protection component.
Layer Routing Strategy
2-Layer Board
Route all signals on the top layer. Use bottom layer as ground fill (poured copper, GND net). Keep communication signal traces short and away from noisy components (oscillators, switchers). Via parasitic effects are less significant at I2C/SPI speeds on 2-layer boards.
4-Layer Board (Recommended for Multi-Interface Designs)
Layer assignment: Top = signal + components, L2 = solid ground plane, L3 = power planes, Bottom = signal. Route communication signals on both Top and Bottom, using L2 as a reference plane. Keep high-speed SPI traces on the top layer (direct reference from L2). Route I2C and UART on either layer.
Development Boards for I2C, SPI, and UART Projects
Test your communication interface designs with these development boards:
- Arduino UNO R3 — Full I2C, SPI, and UART interfaces for prototyping before custom PCB design
- Waveshare ESP32-S3 Nano — ESP32-S3 with multiple I2C, SPI, and UART peripherals in a compact form factor
- Waveshare RS485 Relay Module — UART to RS485 for industrial communication interface testing
KiCad Routing Tips for Communication Lines
- Net classes for signal groups: Create net classes for I2C, SPI, UART groups in KiCad. Assign minimum trace width (0.15-0.2mm) and clearance (0.15mm) to each class. This applies design rules consistently across all traces in each group.
- Route bus signals together: Use KiCad’s interactive router to route MOSI/MISO/SCLK together in one pass — the router maintains equal spacing.
- Length matching for SPI: After routing, use Route > Tune Single Track Length to add meanders on shorter traces to match SCLK trace length.
- Via placement check: Inspect Signal Integrity: vias in the I2C/SPI path add capacitance (~0.5 pF each) and inductance (~1 nH each). Minimize vias in SPI high-speed paths.
- Teardrops on pads: Add teardrops (Edit > Cleanup Graphics > Add Teardrops) to the pads on I2C and SPI traces. This prevents trace-to-pad necking which can cause trace breakage during board flex.
Frequently Asked Questions
Does I2C need controlled impedance traces?
No, not in the typical use case. I2C’s open-drain nature means the rise time is dominated by the RC time constant of pull-up resistor and bus capacitance, not transmission line effects. Standard trace widths (0.15-0.25mm) are fine for I2C traces under 200mm in length. Controlled impedance only matters for I2C when operating above 1 MHz (Fast Plus or High Speed mode) with very long traces on multi-layer boards.
How do I reduce SPI communication errors from PCB noise?
Common SPI noise solutions: (1) Add 22-33 ohm series termination resistors on SCLK and MOSI close to the master output pins to damp ringing. (2) Add decoupling capacitors (100nF) on all IC VCC pins. (3) Ensure continuous ground plane under all SPI traces. (4) Increase SPI clock divider in firmware to slow the clock — slower edges are more robust over noisy traces. (5) If using long cables, add a pull-down on MISO to prevent floating.
What causes I2C clock stretching issues on PCB?
Clock stretching problems on PCB usually trace to: excessive bus capacitance from long traces (reduces rise time), too-high pull-up resistance (also increases rise time), and multiple devices with different pull-up voltage requirements on the same bus. Check actual rise time on an oscilloscope — I2C 400kHz requires SCL rise time under 300ns. If rise time is excessive, lower the pull-up resistance or reduce bus length.
Can I2C and SPI share traces on a PCB?
No. I2C and SPI are separate protocols with incompatible signaling levels and timing. They cannot share physical traces. They share the same MCU power supply and ground plane, but signal traces are always separate. Some MCUs allow remapping I2C and SPI to share physical pins (multiplexed), but only one protocol can be active at a time, and this is a software configuration — the PCB traces are dedicated to whichever protocol uses each pin.
How long can UART lines be on a PCB without RS-232 conversion?
CMOS/TTL UART (3.3V or 5V) signals can reliably drive PCB traces up to approximately 100-300mm without issues. Beyond this, signal reflections and capacitive loading can cause framing errors at higher baud rates. For off-board connections (via connector to external cables), use RS-232 (up to 15m), RS-485 (up to 1200m), or a UART isolation buffer. The transition from PCB trace to cable is the critical point — add ESD protection and proper termination at the connector.
Shop Development Boards and Cables
Find Arduino boards, ESP32 modules, cables, and connectors for I2C, SPI, and UART projects at Zbotic.
Add comment