RisalDash RisalDash
Wired microcontroller interfaces

One byte, six ways to send it

The data is always the same: 0x4A. The difference between buses is how many wires you need, who sets the clock, how the receiver knows where a byte begins, and how far it can travel. Below is the same byte on six buses. Change the bits in the panel at the bottom — every waveform redraws.

One byte, six buses0x4A
start here

Why do chips even need to talk to each other?

Inside almost any device — a smartwatch, a kettle, a car — sits a microcontroller, a little boss-brain. Around it are the "staff": a temperature sensor, a display, a flash chip, a Wi-Fi module. The boss has to collect their data and hand out commands. The question is exactly how they talk.

You could run a separate bundle of wires to each one — fast, but the board instantly turns into spaghetti. Or you run one or two shared wires that everyone takes turns speaking on, following a set of rules. Those wire-talking rules are what we call serial buses: "serial" because the bits travel down the wire one after another, not all at once.

The rest of this article covers the six most common of these "languages". They all do the same job (move bytes around), but differently — and each is tuned for its own kind of task.

One job — its own bus

Push an image to a colour display

SPI — you need serious speed, the wires are short and cheap.

Hang a dozen small sensors on a board

I²C — just two wires for all of them; speed is not critical, sparing pins is.

Link nodes under a car's hood

CAN — sparks, noise and vibration all around — it has to be bulletproof.

Dump debug text to a computer

UART — the simplest two-wire cable, works with almost anything, no setup.

String thermometers around a house

1-Wire — one wire for every sensor over tens of metres; speed does not matter.

Talk to an industrial box or a server console

RS-232 — an old reliable standard: big voltages carry the cable for metres.

A glossary in plain words

Byte

The smallest useful chunk of data — a number from 0 to 255. One character, one pixel colour, one sensor reading. Eight bits (zeros and ones) in a row.

Clock

A conductor with a metronome: it ticks "one-two-three", and on each tick devices send exactly one bit. With a clock (SPI, I²C) they run in sync; without one (UART) both sides agree on the exact tempo in advance.

Pull-up

An ordinary resistor that ties a wire to "plus" so it does not float in the air and pick up noise like an antenna when nobody is transmitting.

Controller and peripheral

The controller (master) starts the conversation and sets the pace; the peripheral (slave) answers when addressed. Some buses have a single controller, others treat everyone as equals.

00

Four questions that tell every bus apart

QUESTION 1

Who sets the clock?

A dedicated clock line means the bus is synchronous (SPI, I²C): the receiver need not know the frequency in advance. No such line means it is asynchronous (UART, RS-232, 1-Wire): the speed must be agreed beforehand, and both sides have to hold it precisely.

QUESTION 2

How do you find the start of a byte?

By a service bit (the UART start bit), by a chip-select edge (CS on SPI), by a deliberate rule violation (START on I²C — SDA falls while SCL is high), or by a long reset pulse (1-Wire).

QUESTION 3

How many devices on the line?

Two (UART, RS-232), one controller and many peripherals selected by a separate line (SPI) or by address (I²C, 1-Wire), or all equal and contending for the bus (CAN).

QUESTION 4

How is the level read?

Single-ended relative to a common ground — simple, but it picks up noise (UART, SPI, I²C). Differential — from the difference of two wires in a twisted pair, so noise hits both and cancels out (CAN, RS-485). That is what buys tens of metres instead of centimetres.

Asynchronous: data only
No clock. The receiver catches the falling edge of the start bit, waits half a bit, then samples in the middle of every bit interval, timing it with its own counter. Let the frequencies drift more than ≈2–3 % and the byte falls apart.
Synchronous: data + clock
The controller itself says "read now" with a clock edge. The speed can be anything and may even wander — the receiver still lands on the bit. The price is an extra wire.
01 / asynchronous · point-to-point

UART

Universal Asynchronous Receiver / Transmitter

Two data wires, no clock. Both sides agree on the speed in advance (115200), and the byte is wrapped in a frame: a start bit, eight data bits least significant first, a stop bit. At rest the line is high — so a falling level is the "attention, here it comes".

