MyRoboPathOpen Robotics Lab
Embedded Systems & Networking16 min readUpdated 2026-03-30All Levels

Communication Protocols in Robotics: UART, I2C, SPI, CAN & Ethernet

The Architectural Guide to Inter-Chip Buses, Differential Industrial Signaling, and Real-Time Sensor Networks

MyRoboPath Hardware Engineering Lab
Embedded Systems & Robotics Core Team
Communication Protocols in Robotics: UART, I2C, SPI, CAN & Ethernet
SPI Bandwidth
10 - 80 Mbps
Highest throughput inter-chip synchronous bus
CAN Bus Range
Up to 1000 m
Differential noise immunity at industrial voltages
I2C Pin Count
2 Wires (SDA/SCL)
Multi-device addressing with minimal PCB traces
Ethernet Throughput
100M - 10 Gbps
Massive bandwidth for 3D LiDAR & real-time video

Core Engineering Takeaways

  • •Single-ended protocols (UART, I2C, SPI) share ground reference and suffer severe electromagnetic interference beyond 30cm to 1 meter.
  • •Differential protocols (RS-485, CAN bus, Ethernet) measure the voltage difference between two complementary wires (D+/D- or CAN_H/CAN_L), eliminating common-mode motor noise.
  • •I2C requires pull-up resistors sized according to total bus capacitance; too high results in slow edge rise times, while too low overloads the open-drain drivers.
  • •SPI offers the highest inter-chip bandwidth (10-50+ Mbps) and full-duplex communication, but demands a dedicated Chip Select (CS) line per slave device.
  • •CAN bus employs non-destructive bitwise arbitration based on message priority (identifier), guaranteeing that high-priority emergency messages are never blocked or corrupted.
  • •Modern robots adopt a hybrid hierarchy: SPI/I2C on-board PCB, CAN bus for motor drives and chassis nodes, and Ethernet for high-bandwidth LiDAR/RGB-D cameras.
Prerequisites
  • Basic understanding of digital logic levels (0V logic LOW, 3.3V/5V logic HIGH)
  • Familiarity with microcontroller pins and basic serial communication

1. Why Robots Need Multi-Tier Communication Architectures

A complete mobile robot or robotic arm is a distributed computing system. Inside a single chassis, you will find:

  • Low-rate environmental sensors (IMUs, temperature probes, ambient light detectors)
  • High-frequency motor controllers updating PID velocity loops at 1 kHz
  • Safety emergency stops and limit switches requiring guaranteed sub-millisecond response
  • High-data-rate perception sensors (3D LiDARs, depth cameras, stereo vision) streaming tens of megabytes per second.

No single protocol solves all of these needs simultaneously. If you try to stream video over I2C, the bus saturates instantly. If you run raw SPI across a 2-meter robotic arm alongside high-current motor cables, electromagnetic noise will corrupt your packets and reset your microcontrollers.

Robotics engineers solve this by designing a multi-tiered communication hierarchy:

  1. 1
    On-Board Inter-Chip Tier (SPI, I2C): Confined to a single PCB or shielded short cables (< 20 cm) for IMUs, flash memory, and ADCs.
  2. 2
    Deterministic Control Tier (CAN Bus, RS-485): Differential twisted pairs traversing the noisy chassis to communicate with motor drives, battery management systems (BMS), and arm joints.
  3. 3
    High-Bandwidth Perception Tier (Ethernet / USB 3.0): Linking SBCs, depth cameras, LiDARs, and ROS 2 compute clusters.

2. UART & RS-485: Point-to-Point and Differential Long-Distance Serial

UART (Universal Asynchronous Receiver-Transmitter)

UART is an asynchronous, full-duplex, point-to-point protocol. "Asynchronous" means there is no shared clock line; instead, both transmitter (TX) and receiver (RX) must agree in advance on a precise baud rate (e.g., 9600, 115200, 921600 bps).

Data is transmitted in standard byte frames:

  • 1 Start Bit (Logic LOW): Alerts the receiver that a byte is starting.
  • 5 to 9 Data Bits: Typically 8 bits (Least Significant Bit first).
  • Optional Parity Bit: Simple error checking (Even/Odd/None).
  • 1 or 2 Stop Bits (Logic HIGH): Allows the line to return to idle.

Because UART is single-ended (referencing 0V GND), electrical noise from PWM motor switching easily couples into the wire. Over distances greater than 1 meter, high baud rates experience bit corruption.

Upgrading to RS-485 for Rugged Robotics

