11. หาสาเหตุเมื่อโดรนไม่ทำตามโค้ด
ใช้ Serial Monitor ตรวจการสื่อสาร I2C กับ Flight Controller และปัญหาที่ชมรมเจอบ่อย
โค้ดที่อัปโหลดผ่านไม่ได้แปลว่าโดรนจะทำตามที่คิด เหมือนส่งข้อความไลน์แล้วยังไม่แน่ใจว่าปลายทางเห็นหรือเปล่า หน้านี้สอนวิธีไล่หาสาเหตุทีละชั้น จากง่ายไปยาก
1. เปิดตาดูด้วย Serial Monitor
drone.beginDefault() (เรียกใน setup() ของ drone_sanam5.ino) เปิด Serial ที่ 9600 baud ให้แล้ว ตั้ง Serial Monitor ให้ตรงนี้ ไม่งั้นเห็นแต่ตัวอักษรขยะ
พิมพ์ความสูงที่อ่านได้จาก FC:
void DebugHeight() {
drone.poll();
Serial.print("height cm = ");
Serial.println(drone.heightCm());
}ผูกกับปุ่มที่ว่างแล้วกดดู (drone.onKey11(DebugHeight); ในโหมด Mission) ได้หลายประโยชน์
- ตัวเลขเปลี่ยนตามเมื่อยกโดรนขึ้นลง แปลว่า Arduino คุยกับ FC ได้
- เป็น 0 ตลอด ไม่มีข้อมูลจาก FC (ดูหัวข้อ I2C ด้านล่าง)
- เป็นเลขใหญ่เกิน 300 เซ็นเซอร์อ่านพลาด โค้ดชมรมถือว่าค่าไม่ถูกต้องเช่นกัน (
h == 0 || h > 300)
เติมข้อความบอกจุดที่โค้ดไปถึงได้ด้วย
Serial.println("เริ่ม fw");
drone.fw(250);
Serial.println("จบ fw");Serial ช้ากว่าที่คิด
ที่ 9600 baud ส่งได้ราว 960 ตัวอักษรต่อวินาที ข้อความ 20 ตัวอักษรกินเวลาประมาณ 20 ms การพิมพ์ถี่ๆ ใน loop() ที่ต้องจับเวลาแม่นจะทำให้เวลาเพี้ยน พิมพ์เฉพาะตอนดีบั๊ก แล้วลบออกก่อนแข่ง
2. ตรวจ I2C
Arduino กับ FC คุยกันผ่านสายสองเส้น SDA และ SCL ตามโค้ด Arduino ตั้งตัวเองเป็นอุปกรณ์ที่อยู่ 0x33 (Wire.begin(0x33) ใน protocol.cpp) และ FC มีที่อยู่ 0x34
ไล่ตรวจตามลำดับ:
- สาย Type-C อยู่ช่องถูกฝั่งไหม ช่องฝั่ง Arduino ใช้อัปโหลด ห้ามสลับกับช่อง FC
- ขั้วต่อสาย ถ้าหลวม ข้อมูลจะหาย
heightCm()เป็น 0 เพราะpoll()เติม 0 ให้ไบต์ที่อ่านไม่ได้ - ปุ่มรีโมทกดแล้วไม่มีผล ลองพิมพ์ใน handler ของปุ่มนั้นก่อน ถ้าไม่ออกแปลว่า Arduino ไม่ได้รับเลขปุ่ม
- ที่อยู่ซ้ำ อย่าเพิ่มอุปกรณ์ I2C ตัวอื่นที่ใช้
0x33หรือ0x34ดู ต่อสาย I2C
อย่าเปลี่ยน Wire.begin(0x33) หรือ FC_ADDR = 0x34 ใน protocol.cpp เว้นแต่ผู้ผลิตระบุ
3. ปัญหาที่เจอบ่อย
| อาการ | สาเหตุที่เป็นไปได้ | แก้อย่างไร |
|---|---|---|
| อัปโหลดไม่ได้ ไม่มี Port | ไม่ได้เลือก Port หรือไม่มี driver | ตรวจ Tools → Port ติดตั้ง CH340 หรือ CP2102 |
| อัปโหลดแล้วบอร์ดไม่ตอบ | เลือกบอร์ดผิด | Board = Arduino Nano, Processor = ATmega328P (Old Bootloader) |
#error ตอน Verify | ACTIVE_FLIGHT_MODE ผิด | แก้ที่ mode_config.hpp ดู โหมดบิน |
| กดปุ่มแล้วเงียบ | ไม่ได้ผูก onKeyN หรือเลือกโหมดผิด | ตรวจ loop...Mode() ของโหมดที่เลือก |
| ขึ้นบินแล้วเอียงหรือไหล | calibrate ไม่นิ่ง | วางพื้นเรียบ ห้ามจับระหว่าง calibrate |
| ไปไม่ถึง หรือเลยจุดที่ต้องการ | ค่า ms/cm ไม่ตรงโดรน | วัดใหม่ตาม ระยะกับเวลา |
| ปล่อยบอลไม่หมด | MISSION_DROP_WAIT_MS สั้นไป | เพิ่มเป็น 700–1000 ms แล้วทดสอบ (ค่าตามคู่มือชมรม) |
| เซอร์โวกระตุกตอนเปิดเครื่อง | ยังไม่ตั้งค่า pulse ตั้งต้น | เรียก close_all_ball_gate() ใน setup ก่อน |
| ยิงดอกไม่ออกหรือออกช้า | FIRE_HOLD_MS น้อยไปหรือแรงดันเซอร์โวต่ำ | เพิ่มเวลาและตรวจแบตเตอรี่ |
| ขึ้นเกือบถึงแล้วลงต่ำกว่าเป้า | smooth_set_height ขั้นสุดท้ายไม่ถึง | เติม set_height(เป้า) ตามหลัง |
4. วิธีคิดเวลาเจอปัญหาใหม่
- ทำให้เกิดซ้ำได้ ถ้าเกิดบางครั้งแบบสุ่ม ให้จดแบต เวลา และพื้น
- ตัดให้เล็กที่สุด เขียน handler ที่มีแค่คำสั่งเดียว เช่น
drone.fw(100)แล้วดูว่ายังผิดไหม - เปลี่ยนทีละอย่าง เปลี่ยนสองค่าพร้อมกันแล้วหายก็ไม่รู้ว่าค่าไหนช่วย
- จดค่าไว้ ผลวัดทุกครั้งลงตาราง ดีกว่าจำ
ลองทำ
- เปิด Serial Monitor ที่ 9600 แล้วผูก
DebugHeightกับ KEY11 ยกโดรนขึ้นลงมือแล้วดูตัวเลข - ตั้ง Serial Monitor ที่ 115200 ดูว่าข้อความเพี้ยนอย่างไร แล้วตั้งกลับ
- เขียน handler ที่พิมพ์ข้อความก่อนและหลัง
drone.settle()แล้วจับเวลาจาก Serial เทียบกับ 220 ms
พังตรงไหนบ่อย
- ตั้ง baud ไม่ตรง เห็นตัวอักษรขยะ ตั้ง 9600
- ลืมลบ Serial ที่พิมพ์ถี่ๆ ทำให้ท่อนที่ต้องจับเวลาแม่นเพี้ยน
- เปลี่ยนหลายอย่างพร้อมกัน แก้ไม่ได้เพราะไม่รู้อะไรเป็นสาเหตุ
- โทษโค้ดทั้งที่สายหลวม ตรวจฮาร์ดแวร์ก่อนเสมอ