WiresTX, RX, GND
Clocknone, by agreement
Duplexfull
Devices2
Speed9600 … 115200 bit/s
up to 1–3 Mbit/s
Reachup to ~1 m at TTL levels
Waveform of an 8N1 frame 0x4A
The least significant bit goes first, so on screen the byte reads "backwards" relative to the 0b notation. The 8N1 frame = 8 data bits, No parity, 1 stop bit: every 8 useful bits costs 10 bit intervals, that is 20 % of the traffic — overhead.
Wiring diagram
The one trick: the TX of one goes to the RX of the other, the lines cross over. And a common ground is mandatory — without it there is simply no "zero".
How it works
  1. The line rests at 1. The receiver waits for a falling edge.
  2. The transmitter pulls the line down for one bit interval — that is the start bit. The receiver starts its timer.
  3. Then come 8 data bits, least significant first. The receiver reads the level in the middle of each interval (usually with 16× oversampling, to avoid catching an edge).
  4. If needed — a parity bit: a single-error check.
  5. The stop bit returns the line to 1. If the line is low at that moment, the receiver reports a framing error: most likely the baud rate did not match.
Strengths
  • Two wires, full duplex, built into every microcontroller.
  • No controller or peripheral — anyone can talk, anytime.
  • Easy to debug: plug in a USB adapter and read text in a terminal.
  • Works over anything: RS-232, RS-485, fibre, radio.
Limitations
  • Exactly two participants, no addressing.
  • Needs a precise clock source: an internal RC oscillator often cannot hold 115200.
  • Error checking — a parity bit at most.
  • 20 % of the bandwidth goes to start and stop.
  • Knows nothing about delivery: it sends into the void and never finds out.

Where you meet it: the debug console of any board, GSM/GPS/Wi-Fi modules with AT commands, receipt printers, barcode scanners, the "microcontroller ↔ Linux board" link, firmware bootloaders.

02 / synchronous · star

SPI

Serial Peripheral Interface

The fastest and most straightforward bus: the controller toggles the clock line, and on every clock two shift registers swap bits — one out and one back, at the same time. No addresses, no acknowledgements: you talk to whichever device you selected with the CS line.

WiresSCK, MOSI, MISO,
CS (one per peripheral)
Clockfrom the controller
Duplexfull
Devices1 controller + N peripherals
Speed10 … 100 MHz
Reachcentimetres, one board
Byte exchange, mode 0 (CPOL=0, CPHA=0) 0x4A
While the controller sends its byte on MOSI, the peripheral sends its own on MISO in the same clocks — here inverted for the example. The arrows mark the sampling moment: in mode 0 the data is set on the falling edge and read on the rising edge. The most significant bit goes first.
Wiring diagram
SCK, MOSI and MISO are shared by everyone, but you need as many CS lines as there are peripherals — and each one takes a pin on the controller. That is the main price you pay for speed.
How it works
  1. The controller pulls the CS of the chosen peripheral low — the others disable their outputs and stay out of the way.
  2. The controller issues 8 clocks on SCK. Each clock = one bit in each direction.
  3. On one edge the data is set, on the opposite one it is read. Which is which is decided by CPOL and CPHA, hence modes 0…3.
  4. Bytes run back to back with no service bits: however many clocks you give is however many bits you transfer. The bandwidth is used at 100 %.
  5. The controller raises CS — the transaction is closed and the peripheral resets its internal state machine.
Strengths
  • Tens of megabits: the only option for displays, SD cards and flash.
  • Full duplex and zero overhead.
  • The simplest hardware — it can be built from shift registers.
  • A transfer of any length: it need not be a whole number of bytes.
Limitations
  • Wires: 3 + one CS per device.
  • A single controller, no arbitration.
  • No acknowledgement: the controller never learns that a peripheral died or was never soldered on.
  • No standard on top: every chip has its own command set and its own mode.
  • Only within a board — long cables "ring".

Where you meet it: SD cards, TFT and e-Ink displays, NOR flash chips (including QSPI, from which the firmware boots), nRF24L01 and LoRa radio modules, fast ADCs, accelerometers in high-rate mode.

03 / synchronous · shared bus

I²C

Inter-Integrated Circuit · TWI

Two wires for the whole board. Devices can only pull the line to zero, and the pull-up resistors raise it back — so a bus conflict is physically impossible. Each device has a 7-bit address, and every byte sent is confirmed by an ACK bit.

