ชมรมโดรน

11. หาสาเหตุเมื่อโดรนไม่ทำตามโค้ด

ใช้ Serial Monitor ตรวจการสื่อสาร I2C กับ Flight Controller และปัญหาที่ชมรมเจอบ่อย

โค้ดที่อัปโหลดผ่านไม่ได้แปลว่าโดรนจะทำตามที่คิด เหมือนส่งข้อความไลน์แล้วยังไม่แน่ใจว่าปลายทางเห็นหรือเปล่า หน้านี้สอนวิธีไล่หาสาเหตุทีละชั้น จากง่ายไปยาก

ไล่หาสาเหตุทีละขั้นเมื่อโดรนไม่ทำตามที่คิด1อัปโหลดสำเร็จ ไม่มี error สีแดงไม่ผ่าน → Board / Port / driver2ACTIVE_FLIGHT_MODE ตรงกับไฟล์ที่แก้ไม่ผ่าน → เปิด mode_config.hpp3loop() ผูก onKeyN กับ handler แล้วไม่ผ่าน → เพิ่มบรรทัด drone.onKeyN4Serial Monitor (9600) เห็นข้อความของเราไม่ผ่าน → ตั้ง baud ให้ตรง5โดรนทำตามคำสั่ง แต่ระยะ/ความสูงเพี้ยนไม่ผ่าน → วัด ms/cm และความสูงใหม่
ไล่ตามลำดับ ผ่านข้อไหนค่อยไปข้อถัดไป ไม่ผ่านข้อไหนแก้ข้อนั้นก่อนแล้วลองใหม่

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

Arduino กับ Flight Controller คุยกันผ่าน I2Cสาย SDA และ SCL สองเส้น ที่อยู่ 0x33 กับ 0x34Arduino Nanoที่อยู่ 0x33เก็บ m_i2cData 6 ไบต์Flight Controllerที่อยู่ 0x34ส่ง 8 ไบต์ให้ poll()SDASCLเสียบผิดช่อง หรือสายหลวม = ไม่มีคำสั่งถึง FCตรวจ: สาย Type-C อยู่ช่องฝั่ง Arduino ไม่ใช่ช่อง FC
Arduino เก็บคำสั่ง 6 ไบต์ไว้ให้ FC มาอ่าน และรับเลขปุ่มที่ FC ส่งมา เมื่อเรียก poll() ก็อ่านข้อมูล 8 ไบต์กลับจาก FC

ไล่ตรวจตามลำดับ:

  1. สาย Type-C อยู่ช่องถูกฝั่งไหม ช่องฝั่ง Arduino ใช้อัปโหลด ห้ามสลับกับช่อง FC
  2. ขั้วต่อสาย ถ้าหลวม ข้อมูลจะหาย heightCm() เป็น 0 เพราะ poll() เติม 0 ให้ไบต์ที่อ่านไม่ได้
  3. ปุ่มรีโมทกดแล้วไม่มีผล ลองพิมพ์ใน handler ของปุ่มนั้นก่อน ถ้าไม่ออกแปลว่า Arduino ไม่ได้รับเลขปุ่ม
  4. ที่อยู่ซ้ำ อย่าเพิ่มอุปกรณ์ 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 ตอน VerifyACTIVE_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. วิธีคิดเวลาเจอปัญหาใหม่

  1. ทำให้เกิดซ้ำได้ ถ้าเกิดบางครั้งแบบสุ่ม ให้จดแบต เวลา และพื้น
  2. ตัดให้เล็กที่สุด เขียน handler ที่มีแค่คำสั่งเดียว เช่น drone.fw(100) แล้วดูว่ายังผิดไหม
  3. เปลี่ยนทีละอย่าง เปลี่ยนสองค่าพร้อมกันแล้วหายก็ไม่รู้ว่าค่าไหนช่วย
  4. จดค่าไว้ ผลวัดทุกครั้งลงตาราง ดีกว่าจำ

ลองทำ

  1. เปิด Serial Monitor ที่ 9600 แล้วผูก DebugHeight กับ KEY11 ยกโดรนขึ้นลงมือแล้วดูตัวเลข
  2. ตั้ง Serial Monitor ที่ 115200 ดูว่าข้อความเพี้ยนอย่างไร แล้วตั้งกลับ
  3. เขียน handler ที่พิมพ์ข้อความก่อนและหลัง drone.settle() แล้วจับเวลาจาก Serial เทียบกับ 220 ms

พังตรงไหนบ่อย

  • ตั้ง baud ไม่ตรง เห็นตัวอักษรขยะ ตั้ง 9600
  • ลืมลบ Serial ที่พิมพ์ถี่ๆ ทำให้ท่อนที่ต้องจับเวลาแม่นเพี้ยน
  • เปลี่ยนหลายอย่างพร้อมกัน แก้ไม่ได้เพราะไม่รู้อะไรเป็นสาเหตุ
  • โทษโค้ดทั้งที่สายหลวม ตรวจฮาร์ดแวร์ก่อนเสมอ

On this page