Module 4/5 · Weeks 10–12 · 27 h

Serial interfaces and DroneCAN

UAT 204 Microcontrollers and Embedded Systems

About 80 minDraft, awaiting reviewLast updated 27 September 2026

Lesson

By the end of this module you will be able to

  1. Explain the 8N1 UART frame and calculate real throughput from baud rate
  2. Explain the I2C bus (addresses, pull-ups, speeds) and SPI (four CPOL/CPHA modes) and choose between them
  3. Explain CAN and DroneCAN and why they are used for multiple devices on a drone
  4. Design a simple data frame with a checksum and detect corrupted data

Prerequisites: UAT 204 modules 1–3

Why this matters

A flight controller talks to dozens of devices at once: the IMU sends thousands of readings a second over SPI, the compass and barometer use I2C, the GPS and telemetry radio use UART, and on larger drones the GPS, ESCs and power module share a single CAN bus. Choosing the wrong interface or speed makes data slow, lost or unanswered.

UART

A UART sends data one bit at a time on one wire per direction (TX crossed to RX), and both sides must use the same baud rate. Per Microchip TB3216, an 8N1 frame has one start bit, eight data bits and one stop bit, 10 bits per byte, so it carries baud/10 bytes per second.

A UART frame waveform. The line idles high; the start bit goes low, followed by data bits D0 to D7 of byte 0x41 sent least significant bit first, then a high stop bit. Below: 10 bits per byte, 8N1
Figure 1 An 8N1 UART frame

ArduPilot’s default baud rate is 57600 for telemetry ports and 230400 for the GPS port.

I2C and SPI

Under NXP’s I2C specification (UM10204 rev 7.0), the I2C bus uses two lines, SDA and SCL, which are open-drain and need pull-up resistors. Each device has a 7-bit address; standard speeds are 100 kbit/s (Standard-mode), 400 kbit/s (Fast-mode) and 1 Mbit/s (Fast-mode Plus). Many devices can share two wires, but it is slower than SPI.

SPI uses a clock (SCK), data lines MOSI and MISO, and a separate chip-select (CS) line for each device. It is much faster than I2C, so it is used for IMUs read frequently. Per Analog Devices, SPI has four modes set by clock polarity (CPOL) and the sampling edge (CPHA); both sides must use the same mode.

Three buses. I2C: an MCU and three devices at addresses 0x68, 0x76 and 0x1E share the SDA and SCL lines. SPI: an MCU and three devices share SCK, MOSI and MISO, with a separate CS line to each. CAN: a CANH and CANL pair with terminating resistors at both ends connects the FC, GPS and ESC
Figure 2 I2C, SPI and CAN buses

CAN and DroneCAN

CAN uses a CANH/CANL pair carrying a differential signal, so it resists noise and supports long runs. All devices connect to the same pair, with terminating resistors at both ends. The standard is ISO 11898-1 (latest edition 2024, which adds CAN XL). ArduPilot’s documentation says 1 Mbit/s is usually used, and CAN_P1_BITRATE defaults to 1,000,000.

DroneCAN is a protocol on CAN for unmanned aircraft, continuing UAVCAN v0. ArduPilot and PX4 support DroneCAN devices such as GPS units, compasses, ESCs and power modules. Advantages are less wiring and devices that report their own status.

Example 1 Real throughput

for label, baud in (("telemetry", 57_600), ("GPS", 230_400)):
    bytes_per_s = baud / 10                       # 8N1 = 10 bits per byte
    print(f"{label:<9} {baud:>7} baud -> {bytes_per_s:,.0f} bytes/s; a 40-byte message at 50 Hz uses "
          f"{40 * 50 / bytes_per_s:.0%} of the link")

bits = 9 * (1 + 1 + 1 + 6) + 2                    # address, register, repeated address, 6 data bytes + start/stop, approx.
for label, hz in (("I2C 100k", 100_000), ("I2C 400k", 400_000)):
    print(f"{label}: reading 6 bytes takes about {bits / hz * 1e6:.0f} µs")
telemetry   57600 baud -> 5,760 bytes/s; a 40-byte message at 50 Hz uses 35% of the link
GPS        230400 baud -> 23,040 bytes/s; a 40-byte message at 50 Hz uses 9% of the link
I2C 100k: reading 6 bytes takes about 830 µs
I2C 400k: reading 6 bytes takes about 208 µs