WiresSDA, SCL, GND
+ 2 pull-ups
Clockfrom the controller, the peripheral
can slow it down
Duplexhalf
Devicesup to 112 addresses
Speed100 / 400 kHz,
1 MHz Fm+, 3.4 MHz HS
Reachtens of cm, limited by 400 pF capacitance
Writing a byte to device 0x3C 0x4A
The bus rule: SDA changes only while SCL is low. A change while SCL is high is a service symbol: a fall = START, a rise = STOP. The hatched ACK bit is pulled by the peripheral itself — that is how the controller learns it was heard. The logic here is inverted from what you would expect: 0 (line pulled) = ACK “got it”, 1 (line released) = NACK “nobody home” or “stop” — that is open-drain at work.
Wiring diagram
Two pull-ups for the whole bus (usually 4.7 kΩ at 100 kHz, 2.2 kΩ at 400 kHz) — not a pair per device. Everyone has "open drain" outputs: they have nothing to drive the line high.
How it works
  1. START: SDA falls while SCL is high. The bus is busy.
  2. The controller sends 7 address bits and a direction bit: 0 — write, 1 — read.
  3. The device with that address pulls SDA on the ninth clock — ACK. Silence on the ninth clock means "nobody home".
  4. Then come the data bytes, each with its own ACK. The receiver may answer NACK — "enough".
  5. Not keeping up? The peripheral holds SCL low — clock stretching, and the controller waits patiently.
  6. STOP: SDA rises while SCL is high. The bus is free.
Strengths
  • Two wires for dozens of devices — a huge saving in pins.
  • Addressing and receipt acknowledgement are built into the protocol.
  • You can scan the bus and learn what is actually connected to it.
  • Several controllers with fair arbitration.
Limitations
  • Orders of magnitude slower than SPI, half duplex.
  • Addresses clash: two identical sensors often cannot sit side by side.
  • Bus capacitance limits wire length and speed.
  • A hung peripheral can hold SDA low and kill the whole bus.
  • Overhead: an address and an ACK per byte.

Where you meet it: almost all sensors (BME280, MPU6050, VL53L0X), SSD1306 OLED displays, 24Cxx EEPROMs, real-time clocks, power-management chips, port expanders, the monitor EDID in an HDMI cable.

Hands-on: four I²C sensors compared on one bus →

04 / differential · all equal

CAN

Controller Area Network

A bus designed for a car, where a starter motor sparks nearby. A twisted pair, differential levels, 120 Ω at the ends. There are no controllers — there are messages with priority: it is not a node that is addressed but the meaning of the message itself, via an identifier, and every node decides for itself whether to listen.

WiresCAN_H, CAN_L (twisted pair)
+ 2×120 Ω
Clocknone, synchronised on edges
Duplexhalf
Devicesdozens of equals
Speed500 kbit/s typical,
up to 1 Mbit/s · CAN FD up to 8
Reach40 m at 1 Mbit/s,
500 m at 125 kbit/s
Differential pair: dominant beats recessive CAN_H / CAN_L
The recessive state — both lines around 2.5 V, difference ≈0 V, that is a logic 1. The dominant one — the lines spread apart by ±1 V, that is a logic 0. If one node sends 1 and another sends 0, the bus ends up at 0. The whole arbitration is built on this simple fact. An analogy: 0 is dominant (someone speaking out loud), 1 is recessive (everyone silent). You can talk over silence, not the other way around — so the node whose ID has earlier zeros wins arbitration without losing a single bit.
Frame structure · the same byte as the single data byte 0x4A
The payload is at most 8 bytes (64 in CAN FD), yet it carries 44+ service bits: priority, length, CRC-15, an acknowledgement from all listeners at once. This bus is not about volume but about reliability.
Wiring diagram
One trunk line with short stubs and mandatory 120 Ω terminators at the two ends — without them reflections break frames. The microcontroller does not reach the bus itself: a transceiver sits between them.
How it works
  1. A node waits for silence on the bus and begins the frame with a dominant SOF.
  2. It sends the identifier and listens to the bus at the same time. If it sees a 0 where it drove a 1, someone has higher priority: it quietly yields and tries again. Lower ID = higher priority, and the winner's bytes are untouched.
  3. Then come the length and 0–8 data bytes, followed by CRC-15.
  4. Everyone who received the frame without errors pulls the ACK bit. One shared bit for all listeners.
  5. Spotted an error — any node emits an error frame and tears the frame down for everyone. The transmitter retries automatically.
  6. A node that keeps failing takes itself off the bus by its error counters — bus off. A broken part will not drag the network down with it.
Strengths
  • Survives heavy noise and tens of metres.
  • Priorities and arbitration with no lost frame.
  • Error detection, automatic retry, self-isolation of a broken node.
  • Broadcasting: add a listener and the existing nodes need no changes.
  • Just two wires for the whole network.
