โมดูล 4/5 · สัปดาห์ 10–12 · 27 ชม.

อินเทอร์เฟซอนุกรมและ DroneCAN

UAT 204 ไมโครคอนโทรลเลอร์และระบบสมองกลฝังตัว

เวลาเรียนประมาณ 80 นาทีร่าง รอตรวจปรับปรุงล่าสุด 27 กันยายน 2569

บทเรียน

เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ

  1. อธิบาย frame ของ UART แบบ 8N1 และคำนวณอัตราส่งข้อมูลจริงจาก baud rate
  2. อธิบายบัส I2C (ที่อยู่ pull-up ความเร็ว) และ SPI (สี่โหมดตาม CPOL/CPHA) และเลือกใช้ให้เหมาะ
  3. อธิบาย CAN และ DroneCAN และเหตุที่ใช้กับอุปกรณ์บนโดรนหลายตัว
  4. ออกแบบ frame ข้อมูลอย่างง่ายพร้อม checksum และตรวจข้อมูลที่เสียหาย

ความรู้พื้นฐานที่ควรมี: UAT 204 โมดูล 1–3

ทำไมต้องรู้

ตัวควบคุมการบินคุยกับอุปกรณ์หลายสิบตัวพร้อมกัน IMU ส่งค่าหลายพันครั้งต่อวินาทีผ่าน SPI เข็มทิศและบารอมิเตอร์ใช้ I2C GPS และวิทยุ telemetry ใช้ UART และบนโดรนขนาดใหญ่ GPS ESC และ power module ต่อกันบนบัส CAN เส้นเดียว การเลือกอินเทอร์เฟซผิดหรือตั้งความเร็วผิด ทำให้ข้อมูลช้า หาย หรืออุปกรณ์ไม่ตอบ

UART

UART ส่งข้อมูลทีละบิตบนสายเดียวต่อทิศทาง (TX ต่อ RX ไขว้กัน) โดยทั้งสองฝั่งต้องตั้ง baud rate ตรงกัน ตามเอกสาร Microchip TB3216 frame แบบ 8N1 มี start bit หนึ่งบิต ข้อมูลแปดบิต และ stop bit หนึ่งบิต รวม 10 บิตต่อหนึ่งไบต์ จึงส่งได้ baud/10 ไบต์ต่อวินาที

รูปคลื่นของ frame UART สายอยู่สูงขณะว่าง start bit ต่ำ ตามด้วยบิตข้อมูล D0 ถึง D7 ของไบต์ 0x41 โดยส่งบิตต่ำสุดก่อน แล้ว stop bit สูง ด้านล่างเขียนว่า 10 บิตต่อหนึ่งไบต์แบบ 8N1
ภาพที่ 1 frame ของ UART แบบ 8N1

ArduPilot ตั้ง baud เริ่มต้นของพอร์ต telemetry ไว้ที่ 57600 และพอร์ต GPS ที่ 230400

I2C และ SPI

ตามข้อกำหนด I2C ของ NXP (UM10204 rev 7.0) บัส I2C ใช้สองสาย SDA และ SCL แบบ open-drain ต้องมีตัวต้านทาน pull-up อุปกรณ์แต่ละตัวมี ที่อยู่ 7 บิต ความเร็วมาตรฐานคือ 100 kbit/s (Standard-mode), 400 kbit/s (Fast-mode) และ 1 Mbit/s (Fast-mode Plus) ต่ออุปกรณ์หลายตัวบนสองสายได้ แต่ช้ากว่า SPI

SPI ใช้สายนาฬิกา SCK สายข้อมูล MOSI และ MISO และสายเลือกอุปกรณ์ (CS) แยกให้แต่ละตัว เร็วกว่า I2C มาก จึงใช้กับ IMU ที่ต้องอ่านบ่อย ตามบทความของ Analog Devices SPI มีสี่โหมดตามขั้วนาฬิกา (CPOL) และขอบที่อ่านข้อมูล (CPHA) ทั้งสองฝั่งต้องตั้งโหมดตรงกัน

