%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D'}}}%%
graph TB
subgraph I2C["I2C (Inter-Integrated Circuit)"]
I2C_Props["2 wires: SDA, SCL<br/>Multi-master capable<br/>Speed: 100kHz-3.4MHz<br/>Max devices: 127"]
I2C_Use["Use for:<br/>- Multiple sensors<br/>- Short distances<br/>- Moderate speed<br/>- Simple wiring"]
end
subgraph SPI["SPI (Serial Peripheral Interface)"]
SPI_Props["4+ wires: MOSI, MISO,<br/>SCK, CS (per device)<br/>Full-duplex<br/>Speed: 10-100+ MHz<br/>Point-to-point"]
SPI_Use["Use for:<br/>- High-speed data<br/>- Displays/Flash<br/>- Real-time ADC<br/>- Low latency"]
end
subgraph UART["UART (Universal Async RX/TX)"]
UART_Props["2 wires: TX, RX<br/>Asynchronous<br/>Speed: 9600-921600 baud<br/>Point-to-point"]
UART_Use["Use for:<br/>- GPS modules<br/>- Bluetooth/Wi-Fi<br/>- Debug console<br/>- Simple comms"]
end
style I2C fill:#16A085,stroke:#2C3E50,color:#fff
style SPI fill:#E67E22,stroke:#2C3E50,color:#fff
style UART fill:#2C3E50,stroke:#16A085,color:#fff
style I2C_Props fill:#16A085,stroke:#2C3E50,color:#fff
style I2C_Use fill:#16A085,stroke:#2C3E50,color:#fff
style SPI_Props fill:#E67E22,stroke:#2C3E50,color:#fff
style SPI_Use fill:#E67E22,stroke:#2C3E50,color:#fff
style UART_Props fill:#2C3E50,stroke:#16A085,color:#fff
style UART_Use fill:#2C3E50,stroke:#16A085,color:#fff
198 Serial Communication Protocols
198.1 Learning Objectives
By the end of this chapter, you will be able to:
- Compare Serial Protocols: Evaluate I2C, SPI, and UART for different sensor integration scenarios
- Apply Protocol Selection Criteria: Use pin count, speed, and distance factors to choose appropriate interfaces
- Implement Multi-Sensor Systems: Design reliable bus architectures for connecting multiple sensors
- Debug Protocol Issues: Identify and resolve common serial communication problems
198.2 Prerequisites
Before diving into this chapter, you should be familiar with:
- Hardware Platform Selection: Understanding microcontroller and SBC capabilities helps you match serial protocols to available hardware interfaces
- Communication and Protocol Bridging: Knowledge of higher-level protocol concepts provides context for understanding low-level serial interfaces
Enhance your learning by exploring related resources:
- Simulations Hub: Try interactive tools for protocol comparison and signal timing analysis
- Hands-On Labs Hub: Practice I2C and SPI communication with ESP32 simulations
- Knowledge Gaps Hub: Clarify common misconceptions about serial protocol trade-offs
Think of serial communication like sending a message through a tube - one letter at a time. Different protocols are like different types of tubes with different rules.
Everyday Analogy: Imagine three ways to pass notes in class:
- I2C is like passing notes through a single row with seat numbers - many people can share one path, but you need to call out who the note is for
- SPI is like having a private messenger for each friend - faster delivery, but you need more messengers
- UART is like two tin cans connected by string - simple, works over longer distances, but only connects two people
| Term | Simple Explanation |
|---|---|
| I2C (I-squared-C) | A two-wire bus where many devices share the same wires, using addresses to know who’s talking |
| SPI | A four-wire system that’s very fast, with a dedicated “select” wire for each device |
| UART | The simplest two-wire connection between just two devices, like a phone call |
| Bus | A shared communication path, like a road many cars can use |
| Pull-up Resistor | A component that keeps I2C wires at the correct voltage when not actively being used |
Why This Matters for IoT: Your temperature sensor uses I2C (2 wires, simple). Your display uses SPI (fast updates). Your GPS module uses UART (comes with built-in protocol). Understanding these helps you wire things correctly and debug problems when sensors don’t respond.
The Mistake: Connecting multiple I2C sensors assuming they will “just work,” then experiencing intermittent data corruption, missed readings, or bus lockups in deployment.
Why It Happens: I2C address conflicts, bus capacitance exceeding limits with long wires, clock stretching incompatibilities between sensors, and missing pull-up resistors all manifest as intermittent failures that rarely appear during bench testing with short jumper wires.
The Fix: Map all I2C addresses before wiring - use a bus scanner script first. Calculate total bus capacitance (each sensor + wire length × 100pF/m) and keep under 400pF for 100kHz I2C. Use appropriate pull-up resistors (2.2k-4.7k for 3.3V systems). Add I2C bus recovery code (clock pulse sequence) for stuck-bus conditions. Consider I2C multiplexers (TCA9548A) for address conflicts. For long runs (>30cm), switch to RS-485 or CAN bus instead.
In one sentence: Choose I2C for multiple low-speed sensors (2 wires, 127 devices), SPI for high-speed peripherals like displays and flash (fastest, more pins), and UART for GPS/Bluetooth modules (simplest, point-to-point).
Remember this: I2C = many sensors, few wires. SPI = fast data, more wires. UART = simple modules, two wires.
198.3 Serial Protocol Comparison
198.4 Protocol Selection Matrix
This variant presents I2C, SPI, and UART selection as a multi-criteria decision matrix, helping engineers systematically evaluate trade-offs.
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D', 'fontSize': '11px'}}}%%
graph TB
subgraph Matrix["PROTOCOL SELECTION CRITERIA"]
direction TB
subgraph I2C_Box["I2C"]
I2C_Score["Pins: 2 *****<br/>Speed: 400K **<br/>Devices: 127 *****<br/>Distance: 1m **<br/>Complexity: ***"]
I2C_Use["USE: Multiple sensors<br/>temp, humidity, IMU"]
end
subgraph SPI_Box["SPI"]
SPI_Score["Pins: 4+n **<br/>Speed: 80M *****<br/>Devices: CS pins ***<br/>Distance: 3m ***<br/>Complexity: ****"]
SPI_Use["USE: High-speed<br/>flash, display, ADC"]
end
subgraph UART_Box["UART"]
UART_Score["Pins: 2 *****<br/>Speed: 1M ***<br/>Devices: 1 *<br/>Distance: 15m *****<br/>Complexity: *****"]
UART_Use["USE: Debug, GPS<br/>Bluetooth modules"]
end
end
I2C_Box --> Decision{Your Priority?}
SPI_Box --> Decision
UART_Box --> Decision
Decision -->|"Many sensors"| I2C_Win["Choose I2C"]
Decision -->|"High throughput"| SPI_Win["Choose SPI"]
Decision -->|"Long cable/debug"| UART_Win["Choose UART"]
style I2C_Box fill:#16A085,stroke:#2C3E50,color:#fff
style SPI_Box fill:#E67E22,stroke:#2C3E50,color:#fff
style UART_Box fill:#2C3E50,stroke:#16A085,color:#fff
style I2C_Win fill:#16A085,stroke:#2C3E50,color:#fff
style SPI_Win fill:#E67E22,stroke:#2C3E50,color:#fff
style UART_Win fill:#2C3E50,stroke:#16A085,color:#fff
198.5 Protocol Technical Details
198.5.1 I2C (Inter-Integrated Circuit)
I2C uses a shared bus architecture with just two wires:
| Property | Value |
|---|---|
| Wires | 2 (SDA data, SCL clock) |
| Speed | Standard 100kHz, Fast 400kHz, Fast+ 1MHz, High-speed 3.4MHz |
| Addressing | 7-bit (127 devices) or 10-bit (1024 devices) |
| Distance | 1-3 meters typical (capacitance limited) |
| Pull-ups | Required (2.2k-10k depending on bus speed) |
Best for: Multiple sensors, EEPROMs, RTCs, small displays, low pin count
Common I2C Addresses: - BME280 (temp/humidity): 0x76 or 0x77 - SSD1306 OLED: 0x3C or 0x3D - MPU6050 IMU: 0x68 or 0x69 - DS3231 RTC: 0x68
198.5.2 SPI (Serial Peripheral Interface)
SPI uses a master-slave architecture with dedicated select lines:
| Property | Value |
|---|---|
| Wires | 4 minimum (MOSI, MISO, SCK, CS per device) |
| Speed | 1-100+ MHz (device dependent) |
| Topology | Master-slave, one CS per slave |
| Duplex | Full-duplex (simultaneous read/write) |
| Distance | 1-3 meters (signal integrity limited) |
Best for: Flash memory, SD cards, displays, ADCs, high-speed sensors
198.5.3 UART (Universal Asynchronous Receiver/Transmitter)
UART provides simple point-to-point asynchronous communication:
| Property | Value |
|---|---|
| Wires | 2 (TX, RX) + ground |
| Speed | 9600-921600 baud typical |
| Topology | Point-to-point only |
| Distance | 15+ meters (with RS-232/RS-485) |
| Handshaking | Optional (RTS/CTS) |
Best for: GPS modules, Bluetooth/Wi-Fi modules, debug console, legacy devices
198.6 Hands-On Lab: I2C vs SPI Protocol Selection
Objective: Understand trade-offs between I2C and SPI protocols.
Scenario: Design a weather station with: - 1x Temperature/Humidity sensor - 1x Barometric pressure sensor - 1x Real-time clock (RTC) - 1x EEPROM for data logging - 1x Flash memory (4MB) for firmware updates
Tasks:
- Design two versions:
- Version A: All devices on I2C bus
- Version B: Sensors on I2C, Flash on SPI
- Calculate for each version:
- Total pin count required
- Maximum theoretical data throughput
- Firmware complexity (protocol handling)
- Simulate I2C bus:
- Create I2C devices for all sensors
- Scan bus and verify addressing
- Read from all devices
- Calculate total transaction time
- Simulate SPI version:
- Create SPI flash device
- Simulate firmware read (1KB)
- Compare speed with I2C EEPROM
Expected Results: - I2C version: Simpler wiring, lower pin count, adequate for sensor data rates - SPI version: Faster firmware updates, slightly more complex
198.7 Hands-On Lab: ADC Resolution Determination
Objective: Calculate required ADC resolution for various sensors.
Scenario: Design precision sensors for:
- Medical thermometer: 35-42°C range, 0.1°C accuracy
- Sensor: TMP117 (10mV/°C)
- ADC reference: 3.3V
- Industrial pressure sensor: 0-100 PSI, 0.5 PSI accuracy
- Sensor: 0.5-4.5V output for 0-100 PSI
- ADC reference: 5.0V
- pH sensor: pH 0-14, 0.01 pH accuracy
- Sensor: 414mV per pH unit
- ADC reference: 3.3V
Tasks:
For each sensor, calculate:
- Required voltage resolution
- Required ADC bits
- Actual achievable resolution with standard ADC (10-bit, 12-bit, 16-bit)
Select minimum ADC resolution for each application
Calculate total system cost with different ADC options:
- 10-bit ADC: $3
- 12-bit ADC: $5
- 16-bit ADC: $12
Determine if a single high-resolution ADC can serve all sensors or if multiple ADCs are needed
Deliverables: - ADC requirement table for each sensor - Cost-benefit analysis - Recommendation for ADC configuration
198.8 Knowledge Check
198.9 Summary
This chapter explored serial communication protocols for IoT sensor integration:
- I2C: A two-wire bus protocol supporting up to 127 devices on shared SDA/SCL lines. Ideal for multiple low-speed sensors (temperature, humidity, IMU) with minimal wiring. Requires pull-up resistors and has distance limitations (~1m).
- SPI: A high-speed four-wire protocol with dedicated chip-select per device. Best for flash memory, displays, and high-bandwidth peripherals. Faster than I2C but requires more GPIO pins.
- UART: Simple asynchronous two-wire point-to-point communication. Standard interface for GPS modules, Bluetooth/Wi-Fi modules, and debug consoles. Works over longer distances but connects only two devices.
- Protocol Selection: Match protocol to requirements - I2C for sensor clusters, SPI for high-speed peripherals, UART for module interfaces. Consider pin count, speed, distance, and device count.
- Common Pitfalls: I2C address conflicts, bus capacitance limits, missing pull-ups, and clock stretching issues can cause intermittent failures that are hard to debug in deployment.
Deep Dives: - Communication and Protocol Bridging - Higher-level protocol concepts - Sensor Fundamentals - ADC and sensor interfaces - Prototyping Hardware - Development board interfaces
Comparisons: - Hardware Platform Selection - MCU interface availability
198.10 What’s Next
Having covered serial communication protocols, the next chapter examines Development Workflow and Tooling, exploring IDEs, debugging techniques, CI/CD pipelines, and Over-The-Air (OTA) update strategies for professional IoT development.