การรับส่งข้อมูลด้วย 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);
}
}
💡 ข้อควรระวัง
- Endiness: สถาปัตยกรรมชิปที่ต่างกัน (เช่น AVR vs ARM) อาจเก็บข้อมูลสลับด้านกัน ควรระวังเมื่อส่งข้ามค่าย
- Padding: คอมไพเลอร์อาจเพิ่มช่องว่าง (Padding) ใน Struct เพื่อให้การประมวลผลเร็วขึ้น แนะนำให้เพิ่ม
__attribute__((packed))หากต้องการขนาดที่แม่นยำที่สุด - Serial Buffer: ตรวจสอบความเร็ว Serial (Baud Rate) ให้สัมพันธ์กับปริมาณข้อมูลที่ส่ง