สามแบบ I2C มี MCU กับอุปกรณ์สามตัวที่อยู่ 0x68 0x76 0x1E ต่อบนสาย SDA และ SCL ร่วมกัน SPI มี MCU กับอุปกรณ์สามตัวบนสาย SCK MOSI MISO ร่วมกัน และสาย CS แยกไปแต่ละตัว CAN มีสาย CANH และ CANL คู่หนึ่ง มีตัวต้านทานปลายสายที่สองปลาย ต่อกับ FC GPS และ ESC
ภาพที่ 2 บัส I2C, SPI และ CAN

CAN และ DroneCAN

CAN ใช้สายคู่ CANH และ CANL ส่งสัญญาณแบบผลต่าง จึงทนสัญญาณรบกวนและเดินสายยาวได้ อุปกรณ์ทุกตัวต่อบนสายคู่เดียวกัน มีตัวต้านทานปิดปลายสายที่ปลายทั้งสองด้าน มาตรฐานคือ ISO 11898-1 (ฉบับล่าสุด 2024 ซึ่งเพิ่ม CAN XL) เอกสาร ArduPilot ระบุว่าความเร็วที่ใช้บ่อยคือ 1 Mbit/s และค่าเริ่มต้นของ CAN_P1_BITRATE คือ 1,000,000

DroneCAN เป็นโพรโทคอลบน CAN สำหรับอากาศยานไร้คนขับ พัฒนาต่อจาก UAVCAN v0 ArduPilot และ PX4 รองรับอุปกรณ์ DroneCAN เช่น GPS เข็มทิศ ESC และ power module ข้อดีคือเดินสายน้อยลงและอุปกรณ์รายงานสถานะของตัวเองได้

ตัวอย่างที่ 1 อัตราส่งข้อมูลจริง

for label, baud in (("telemetry", 57_600), ("GPS", 230_400)):
    bytes_per_s = baud / 10                       # 8N1 = 10 บิตต่อไบต์
    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                    # ที่อยู่ ทะเบียน ที่อยู่ซ้ำ 6 ไบต์ข้อมูล + start/stop โดยประมาณ
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

ข้อความ 40 ไบต์ที่ 50 ครั้งต่อวินาทีใช้ลิงก์ telemetry 57600 ไปราวหนึ่งในสาม ถ้าเพิ่มข้อความอื่นอาจเกินความจุ ส่วนการอ่านเซนเซอร์ 6 ไบต์ผ่าน I2C ที่ 400 kHz ใช้เวลาราว 0.2 ms จึงอ่านได้หลายร้อยครั้งต่อวินาทีเมื่อมีอุปกรณ์น้อย การคิดจำนวนบิตของ I2C ในตัวอย่างเป็นการประมาณ

ตรวจข้อมูลเสียหายด้วย checksum

ตัวอย่างที่ 2 frame อย่างง่ายพร้อม checksum

โมดูลเซนเซอร์ของเราส่ง frame สมมติ: ไบต์เริ่ม 0xAA ความยาว ข้อมูล และ checksum แบบ XOR ของไบต์ความยาวและข้อมูล

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]))       # เช่น แรงดัน 2500 และอุณหภูมิ 300
print("frame:", frame.hex(" "), "| valid:", check_frame(frame))
damaged = bytearray(frame); damaged[3] ^= 0x10              # สัญญาณรบกวนทำให้บิตหนึ่งกลับค่า
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

checksum แบบ XOR จับบิตเดียวที่เสียได้ แต่พลาดความเสียหายบางแบบ เช่น บิตตำแหน่งเดียวกันเสียในสองไบต์ โพรโทคอลจริงอย่าง MAVLink และ DroneCAN จึงใช้ CRC ที่แข็งแรงกว่า