Limitations
  • Needs a transceiver and a correct topology with terminators.
  • 8 bytes per frame — large blocks have to be chopped up.
  • Harder to learn and debug, you need an analyser.
  • Carries no meaning on its own: it needs a higher-level protocol — OBD-II, J1939, CANopen.
  • A low-priority message on a busy bus can wait a long time.

Where you meet it: all automotive electronics and diagnostics via OBD-II, trucks and agricultural machinery (J1939), industrial automation (CANopen), BLDC motor controllers, lifts, medical equipment, battery BMS.

05 / levels and connector · point-to-point

RS-232

EIA/TIA-232 · the "COM port"

A common confusion: RS-232 is not another UART. The frame is the same, the start and stop bits are the same. The standard describes the voltages and connector: here a logic one is −12 V and a zero is +12 V. Inversion plus a 24-volt swing: the signal survives both a long cable and interference that would kill TTL.

WiresTXD, RXD, GND
+ RTS/CTS, DTR/DSR
Levels1 = −5…−15 V
0 = +5…+15 V
Duplexfull
Devices2
Speed300 … 115200 bit/s
Reachup to 15 m
One frame in two worlds: TTL and RS-232 0x4A
On top, what comes out of the microcontroller; below, what goes into the cable after the MAX3232. The shape is identical, but inverted and stretched across zero. You cannot connect RS-232 straight to a microcontroller pin: −12 V would kill it.
The DE-9 connector and the level converter
The minimal working set is three wires: 2 RXD, 3 TXD, 5 GND. The rest are hardware flow control (RTS/CTS) and a modem legacy (DTR, DSR, DCD, RI). A cable between two equal devices crosses 2 and 3 and is called a null-modem cable.
What you need to know in practice
  1. Inside the device lives an ordinary UART. RS-232 begins after the level chip.
  2. MAX232 / MAX3232 make ±12 V from a single supply using charge pumps on four capacitors.
  3. The setup is described by a string like 115200 8N1 — speed, data bits, parity, stop bits. Get even one part wrong and the screen shows garbage.
  4. The ground is shared between both devices, and that is the weak spot: different ground potentials on a long cable drive a current through the "zero".
  5. Need hundreds of metres or many nodes — take the differential relatives: RS-422 and RS-485 (up to 1200 m, up to 32 nodes, Modbus lives on top of it). It is essentially the same UART frame, just sent over a twisted pair at differential levels like CAN — hence the reach and the noise immunity.
Strengths
  • A large voltage swing → noise immunity above TTL, metres instead of centimetres.
  • Full duplex, hardware flow control.
  • Absolute compatibility: the standard is over sixty years old.
  • Added to any UART with a single chip.
Limitations
  • Only two devices.
  • Single-ended levels relative to a common ground — a long way from RS-485.
  • A bulky connector, needs capacitors and a separate chip.
  • Gone from computers: it lives on through USB-UART adapters (CP2102, FT232, CH340).

Where you meet it: industrial controllers and CNC, laboratory instruments, UPS units, point-of-sale equipment, network switches and servers (the console port), diagnostics in railway and power-grid automation.

06 / asynchronous · single wire

1-Wire

Dallas / Maxim single-bus interface

The limit of thrift: a single data line with a pull-up — and the device can even draw power from it, storing energy in a capacitor while the line is free. No clock, no second wire: everything is encoded by the duration of a low pulse. Each device carries a unique 64-bit number, burned in at the factory.

WiresDQ + GND
(+ VCC optional)
Clocknone, only timings
Duplexhalf
Devicesmany, searched by ROM ID
Speed≈16 kbit/s,
overdrive ≈125
Reachtens of metres
Reset, presence and a byte written in time slots 0x4A
A one and a zero differ only in the length of the low pulse inside the slot: a short dip ≈6 µs is a 1, a long ≈60 µs is a 0. Hence the main difficulty: the driver lives on microsecond delays, and a stray interrupt in the middle of a slot corrupts the bit.
Wiring diagram and parasite power
A 4.7 kΩ pull-up — and all the sensors hang on that same line. In parasite-power mode a third wire is not needed at all: while the line is high, the device charges its internal capacitor.
How it works
  1. The controller holds the line low for ≥480 µs — a reset. Every device on the line restarts.
  2. The devices answer with their own dip for 60–240 µs — a presence pulse: "we are here".
  3. The controller sends a command in 60–120 µs slots. Then either Skip ROM, if there is one device, or Match ROM with the 64-bit number of a specific one.
  4. Several devices are found by the ROM search algorithm: a bit-by-bit walk of the address tree, with nodes filtered out in groups.
  5. When reading, the controller itself drops the line for 1–2 µs, releases it and checks the level: the peripheral holds it low — 0, released it — 1.
  6. The last byte of the device number is a CRC-8, so the connection is verified right away.
