Digital Communication
How chips talk to each other: UART, I²C, SPI and 1-Wire.
The question
Your thermometer probe sends temperatures to the Pico over a single data wire. How does it do that without the messages getting jumbled?
What you’ll discover: how digital devices send data one bit at a time, and how the common connections, UART, I²C, SPI and 1-Wire, compare.
In simple terms
BeginnerOne bit at a time
Inside a project, chips constantly exchange data: a sensor sends readings, a display receives text. Most of the time they use serial communication: sending bits one after another along a wire, as a pattern of high and low voltages, using rules both sides agree on. Those rules are a protocol.
Two big questions every protocol answers: how do both sides agree on the timing of each bit, and how does a message reach the right device when several share the wires?
The common four
| Protocol | Wires (plus ground) | How it works |
|---|---|---|
| UART | 2: TX and RX | Each side transmits on its TX and listens on RX, so TX connects to the other device’s RX. Both agree on a speed in advance, the baud rate, such as 9,600 or 115,200 bits per second. |
| I²C | 2: SDA (data) and SCL (clock) | A controller sends a clock and each device has its own address, so many sensors can share two wires. Needs pull-up resistors. Common speeds are 100 kHz and 400 kHz. |
| SPI | 3 shared, plus a chip-select per device | A clock, data out and data in, with a separate chip-select line to pick each device. Fast and simple, but uses more pins. |
| 1-Wire | 1: data (with a pull-up) | Timing-based signalling on a single wire, with a unique 64-bit address in every device. Used by the DS18B20 in the Digital Thermometer. |
Go deeper
IntermediateUsing them on a Pico
The Pico has two UARTs, two I²C controllers and two SPI controllers, which can be assigned to several different pins. In MicroPython, scanning an I²C bus lists the addresses of every device it finds:
from machine import Pin, I2C
i2c = I2C(0, sda=Pin(4), scl=Pin(5)) # GP4 = SDA, GP5 = SCL
print([hex(a) for a in i2c.scan()])
An empty list usually means a wiring problem or missing pull-up resistors (many sensor boards include them). Two devices with the same address can’t share one bus without help.
AdvancedSignal integrity
I²C and SPI were designed for short connections on a circuit board, typically centimetres, not metres. Long wires add capacitance, which rounds off the sharp edges of the signal, and pick up interference. Symptoms are intermittent errors that come and go with temperature or movement.
For longer runs, slow the bus down, use stronger pull-ups (within the devices’ limits), keep data and ground wires together, or choose a protocol designed for distance, such as RS-485, which uses a pair of twisted wires to cancel out interference. Always add error checking: the DS18B20, for example, sends a CRC check value with each reading so the receiver can tell a corrupted reading from a good one.
Quick check
In a UART connection, what does TX connect to?
The other device’s RX.
How can many I²C devices share the same two wires?
Each device has its own address.
Why are I²C and SPI not ideal for long wires?
Long wires add capacitance and pick up interference, corrupting the signal.
Words to know
- Protocol
- The agreed rules for communication.
- Baud rate
- The speed of a serial connection, in bits per second.
- Address
- A number that identifies one device on a shared bus.
- CRC
- A check value used to detect corrupted data.
Learn more
- MicroPython: Raspberry Pi Pico quick reference: official, including the DS18B20 sensor
- Next: Circuit board design
Electronics School is part of the Discovery Zone. Every activity here runs on small batteries or a USB cable: never wall outlets. The one plug-in tool is the optional soldering iron, set up by an adult.