ปฏิบัติการประจำโมดูล

ปฏิบัติการ: เชื่อมเซนเซอร์และส่งข้อมูลให้ตัวควบคุมการบิน

  1. ต่อเซนเซอร์ I2C (เช่น บารอมิเตอร์หรือ IMU บนบอร์ดฝึก) กับ Pico 2 สแกนหาที่อยู่ของอุปกรณ์บนบัส แล้วอ่านค่า
  2. วัดสัญญาณ SDA และ SCL ด้วย logic analyzer ระบุ start ที่อยู่ ACK และข้อมูล
  3. ส่ง frame ตามตัวอย่างที่ 2 ผ่าน UART ไปคอมพิวเตอร์ แล้วเขียนโปรแกรมฝั่งรับตรวจ checksum
  4. ตั้ง baud ผิดหนึ่งฝั่ง สังเกตข้อมูลที่ได้ แล้วอธิบายเหตุ
  5. ศึกษาหน้า DroneCAN ของ ArduPilot ระบุพารามิเตอร์ที่ต้องตั้งเพื่อใช้ GPS แบบ DroneCAN

ข้อผิดพลาดที่พบบ่อย

ระวัง

  • ต่อ TX กับ TX แทนการไขว้ไป RX
  • ลืมตัวต้านทาน pull-up ของ I2C หรือมีหลายชุดขนานกันจนแรงเกิน
  • ใช้ที่อยู่ I2C ซ้ำกัน บนบัสเดียว
  • ตั้งโหมด SPI ไม่ตรงกับอุปกรณ์
  • ไม่ปิดปลายสาย CAN หรือปิดผิดจำนวน

สรุป

  • UART แบบ 8N1 ใช้ 10 บิตต่อไบต์ ส่งได้ baud/10 ไบต์ต่อวินาที
  • I2C ใช้สองสายแบบมีที่อยู่ ต้องมี pull-up ส่วน SPI เร็วกว่าแต่ต้องมี CS แยกให้แต่ละอุปกรณ์
  • CAN ทนสัญญาณรบกวน อุปกรณ์หลายตัวต่อบนสายคู่เดียว DroneCAN คือโพรโทคอลบน CAN สำหรับโดรน
  • ข้อมูลที่ส่งควรมี checksum หรือ CRC เพื่อตรวจความเสียหาย

แบบฝึกตรวจความเข้าใจ

  1. UART 115200 baud แบบ 8N1 ส่งได้กี่ไบต์ต่อวินาที
  2. ความเร็ว Fast-mode ของ I2C คือเท่าใด
  3. SPI ต่ออุปกรณ์สามตัวต้องมีสาย CS กี่เส้น
  4. DroneCAN พัฒนาต่อจากโพรโทคอลใด
  5. XOR ของไบต์ 0x0F กับ 0xF0 ได้เท่าใด
เฉลย
  1. ไบต์ต่อวินาที
  2. 400 kbit/s
  3. สามเส้น หนึ่งเส้นต่ออุปกรณ์หนึ่งตัว
  4. UAVCAN v0
  5. 0xFF

สรุปสูตรสำคัญ

อัตราส่งข้อมูลของ UART แบบ 8N1
Checksum แบบ XOR

แหล่งอ้างอิงหลัก

  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

อ่านเพิ่มเติม

ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล

ในชั้นเรียน / ภาคสนาม

ปฏิบัติการในห้องแล็บหรือภาคสนามตามใบงาน พร้อม checklist ความปลอดภัย

หลักฐานการเรียนรู้: ใบงานที่ผ่านการตรวจและผล quiz

แบบทดสอบประจำโมดูล

แบบทดสอบนี้ใช้ตรวจความเข้าใจ (formative) ไม่ใช่การสอบเก็บคะแนน

โดเมนความรู้: เซนเซอร์และระบบสมองกลฝังตัว · การสื่อสาร เครือข่าย และ IoT