ข้ามไปที่เนื้อหา

การรับส่งข้อมูลด้วย Binary Struct (Binary Data Sync)

เมื่อต้องส่งข้อมูลจำนวนมากระหว่างบอร์ด (เช่น จาก ESP32 ไปยัง Arduino Nano) การส่งแบบข้อความ (String/JSON) จะช้าและกินทรัพยากรมาก การใช้ Struct จะช่วยให้การรับส่งข้อมูลเร็วและมีประสิทธิภาพสูงสุด


1. การสร้างโครงสร้างข้อมูล (Structure Definition)

ทั้งฝั่งผู้ส่ง (Sender) และผู้รับ (Receiver) ต้องมีโครงสร้างข้อมูลที่ "เหมือนกันทุกประการ"

struct RobotStatus {
  uint32_t timestamp;  // เวลา (4 bytes)
  float batteryVoltage; // แรงดันแบต (4 bytes)
  int16_t speedLeft;   // ความเร็วล้อซ้าย (2 bytes)
  int16_t speedRight;  // ความเร็วล้อขวา (2 bytes)
  uint8_t mode;        // โหมดการทำงาน (1 byte)
  char signature[4];   // ลายเซ็นประจำตัว (4 bytes)
};

2. วิธีการส่งข้อมูล (Sender Side)

เราจะใช้คำสั่งการแคสต์ (Casting) ข้อมูลใน Memory ให้เป็นชุดของ byte เพื่อส่งผ่าน Serial

RobotStatus myData;
// กำหนดค่าข้อมูล...
myData.batteryVoltage = 12.6;
strcpy(myData.signature, "GMS");

// ส่งผ่าน Serial
Serial.write((uint8_t *)&myData, sizeof(myData));

3. วิธีการรับข้อมูล (Receiver Side)

ฝั่งรับจะรอจนกว่าข้อมูลจะครบตามขนาดของ RobotStatus แล้วจึงนำมาเก็บลงในตัวแปร

if (Serial.available() >= sizeof(RobotStatus)) {
  RobotStatus receivedData;
  Serial.readBytes((uint8_t *)&receivedData, sizeof(RobotStatus));

  // ตรวจสอบลายเซ็นก่อนใช้งาน
  if (strcmp(receivedData.signature, "GMS") == 0) {
    Serial.print("Battery: ");
    Serial.println(receivedData.batteryVoltage);
  }
}

💡 ข้อควรระวัง

  1. Endiness: สถาปัตยกรรมชิปที่ต่างกัน (เช่น AVR vs ARM) อาจเก็บข้อมูลสลับด้านกัน ควรระวังเมื่อส่งข้ามค่าย
  2. Padding: คอมไพเลอร์อาจเพิ่มช่องว่าง (Padding) ใน Struct เพื่อให้การประมวลผลเร็วขึ้น แนะนำให้เพิ่ม __attribute__((packed)) หากต้องการขนาดที่แม่นยำที่สุด
  3. Serial Buffer: ตรวจสอบความเร็ว Serial (Baud Rate) ให้สัมพันธ์กับปริมาณข้อมูลที่ส่ง