Choose I2C when you need many low-speed chips sharing two wires, SPI when you need bandwidth for a display, memory, or high-rate sensor, and UART when you are talking to one module over a simple point-to-point link — especially a cellular modem, GPS receiver, or debug console. All three move digital data between a microcontroller and its peripherals. They differ in how many wires they burn, how fast they run, how far they reach, and how gracefully they fail. Getting the choice right early keeps a board from being respun.
UART: the simplest link there is
UART is asynchronous serial. Two data lines — transmit and receive — plus a shared ground. There is no clock line; both ends must be configured for the same baud rate and agree on framing. That is the whole protocol.
- Strengths: trivially simple, one peripheral per port, works over long distances when paired with a line driver, and every debug tool on earth speaks it.
- Weaknesses: point-to-point only. Two devices per UART, no addressing, no arbitration. Each additional module wants another pair of pins.
- Typical use: GPS modules, cellular and satellite modems, serial consoles, barcode scanners, communication between two microcontrollers on the same board.
When a UART link has to leave the enclosure, it usually stops being plain UART. RS-485 and RS-232 transceivers wrap the same framing in a differential or higher-voltage physical layer that survives cable runs and electrical noise.
I2C: many parts, two wires
I2C is a synchronous two-wire bus — clock and data, both open-drain with pull-up resistors. Every device on the bus has an address, so dozens of chips can share the same two pins.
- Strengths: outstanding pin efficiency, easy to expand late in a design, and standard across sensor catalogs. Adding a temperature sensor to a board that already has I2C usually costs two solder pads and nothing else.
- Weaknesses: modest throughput, meaningful protocol overhead per transaction, and address collisions between parts from the same family. Bus capacitance limits total trace length, and a single misbehaving device can hold the bus and stall everything on it.
- Typical use: temperature, humidity, pressure, and ambient light sensors, accelerometers polled at low rates, EEPROMs, real-time clocks, small OLED displays, power-management ICs, and fuel gauges.
Two practical traps. First, pull-up resistor values are a real design decision — too high and edges get sluggish at speed, too low and devices cannot pull the line down cleanly. Second, plan an address map before you commit to parts; several popular sensors ship with fixed addresses and no strap pin.
SPI: when you need bandwidth
SPI is synchronous, full-duplex, and push-pull rather than open-drain. It uses clock, data-out, data-in, and one chip-select line per device. There is no addressing scheme — you select a device by asserting its own select pin.
- Strengths: by far the fastest of the three, simple hardware, full duplex, no addressing to negotiate, and no bus-hang failure mode.
- Weaknesses: pin hungry. Every extra device costs another GPIO for chip select, and short traces only — SPI does not travel well.
- Typical use: TFT and e-paper displays, external flash and SD cards, sub-GHz and Wi-Fi radio modules, high-rate IMUs, ADCs and DACs, and anything streaming a continuous sample flow.
Quick decision table
- One external module, off the board, cable involved? UART with an appropriate transceiver.
- Six low-rate sensors, tight pin budget? I2C.
- A display, external flash, or a sensor sampled hundreds or thousands of times per second? SPI.
- Mixed needs? All three, on the same microcontroller. This is normal, not a compromise — a typical connected product runs a display on SPI, environmental sensors on I2C, and a modem on UART.
- Signals leaving the enclosure between boards? Neither raw I2C nor raw SPI. Use a differential bus like RS-485 or CAN, or move the interface behind a local microcontroller.
What about long wiring and electrically noisy environments?
This is where board-level buses stop being the right answer. I2C and SPI were designed to travel inches, not feet. In industrial equipment, vehicles, and anything with motors nearby, use CAN or RS-485: both are differential, both tolerate ground offsets, and both are designed for multi-drop wiring over real distances. Trying to stretch I2C across a machine produces intermittent faults that are miserable to debug in the field, and motor drive electronics only make it worse — see our notes on motor selection for where that noise comes from.
What the choice means at the product level
Bus selection is not a purely software question. It constrains your pin count, and therefore your microcontroller choice — the same tradeoff we cover in how to choose a microcontroller and in the ESP32 vs STM32 comparison. It affects layout, trace length, and layer count, which shows up directly in PCB prototype cost. And it shapes driver work, which is a real line item in firmware development cost.
A useful habit: budget one spare I2C address range and one spare chip-select pin on the first board revision. Requirements grow, and adding one more sensor to a design that already has room is far cheaper than a respin.
Larger platform decisions interact with this too. A design running embedded Linux instead of a bare microcontroller gets kernel drivers for most of these buses for free but adds boot time and power draw. If bus and protocol terminology is new to you, start with what firmware actually is, then explore our wider embedded software guide.
Not sure which buses your board needs, or whether your sensor list fits the microcontroller you picked? Send us your requirements through the contact form and we will map the interfaces before layout starts.