ชมรมโดรน

4. จูนเซอร์โวด้วยองศา

แปลงองศา 0–180 เป็นความกว้างพัลส์ ด้วย Servo_Degree.ino และเลิกจำเลข µs ด้วยมือ

หน้าก่อนหน้าสั่งเซอร์โวด้วยตัวเลขอย่าง 1000 และ 2550 ซึ่งเป็นความกว้างพัลส์ในหน่วยไมโครวินาที คนที่ไม่ได้ตั้งค่ามาเองอ่านแล้วไม่รู้ว่าประตูอยู่ตรงไหน Servo_Degree.ino แก้เรื่องนี้ด้วยการให้สั่งเป็น องศา แล้วแปลงเป็นพัลส์ให้

เหมือนสั่งก๊อกน้ำว่า "เปิดครึ่งหนึ่ง" แทนที่จะบอก "หมุนสามรอบครึ่ง" ต้นทางยังเป็นพัลส์เหมือนเดิม แค่มีตัวแปลงคั่น

1. ช่วงของเซอร์โวชุดนี้

องศาแปลงเป็นความกว้างพัลส์0 องศาได้ 490 ไมโครวินาที 180 องศาได้ 2550 ไมโครวินาที ค่า 62 88 132 ตรงกับ 1200 1500 20000°490 µsS_LEFT_ANGLE 62°1199 µsS_CLOSE_ANGLE 88°1497 µsS_RIGHT_ANGLE 132°2000 µs180°2550 µspulse = 490 + องศา × (2550 − 490) / 180map() ใน Servo_Degree.ino ใช้จำนวนเต็ม ผลจึงตัดเศษ (62° ได้ 1199 ไม่ใช่ 1200)
0° = 490 µs, 180° = 2550 µs และจุดที่ชมรมใช้ยิงเป้า 62° / 88° / 132° ซึ่งแปลงได้ราว 1200 / 1500 / 2000 µs

ค่าปลายสองข้างอยู่บนสุดของไฟล์ เป็นค่า calibrate ของกลไกชุดนี้

const int SERVO_DEGREE_MIN = 0;
const int SERVO_DEGREE_MAX = 180;
const int SERVO_DEGREE_MIN_PULSE = 490;   // pulse ที่ 0°
const int SERVO_DEGREE_MAX_PULSE = 2550;  // pulse ที่ 180°

int servo_degree_to_pulse(int angle) {
  angle = constrain(angle, SERVO_DEGREE_MIN, SERVO_DEGREE_MAX);
  return map(angle, SERVO_DEGREE_MIN, SERVO_DEGREE_MAX,
             SERVO_DEGREE_MIN_PULSE, SERVO_DEGREE_MAX_PULSE);
}

constrain ตัดองศาให้อยู่ใน 0–180 ก่อน แล้ว map ย่อช่วงเส้นตรง สูตรเทียบเท่ากับ

pulse = 490 + องศา × (2550 − 490) / 180
      = 490 + องศา × 11.44

map ของ Arduino คำนวณด้วยจำนวนเต็ม เศษถูกตัดทิ้ง ผลขององศาที่ชมรมใช้ในโค้ดจึงเป็น

องศาตัวแปรใน config.hpppulse ที่คำนวณค่า pulse ตรงๆ ในไฟล์เดียวกัน
62°S_LEFT_ANGLE1199 µsS_LEFT = 1200
88°S_CLOSE_ANGLE1497 µsS_CLOSE = 1500
132°S_RIGHT_ANGLE2000 µsS_RIGHT = 2000
90°ตัวอย่างในคอมเมนต์1520 µs

คู่ค่าห่างกันไม่เกิน 3 µs ชวนให้เชื่อว่าสองชุดตัวเลขถูกเลือกให้ตรงกัน ผู้เขียนโค้ดไม่ได้บันทึกไว้ตรงๆ นี่คือข้อสังเกตจากตัวเลข

2. ลองเครื่องคิดเลข

เครื่องคิดเลขตั้งต้นที่ 500–2500 ซึ่งเป็นค่ามาตรฐานทั่วไป ให้พิมพ์ 490 และ 2550 ในสองช่องล่างให้ตรงกับชุดของชมรมก่อน

90° → พัลส์ 1500 µs (1.50 ms)