To send UART data across several meters in an industrial or agricultural robot, engineers pass the UART signals through an RS-485 transceiver (such as the MAX485 or SN65HVD72). RS-485 converts single-ended TX/RX signals into differential signals (A and B lines):

  • VA−VB>+200 mV→Logic 1 (Mark)V_A - V_B > +200\text{ mV} → \text{Logic 1 (Mark)}
  • VA−VB<−200 mV→Logic 0 (Space)V_A - V_B < -200\text{ mV} → \text{Logic 0 (Space)}

Because external electromagnetic noise induces identical voltages on both tightly twisted wires (common-mode noise), the receiver's differential amplifier cancels it completely out. RS-485 supports daisy-chaining up to 32 (or 128) transceivers over distances up to 1,200 meters.

rs485_motor_driver.cpp
cpp
// HardwareSerial RS-485 Half-Duplex Control
#include <Arduino.h>

#define RS485_DE_RE_PIN 4  // Transmit Enable (HIGH = TX, LOW = RX)
#define MOTOR_NODE_ID   0x02

void setup() {
  pinMode(RS485_DE_RE_PIN, OUTPUT);
  digitalWrite(RS485_DE_RE_PIN, LOW); // Start in Receive Mode
  
  Serial1.begin(115200, SERIAL_8N1, 16, 17); // ESP32 RX=16, TX=17
}

void sendMotorVelocity(uint8_t nodeId, int16_t rpm) {
  uint8_t packet[6];
  packet[0] = 0xAA;                  // Sync header
  packet[1] = nodeId;                // Target node
  packet[2] = (rpm >> 8) & 0xFF;     // Velocity MSB
  packet[3] = rpm & 0xFF;            // Velocity LSB
  packet[4] = packet[1] ^ packet[2] ^ packet[3]; // Checksum
  packet[5] = 0x55;                  // Footer

  // Enable RS-485 Transmitter
  digitalWrite(RS485_DE_RE_PIN, HIGH);
  delayMicroseconds(5); // Stabilize transceiver
  
  Serial1.write(packet, sizeof(packet));
  Serial1.flush(); // Wait until final bit leaves hardware buffer
  
  // Return to listening mode
  digitalWrite(RS485_DE_RE_PIN, LOW);
}

Note: RS-485 transceivers require toggling the DE/RE pin to switch between transmitting and receiving. Calling Serial.flush() ensures the last stop bit is physically transmitted before releasing the bus.

3. I2C: Two-Wire Inter-Integrated Circuit Bus & Pull-Up Physics

How I2C Works

I2C (Inter-Integrated Circuit) uses only two bidirectional lines:

  1. 1
    SDA (Serial Data)
  2. 2
    SCL (Serial Clock)

I2C is a synchronous master-slave (controller-target) architecture. The master drives the clock line, eliminating baud rate drift. Up to 127 devices can share the exact same two wires using unique 7-bit hardware addresses.

Open-Drain / Open-Collector Drivers

Unlike push-pull outputs that drive pins high to VCC, I2C pins use open-drain MOSFETs. An I2C node can only pull a line down to GND (Logic 0) or release it to float. To achieve Logic 1, the bus relies on external pull-up resistors (RpR_p) connected to 3.3V or 5V.

This open-drain architecture prevents electrical short circuits when multiple nodes communicate, and allows features like Clock Stretching (where a slow sensor holds SCL LOW until its ADC finishes converting).

Pull-Up Resistor Sizing Formula

Every device and PCB trace added to an I2C bus introduces parasitic capacitance (CbC_b). When an open-drain transistor turns off, the line voltage rises exponentially according to the RCRC time constant: τ=Rp⋅Cb\tau = R_p \cdot C_b. If RpR_p is too large, the signal edges become rounded and the clock cannot reach Logic 1 threshold within the timing spec. If RpR_p is too small, devices cannot pull the line down below VILV_{IL} (0.3 ⋅\cdot VCC), drawing excessive current.

Maximum I2C Pull-Up Resistor Sizing

Rp(max)=tr0.8473⋅CbR_{p(max)} = \frac{t_r}{0.8473 \cdot C_b}
In Simple Words: The maximum allowable pull-up resistance is directly proportional to maximum allowable rise time (tr) and inversely proportional to total bus capacitance (Cb).
Variables Breakdown:
trt_r
Maximum allowed rise time (1000 ns for Standard 100kHz, 300 ns for Fast Mode 400kHz)Unit: seconds
CbC_b
Total bus parasitic capacitance (traces + pins + cables, max 400 pF)Unit: Farads
Rp(max)R_{p(max)}
Maximum allowable pull-up resistor valueUnit: Ohms
Worked Example:

For Fast Mode (tr = 300 ns) with Cb = 150 pF: Rp(max) = 300e-9 / (0.8473 * 150e-12) ≈ 2,360 Ω (use standard 2.2 kΩ).

I2C Bus Lockup Bug (9 Clock Recovery)

If a microcontroller resets while a slave sensor is pulling SDA LOW during a data byte, the slave waits forever for clock pulses that never come, freezing the entire bus. Firmware must detect this condition at startup and manually toggle SCL 9 times to clock out the stuck byte and send an I2C STOP condition.

4. SPI: Serial Peripheral Interface for High-Throughput Peripherals

High-Speed Synchronous Master-Slave

When an application requires continuous streaming data—such as reading a 16-bit IMU gyro at 4 kHz, writing to a microSD flight data logger, or updating an OLED status screen—I2C is too slow.

SPI (Serial Peripheral Interface) is a 4-wire, full-duplex, push-pull protocol capable of speeds from 10 MHz to 80+ MHz:

  • SCLK (Serial Clock): Generated by the master.
  • MOSI / SDO (Master Out, Slave In): Data from master to target.
  • MISO / SDI (Master In, Slave Out): Data from target to master.
  • CS / SS (Chip Select / Slave Select): Dedicated active-LOW line per device.

Because SPI uses active push-pull transistors rather than passive pull-up resistors, signal rise times are measured in single-digit nanoseconds.

Clock Polarity (CPOL) and Phase (CPHA)

SPI defines four operational modes depending on clock idle state and sampling edges:

  • Mode 0 (CPOL=0, CPHA=0): Clock idles LOW; data sampled on rising edge. (Most common in robotics)
  • Mode 1 (CPOL=0, CPHA=1): Clock idles LOW; data sampled on falling edge.
  • Mode 2 (CPOL=1, CPHA=0): Clock idles HIGH; data sampled on falling edge.
  • Mode 3 (CPOL=1, CPHA=1): Clock idles HIGH; data sampled on rising edge.

The Wiring Trade-Off

The disadvantage of SPI is pin scalability. While I2C supports 100 devices on 2 pins, SPI requires an additional GPIO pin for every slave device. If your robot has 6 smart joint sensors, you need 3 shared bus wires (SCLK, MOSI, MISO) plus 6 discrete CS lines (9 total wires).

5. CAN Bus: The Gold Standard for Noisy, Mission-Critical Actuators

Why Automotive and Industrial Robotics Rely on CAN

Originally created by Bosch for automotive networks, CAN (Controller Area Network) is the most robust serial bus for mobile robots, quadrupeds, autonomous vehicles, and robotic arms.

Key features that make CAN unmatched in robotics:

  1. 1
    Differential Physical Layer: Operates across two twisted wires: CAN_H (High) and CAN_L (Low).
  • Recessive State (Logic 1): Both lines sit at 2.5V (ΔV=0V\Delta V = 0\text{V}).
  • Dominant State (Logic 0): CAN_H drives to 3.5V, CAN_L drops to 1.5V (ΔV=2.0V\Delta V = 2.0\text{V}).
  1. 2
    Termination Resistors: Both extreme ends of the bus must be terminated with a 120 Ω\Omega resistor across CAN_H and CAN_L, creating a net 60 Ω\Omega transmission line impedance that prevents signal reflections.
  2. 3
    Non-Destructive Bitwise Arbitration: Unlike Ethernet where colliding packets are destroyed and retransmitted, CAN uses message identifiers for priority arbitration. If two motor nodes transmit at the same microsecond, the node with the lower numerical ID (dominant zeros) automatically wins the bus without losing a single clock cycle of data.
  3. 4
    Hardware CRC & Error Confinement: Faulty nodes that continuously broadcast bad packets automatically disconnect themselves from the bus (*Bus-Off state*), preventing one damaged sensor from crippling the robot.
can_motor_packet.cpp
cpp
// CAN Bus 2.0B Motor Torque Command Frame
#include <ESP32-TWAI-CAN.hpp>

// Standard 11-bit CAN Identifier (Lower value = higher priority)
#define CAN_ID_EMERGENCY_STOP 0x001  // Highest priority
#define CAN_ID_MOTOR_LEFT_CMD 0x100
#define CAN_ID_MOTOR_RIGHT_CMD 0x101