A 40-byte message 50 times a second uses about a third of a 57600 telemetry link, so adding other messages may exceed capacity. Reading 6 sensor bytes over I2C at 400 kHz takes about 0.2 ms, allowing hundreds of reads a second with few devices. The I2C bit count in the example is an approximation.

Detecting corruption with a checksum

Example 2 A simple frame with a checksum

Our sensor module sends a hypothetical frame: start byte 0xAA, length, data, and an XOR checksum of the length and data bytes.

def make_frame(payload):
    body = bytes([len(payload)]) + payload
    checksum = 0
    for b in body:
        checksum ^= b
    return bytes([0xAA]) + body + bytes([checksum])


def check_frame(frame):
    if frame[0] != 0xAA or frame[1] != len(frame) - 3:
        return False
    checksum = 0
    for b in frame[1:-1]:
        checksum ^= b
    return checksum == frame[-1]


frame = make_frame(bytes([0x09, 0xC4, 0x01, 0x2C]))       # e.g. voltage 2500 and temperature 300
print("frame:", frame.hex(" "), "| valid:", check_frame(frame))
damaged = bytearray(frame); damaged[3] ^= 0x10              # noise flips one bit
print("damaged:", bytes(damaged).hex(" "), "| valid:", check_frame(bytes(damaged)))
frame: aa 04 09 c4 01 2c e4 | valid: True
damaged: aa 04 09 d4 01 2c e4 | valid: False

An XOR checksum catches a single flipped bit but misses some damage, such as the same bit position flipping in two bytes. Real protocols such as MAVLink and DroneCAN therefore use stronger CRCs.

Module lab

Lab: connecting a sensor and sending data to the flight controller

  1. Connect an I2C sensor (such as the barometer or IMU on the training board) to the Pico 2, scan the bus for device addresses and read values.
  2. Capture SDA and SCL with a logic analyzer, identifying start, address, ACK and data.
  3. Send frames as in Example 2 over UART to a computer, and write a receiver that checks the checksum.
  4. Set a wrong baud rate on one side, observe the data received and explain why.
  5. Study ArduPilot’s DroneCAN page and identify the parameters needed to use a DroneCAN GPS.

Common mistakes

Watch out

  • Wiring TX to TX instead of crossing to RX
  • Forgetting I2C pull-ups, or paralleling several sets until they are too strong
  • Duplicate I2C addresses on one bus
  • Setting an SPI mode that does not match the device
  • Not terminating the CAN bus, or terminating it incorrectly

Summary

  • An 8N1 UART uses 10 bits per byte, carrying baud/10 bytes per second
  • I2C uses two addressed wires with pull-ups; SPI is faster but needs a separate CS per device
  • CAN resists noise with many devices on one pair; DroneCAN is the drone protocol on CAN
  • Transmitted data should carry a checksum or CRC to detect corruption

Check your understanding

  1. How many bytes per second does a 115200 baud 8N1 UART carry?
  2. What is the I2C Fast-mode speed?
  3. How many CS lines does SPI need for three devices?
  4. Which protocol does DroneCAN continue?
  5. What is 0x0F XOR 0xF0?
Answers
  1. bytes per second
  2. 400 kbit/s
  3. Three, one per device
  4. UAVCAN v0
  5. 0xFF

Key formulas

UART 8N1 throughput
XOR checksum

Key references

  1. Microchip Technology. (2018). Getting started with USART (TB3216). link
  2. NXP Semiconductors. (2021). I2C-bus specification and user manual (UM10204, Rev. 7.0). link
  3. Dhaker, P. (2018). Introduction to SPI interface. Analog Dialogue, 52(3). link
  4. International Organization for Standardization. (2024). Road vehicles — Controller area network (CAN) — Part 1: Data link layer and physical coding sublayer (ISO 11898-1:2024). link
  5. DroneCAN Development Team. DroneCAN: A lightweight protocol for UAV CAN networks. link
  6. ArduPilot Dev Team. CAN bus setup (advanced). ArduPilot Copter documentation. link
  7. ArduPilot Dev Team. DroneCAN setup (advanced). ArduPilot Copter documentation. link

Further reading

Study the assigned knowledge units in advance, review media and take the module quiz

In class / field

Lab or field practice from worksheets with a safety checklist

Learning evidence: Checked worksheets and quiz results

Module quiz

This is a formative self-check, not a graded exam

Knowledge domain: Sensors and embedded systems · Communications, networks and IoT