Strengths
  • One wire for everything, including power.
  • A unique factory ID: devices need no configuration and addresses never clash.
  • Tens of metres of ordinary twisted pair.
  • Many devices on one line — a garland of temperature sensors around the house.
Limitations
  • Very slow: a DS18B20 measurement takes up to 750 ms.
  • Hard microsecond timings, half duplex.
  • Almost no hardware support in microcontrollers — everything is done by hand.
  • A long line needs careful topology and sometimes an active pull-up.

Where you meet it: DS18B20 thermometers (smart home, incubators, server rooms), iButton keys and door entry systems, DS24xx EEPROMs, identification of batteries and cartridges, humidity sensors in greenhouses.

07

Everything on one screen

BusSignal linesClockDuplexDevicesAddressingSpeedReachLevels
UART 2nonefull2noneup to ~1 Mbit/s~1 msingle-ended, TTL
SPI 3 + N×CSSCK from controllerfull1 + Nby CS line10–100 MHzcmsingle-ended, TTL
I²C 2 + pull-upsSCL from controllerhalfup to 1127-bit address0.1–3.4 MHztens of cmopen drain
CAN 2 (twisted pair)none, on edgeshalfdozensmessage ID, priorityup to 1 Mbit/s40–500 mdifferential
RS-232 2 (+ flow)nonefull2noneup to 115200 bit/s15 m±5…15 V, inverted
1-Wire 1none, timingshalfmany64-bit ROM ID16–125 kbit/stens of mopen drain + pull-up

A useful addition to the table: RS-485 — the differential multi-point version of the serial port: the same UART frame, a twisted pair, up to 32 nodes and 1200 m, half duplex. Modbus RTU and almost all industrial peripherals run on it.

08

Which one to pick for the job

Two devices, a little data, you want it simple and immediate — and you would like to watch the traffic with your own eyes in a terminal.

UART

A display, an SD card, flash or an ADC on the same board: speed matters and the pins are there.

SPI

Five to ten small sensors and registers, little data, and hardly any free pins.

I²C

Metres of wire, vibration and noise, failure not allowed, many nodes and they are all equal.

CAN

To connect to an industrial instrument, a UPS or a server console port.

RS-232

A garland of thermometers along a long cable, speed does not matter, you want as few wires as possible.

1-Wire

Hundreds of metres, dozens of nodes, but CAN is overkill and you need to work with ready-made industrial devices.

RS-485 / Modbus
09

Where it usually breaks

UART

TX and RX not crossed

TX must go to RX. The second classic is a speed mismatch: instead of text you get steady garbage. And a common ground is mandatory.

SPI

Wrong mode or a forgotten CS

The data reads but shifted by a bit — almost always CPOL/CPHA mixed up. A floating CS drifts and opens the peripheral at a random moment: pull it up to the supply.

I²C

No pull-ups or clashing addresses

Without the resistors the bus is completely silent. Two identical sensors — an address clash, saved by an address-select pin or a TCA9548A multiplexer. Long wires add capacitance: lower the frequency.

CAN

No terminators or different speeds

120 Ω go on exactly the two physical ends of the trunk, not on every node. The bit rate must match to the bit across all nodes — otherwise the bus tips into an avalanche of errors.

RS-232

Direct connection to a pin

±12 V burns out the microcontroller input — you need a MAX3232. And check whether a null-modem cable is required: two "terminals" without the cross will not hear each other.

1-Wire

Eaten timings

An interrupt in the middle of a 60 µs slot corrupts the bit. On a long line add a stronger pull-up and check the CRC-8 of every reply before trusting the readings.

General

Different supply levels

5 V and 3.3 V do not get along directly: you need a divider, a level converter or a device with tolerant inputs. Check this before the protocol logic.

General

Debugging blind

A cheap logic analyser shows what you would otherwise guess at for hours: is there an ACK, where did an edge slip, is it the right address. Looking at the bus is far faster than guessing.

This explainer is by the team behind RisalDash, an open-source web-dashboard library for ESP32 / ESP8266.

Sending a byte
hex 0x4A dec 74 bin 01001010 ascii 'J'