void sendTorqueCommand(uint32_t canId, float currentAmps) {
  CanFrame frame = { 0 };
  frame.identifier = canId;
  frame.extd = 0;              // Standard 11-bit ID
  frame.rtr = 0;               // Data frame (not remote request)
  frame.data_length_code = 4;  // 4 bytes payload

  // Convert float to fixed-point int32 (milliamps)
  int32_t current_mA = (int32_t)(currentAmps * 1000.0f);
  frame.data[0] = (current_mA >> 24) & 0xFF;
  frame.data[1] = (current_mA >> 16) & 0xFF;
  frame.data[2] = (current_mA >> 8) & 0xFF;
  frame.data[3] = current_mA & 0xFF;

  // Send with 10ms timeout
  ESP32Can.writeFrame(frame, 10);
}

6. Ethernet & ROS 2 DDS: High-Bandwidth Perception and Telemetry

Moving Beyond Kilobits: The Perception Backbone

When integrating 2D/3D LiDARs (Velodyne, Ouster, Hesai), stereo cameras (Intel RealSense, Stereolabs ZED), or distributed SBCs (Raspberry Pi 5 + NVIDIA Jetson Orin), data rates explode into hundreds of megabits per second. CAN bus (1 Mbps) and SPI cannot handle this volume.

Standard 100BASE-TX (Fast Ethernet) or 1000BASE-T (Gigabit Ethernet) provides:

  • Galvanic Isolation: Magnetics in Ethernet jacks isolate nodes from ground bounce up to 1,500V.
  • Deterministic Switches: Dedicated industrial Ethernet switches route packets simultaneously between multiple sensors without bus contention.
  • ROS 2 DDS (Data Distribution Service): The native publish-subscribe middleware used in ROS 2. DDS operates over standard UDP/IP with fine-grained Quality of Service (QoS) configurations (e.g., Best-Effort for high-rate sensor streams vs Reliable for navigation goal commands).

7. Engineering Selection Matrix: Choosing the Right Protocol

Use the comprehensive engineering matrix below to evaluate trade-offs in speed, wiring simplicity, distance, and noise tolerance across your robot's subsystems.

Table 1: Robotics Communication Protocol Engineering Comparison Matrix
ProtocolMax SpeedMax Cable LengthTopologyWiresNoise ImmunityTypical Robotics Use Case
UART (TTL)115.2 kbps - 3 Mbps< 1 meterPoint-to-point (1-to-1)2 (TX, RX) + GNDLow (Single-ended)GPS NMEA stream, Bluetooth modules, MCU debug console
RS-48510 Mbps - 50 Mbps1,200 metersMulti-drop bus (Daisy chain)2 (A, B) + ShieldVery High (Differential)Smart robotic servos (Dynamixel), industrial PLCs, agricultural chassis
I2C100 kbps - 3.4 Mbps< 30 cmMulti-master / multi-slave2 (SDA, SCL) + GNDLow (Open-drain, EMI sensitive)On-board IMUs (MPU6050, BNO055), EEPROMs, OLED displays
SPI10 Mbps - 80 Mbps< 15 cmMaster / multi-slave3 + N (CS pins) + GNDMedium (Push-pull, fast edges)High-speed IMU gyro sampling, SD card black-box logger, LCD screens
CAN Bus (2.0B)1 Mbps40 m (at 1M), 1000 m (at 50k)Terminated linear bus2 (CAN_H, CAN_L) + GNDHighest (Bit arbitration, CRC, fault containment)Chassis brushless motor drives, ODrive, BMS battery telemetry, joint actuators
Ethernet (100/1000)100 Mbps - 1 Gbps100 metersStar topology (via Switch)4 or 8 (CAT5e / CAT6)Very High (Transformer isolated)3D LiDAR point clouds, ROS 2 inter-SBC communication, video streaming
Frequently Asked Questions

Common Questions & Troubleshooting

Q:Can I connect a 3.3V microcontroller directly to a 5V I2C sensor?

Not directly without a bidirectional level shifter. Because I2C uses pull-up resistors to the bus voltage, pulling up to 5V will inject 5V into the 3.3V MCU’s I/O protection diodes, permanently damaging the microcontroller. Use an inexpensive BSS138 MOSFET-based bidirectional level shifter.

Q:Why does my CAN bus stop working when I remove the 120-ohm resistor?

At high frequencies (1 Mbps), wire traces behave as transmission lines. High-speed electrical transitions reflect back from unterminated cable ends like waves hitting a concrete wall, colliding with forward signals and corrupting bits. The 120-ohm resistors match the characteristic impedance of the twisted pair, absorbing the energy completely.

Q:When should I choose CAN Bus over RS-485?

Choose CAN bus when you have multiple nodes requiring collision-free priority arbitration, automatic error retransmission, and hardware fault isolation (e.g., motor controllers and battery systems). Choose RS-485 when you need higher raw throughput (up to 50 Mbps) for simple master-slave query-response protocols over long distances.