ลองใส่ 62, 88, 132 ดูว่าตรงกับตารางข้างบน (เครื่องคิดเลขปัดเป็นจำนวนเต็มต่างจาก map เล็กน้อย บางค่าอาจต่างกัน 1 µs)

3. เรียกใช้

ฟังก์ชันที่ห่อไว้ให้ใช้ต่อได้ทันทีมี 4 ตัว

release_servo_degree(PORT3, 90);                       // ตัวเดียว
release_dual_servo_degree(PORT3, 62, PORT6, 132);       // สองตัวพร้อมกัน
release_servo_degree_custom(PORT3, 90, 600, 2400);      // กำหนดช่วง pulse เอง

ตัว _custom ไว้สำหรับเซอร์โวที่ปลายช่วงไม่เท่ากับ 490–2550 ส่ง pulse_min และ pulse_max ของตัวนั้นไปเอง และมี release_dual_servo_degree_custom สำหรับสองตัวต่างรุ่น ฟังก์ชันทั้งหมดเรียกต่อไปที่ release_servo_angle จึงบล็อก 1.5 วินาทีเหมือนกัน ผ่าน DroneEasy ก็ใช้ได้ เช่น drone.servoAngle(SHOOT1_PIN, S_LEFT_ANGLE)

4. จูนอย่างเป็นระบบ

ใช้ลำดับนี้ ซึ่งสอดคล้องกับคำแนะนำใน README.ino (ปรับทีละ 25–50 µs ทดสอบทีละช่องก่อนรวม)

  1. ถอดของที่เซอร์โวดันออก หรือถอดใบพัด ไม่มีใครถือโดรนที่ต่อแบตระหว่างจูน
  2. สั่ง release_servo_degree(PORT3, 0) แล้วดูว่าก้านไปสุดข้างหรือชนขอบ ถ้าชน ให้เพิ่ม SERVO_DEGREE_MIN_PULSE ทีละ 25
  3. สั่ง 180° ทำแบบเดียวกันกับ SERVO_DEGREE_MAX_PULSE
  4. สั่ง 90° ต้องอยู่กลางจริง ถ้าไม่ใช่ แปลว่าเส้นไม่ตรงกลางพอดี
  5. จดองศาของตำแหน่ง "ปิด" "เปิด" ของแต่ละกลไกเป็นค่าคงที่ที่มีชื่อ (แบบ S_LEFT_ANGLE) แล้วเรียกจากชื่อเสมอ

ลองทำ

  1. คำนวณด้วยมือว่า 45° ได้กี่ µs จากสูตร 490 + 45 × 11.44 แล้วเทียบกับเครื่องคิดเลข
  2. เขียนฟังก์ชันกลับด้าน pulse_to_degree ที่แปลง µs เป็นองศา (คำใบ้: ใช้ map แต่สลับช่วง) แล้วลองกับ 1200, 1500, 2000
  3. ถ้ากลไกใหม่ใช้ช่วง 600–2400 ให้ใช้ release_servo_degree_custom(PORT3, 90, 600, 2400) แล้วตรวจว่าได้ 1500 µs

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

  • ช่วงเริ่มต้นของเครื่องคิดเลขไม่ใช่ของเรา ลืมเปลี่ยนเป็น 490/2550 ได้ผลต่างหลายสิบ µs
  • ใช้ Servo_Degree กับพอร์ตที่ไม่ได้ตั้ง pinMode เซอร์โวนิ่ง ดูว่า DroneEasy::beginDefault() ตั้งให้พอร์ตนั้นแล้ว
  • ปรับปลายช่วงจนกลไกชน เซอร์โวดันสุดแล้วสั่น ทำให้ร้อนและกินกระแส ถอยกลับ 25–50 µs
  • องศาเกิน 180 constrain ตัดให้เป็น 180 เงียบๆ โดยไม่เตือน ถ้าสั่ง 200 จะได้ 180
  • คิดว่าแปลงกลับได้ โค้ดนี้แปลงทางเดียวจากองศาเป็นพัลส์ ไม่มีตัวอ่านองศาจากเซอร์โว
  • ลืมว่าบล็อก ทุกฟังก์ชันนี้ใช้เวลา 1.5 วินาที ดูงบเวลาของภารกิจ

On this page