คู่มือประกอบหุ่นฐานเซอร์โว — ว32210
หุ่นติดตามใบหน้าต้นฉบับจากโปรเจกต์ face-following-robot-uno-q
หุ่นฐานเซอร์โวแบบกล่อง / บทเรียน 04–13

คู่มือประกอบหุ่นฐานเซอร์โว

หุ่นฐานมาตรฐานของรายวิชา: ตัวถังกล่องพิมพ์ 3D ขับด้วยเซอร์โว FS5103R สองตัว มีกล้อง อัลตราโซนิก และ Arduino UNO Q ทุกกลุ่มใช้ฐานเดียวกันแล้วออกแบบ AI ตามภารกิจของตน ภารกิจหันหาใบหน้าดัดแปลงจากโปรเจกต์ face-following-robot-uno-q ของ Samuel Alexander

เปิดแบบ 3 มิติ → ใบงานเสริม
01 / คู่มือ

ภาพรวมระบบ

UNO Q มีสมองสองส่วนบนบอร์ดเดียว ฝั่ง MPU (Qualcomm, Linux) รันโมเดลตรวจจับใบหน้าและโปรแกรม Python ฝั่ง MCU (STM32, Zephyr RTOS) สร้างสัญญาณ PWM ให้ servo อย่างแม่นยำ ทั้งสองฝั่งคุยกันผ่าน Bridge RPC ระบบประมวลผลได้ประมาณ 10–15 เฟรมต่อวินาที

กล้อง USBส่งภาพ 640 px
MPU · Pythonโมเดล AI ตัดสินใจ (vision_bridge.py หรือ face_follow_main.py)
Bridge RPCdrive("F/B/L/R/S") หรือ set_wheel_pwm(left, right) · get_distance()
MCU · robot_base_servo.inoPWM 50 Hz ที่ D9 และ D10 · อัลตราโซนิกที่ D12/D13
Servo ซ้าย/ขวาหมุนล้อสวนทางกันเพื่อเลี้ยว

หุ่นฐานเดียวกันรองรับทุกภารกิจ สิ่งที่เปลี่ยนตามภารกิจคือโปรแกรมฝั่ง Python

หัวข้อภารกิจ 1–6 และภารกิจที่เสนอเองภารกิจ 7 หันหาใบหน้า
การขับล้อเซอร์โว FS5103R สองตัวต่อตรงกับขา D9/D10 ไฟเลี้ยงจากตัวแปลงไฟ 5 V แยกจากบอร์ด
AI ฝั่ง Linuxvision_bridge.py (OpenCV / Teachable Machine / โมเดลใน App Lab)brick video_object_detection โมเดล face-detection
คำสั่งที่ส่งผ่าน Bridgedrive("F"), drive("L") … ทีละตัวอักษรset_wheel_pwm(left_us, right_us)
โปรแกรมฝั่ง MCUrobot_base_servo.ino ไฟล์เดียวกัน (หยุดเองเมื่อเจอสิ่งกีดขวาง < 15 cm)
ตรรกะการตัดสินใจdecide() ตามตารางการตัดสินใจตัวควบคุมแบบสัดส่วน: heading error → turn
การตรวจสอบ/ปรับค่าlog ใน App Lab · แท็บ "ขับด้วยคำสั่ง" ในแบบ 3 มิติแท็บ "หันหาใบหน้า" ในแบบ 3 มิติ · Web UI พอร์ต 7000 (ฉบับเต็ม)
02 / คู่มือ

รายการอุปกรณ์ (ต่อ 1 กลุ่ม)

อุปกรณ์จำนวนหมายเหตุ
Arduino UNO Q1รุ่น 2 GB หรือ 4 GB
เซอร์โว Feetech FS5103R (หมุนต่อเนื่อง)24–8.4 V · 2.6 kg·cm ที่ 4.8 V
กล้อง Logitech C2701มีไมค์ในตัว ใช้กับภารกิจสั่งด้วยเสียงได้ · กล้อง UVC ทั่วไปใช้แทนได้
อัลตราโซนิก HC-SR041เสียบรางด้านในผนังหน้า
รางถ่าน 2 × 18650 + ถ่าน 2 ก้อน17.4 V เข้า VIN ของบอร์ด
ตัวแปลงไฟ DC-DC step-down 5 V 3 A1เลี้ยงเซอร์โวและอัลตราโซนิก
สวิตช์ไฟ Ø12 mm1ติดผนังหลัง
ตัวเก็บประจุ 470 µF 16 V1คร่อมราง 5V–GND ของเซอร์โว
เบรดบอร์ดเล็กและสาย jumper1 / ~16ผู้–ผู้ และ ผู้–เมีย
USB-C hub หรือ OTG1สำหรับเสียบกล้อง
ชิ้นงานพิมพ์ 3D1 ชุดbody, lid, wheel ×2, caster, cam_mount (ชุดไฟล์ หุ่นเซอร์โวแบบกล่อง_ว32210)
ลูกแก้วหรือลูกเหล็ก Ø16 mm1กดเข้าลูกล้อประคอง
ยางโอริงหรือยางรัดของ2คาดร่องล้อ
น็อต M3 × 10 (8), M3 × 8 (10), หัวน็อต M3, เสารอง M3 (4)1 ชุดพร้อมไขควง
มัลติมิเตอร์1 ต่อห้องปรับตัวแปลงไฟให้ได้ 5.0–5.2 V

การแบ่งหน้าที่ในกลุ่ม 4–5 คน

ผู้ประกอบโครงตัวถัง เซอร์โว ล้อ อัลตราโซนิก ฝาบน
ผู้ต่อวงจรสายสัญญาณ ตัวแปลงไฟ รางไฟ ตัวเก็บประจุ
ผู้ดูแลซอฟต์แวร์App Lab, robot_base_servo.ino, โปรแกรม Python ของภารกิจ
ผู้ตรวจสอบตรวจตามรายการก่อนจ่ายไฟ
ผู้บันทึกบันทึกผลลงใบงาน ถ่ายภาพ
03 / คู่มือ

ประกอบตัวหุ่น

ทุกขั้นมีลิงก์ไปยังแบบ 3 มิติที่แสดงชิ้นส่วนของขั้นนั้นเลื่อนเข้าที่ หมุนดูได้รอบทิศ

  1. 1

    เตรียมตัวถังและติดลูกล้อประคอง

    แคะเศษพลาสติกออกจากรูสกรูและช่องเซอร์โว กดลูกแก้ว Ø16 mm เข้าปลายลูกล้อ แล้วยึดใต้พื้นกล่องด้านหน้าด้วย M3 × 8 สองตัว

    ตรวจ: ลูกแก้วหมุนได้คล่อง ไม่หลุดเมื่อคว่ำ

    ดูแบบ 3 มิติ ขั้นที่ 1
  2. 2

    ยึดเซอร์โวซ้ายและขวา

    สอดเซอร์โวจากด้านในกล่องให้หัวเพลาโผล่ออกช่องข้าง ยึดหูเซอร์โวกับผนังด้วย M3 × 10 และหัวน็อตข้างละ 4 ตัว ตัวขวาหันกลับด้านกับตัวซ้าย ซึ่งเป็นเรื่องปกติ

    ตรวจ: แกนเพลาสองข้างอยู่แนวเดียวกัน ทำเครื่องหมายว่าตัวไหนซ้าย ตัวไหนขวา

    ดูแบบ 3 มิติ ขั้นที่ 2
  3. 3

    ใส่ล้อ

    ยึดแป้นกลมของเซอร์โวในหลุมกลางล้อ สวมเข้ากับเพลาแล้วขันสกรูกลางล้อ คาดยางโอริงที่ร่องล้อ

    ตรวจ: หมุนล้อด้วยมือแล้วไม่แกว่งและไม่เสียดสีตัวถัง

    ดูแบบ 3 มิติ ขั้นที่ 3
  4. 4

    ใส่อัลตราโซนิก

    เสียบบอร์ด HC-SR04 ลงรางด้านในผนังหน้า ให้ตัวรับ-ส่งคลื่นทั้งสองโผล่ออกรูหน้ารถ ขาต่อสายหันลง

    ตรวจ: บอร์ดตั้งตรง ไม่เอียง และตัวรับ-ส่งคลื่นไม่ถูกผนังบัง

    ดูแบบ 3 มิติ ขั้นที่ 4
  5. 5

    วางรางถ่าน ตัวแปลงไฟ และสวิตช์

    วางรางถ่าน 2 × 18650 กลางพื้นระหว่างเซอร์โว รัดด้วยสายตีนตุ๊กแก ยึดตัวแปลงไฟ 5 V ที่รูพื้นด้านหน้าขวา ใส่สวิตช์ที่ผนังหลัง ปรับตัวแปลงไฟให้ได้ 5.0–5.2 V ด้วยมัลติมิเตอร์ก่อนต่อเซอร์โว

    ตรวจ: ยังไม่ใส่ถ่าน สวิตช์อยู่ตำแหน่งปิด

    ดูแบบ 3 มิติ ขั้นที่ 5
  6. 6

    ร้อยสายและปิดฝาบน

    ร้อยสายเซอร์โวและสายไฟจากตัวแปลงไฟขึ้นทางช่องกลางฝา ร้อยสายอัลตราโซนิกขึ้นทางช่องหน้า แล้วสวมฝาและขันสกรูมุม 4 ตัว

    ตรวจ: สายไม่ถูกหนีบระหว่างฝากับตัวถัง

    ดูแบบ 3 มิติ ขั้นที่ 6
  7. 7

    ติดตั้ง Arduino UNO Q

    ยึดบอร์ดบนเสารอง M3 ที่ฝาด้านหลัง ให้พอร์ต USB-C หันไปด้านหลัง

    ตรวจ: ใต้บอร์ดไม่มีโลหะหรือสายเปลือยแตะ

    ดูแบบ 3 มิติ ขั้นที่ 7
  8. 8

    ติดเบรดบอร์ดและตัวเก็บประจุ

    ติดเบรดบอร์ดด้านหน้าฝา เสียบตัวเก็บประจุ 470 µF คร่อมราง 5V กับ GND โดยขายาว (+) อยู่ราง 5V

    ตรวจ: ขั้วตัวเก็บประจุถูกต้อง เพราะถ้ากลับขั้วอาจบวมหรือแตก

    ดูแบบ 3 มิติ ขั้นที่ 8
  9. 9

    ติดแผ่นยึดกล้องและกล้อง

    ขันแผ่นยึดกล้องกับผนังหน้าด้วย M3 × 8 สี่ตัว หนีบกล้อง C270 ที่ขอบบนแผ่น หันเลนส์ตรงไปด้านหน้า ร้อยสาย USB ผ่านช่องหน้าฝาไปที่ hub ของบอร์ด

    ตรวจ: กล้องไม่เอียงซ้าย-ขวา เพราะจะทำให้ค่าตำแหน่งในภาพเพี้ยน

    ดูแบบ 3 มิติ ขั้นที่ 9
  10. 10

    ต่อสายทั้งหมด

    ต่อตามผังในหัวข้อที่ 4 แล้วให้ครูเซ็นเช็กลิสต์ก่อนใส่ถ่านและเปิดสวิตช์

    ทดสอบ: ส่งคำสั่ง T ล้อต้องเดินหน้า ถอย หมุนซ้าย หมุนขวา แล้วหยุด

    ดูแบบ 3 มิติ ขั้นที่ 10
04 / คู่มือ

ผังต่อสาย

อุปกรณ์สาย / ขาต่อที่
เซอร์โวซ้ายสัญญาณ (เหลือง/ขาว)D9
แดง · น้ำตาล/ดำราง 5V · ราง GND
เซอร์โวขวาสัญญาณ (เหลือง/ขาว)D10
แดง · น้ำตาล/ดำราง 5V · ราง GND
อัลตราโซนิก HC-SR04TRIG · ECHOD12 · D13
VCC · GNDราง 5V · ราง GND
รางถ่าน 18650 (+)ผ่านสวิตช์ขา VIN ของ UNO Q และขา IN+ ของตัวแปลงไฟ
รางถ่าน 18650 (−)GNDขา GND ของ UNO Q และขา IN− ของตัวแปลงไฟ
ตัวแปลงไฟ 5 VOUT+ · OUT−ราง 5V · ราง GND
UNO QGNDราง GND (GND ร่วม) · ห้ามต่อขา 5V ของบอร์ดเข้าราง
ตัวเก็บประจุ 470 µFขายาว (+) · ขาสั้น (−)ราง 5V · ราง GND
กล้อง C270USB-AUSB-C hub/OTG → พอร์ต USB-C ของ UNO Q

เซอร์โวขวาติดตั้งกลับด้านกับตัวซ้าย ไม่ต้องสลับสาย robot_base_servo.ino ตั้ง INVERT_R = true และกลับทิศให้ ส่วนไฟเซอร์โวมาจากตัวแปลงไฟ 5 V ไม่ใช่ขา 5V ของบอร์ด เพราะกระแสกระชากของเซอร์โวสองตัวรวมกันได้ถึงราว 1.8 A

การต่อสายจริงบนหุ่น
การต่อสายจริงจากโปรเจกต์ต้นฉบับ (ใช้ D3/D6 และ power bank ต่างจากหุ่นฐานของรายวิชา ใช้ดูวิธีจัดสายเท่านั้น)
05 / คู่มือ

ติดตั้งซอฟต์แวร์ App Lab

  1. เปิด Arduino App Lab เวอร์ชัน 0.6 ขึ้นไป และเชื่อมต่อ UNO Q
  2. สร้างแอปใหม่ หรือนำเข้าไฟล์จาก GitHub ของโปรเจกต์
  3. ตรวจไฟล์ app.yaml ว่าเลือก brick และโมเดลถูกต้อง
  4. ตรวจไลบรารีใน sketch/sketch.yaml: Arduino_RouterBridge, Servo, MsgPack
  5. กด Run: App Lab จะคอมไพล์ sketch แฟลชลง MCU แล้วเริ่ม main.py
  6. ดู log บรรทัด sample_detections ต้องเห็น label "face" และค่า bounding box ที่สมเหตุสมผล
  7. เปิด Web UI ที่ http://<IP ของ UNO Q>:7000 ต้องเห็นภาพจากกล้องและรายการ detection
name: Detect and follow robocar
bricks:
- arduino:video_object_detection:
    model: face-detection
- arduino:web_ui: {}
detect-and-follow-robocar/
├── app.yaml          # เลือก brick และโมเดล
├── python/main.py    # MPU: ตรวจจับ + ตัวควบคุมการเลี้ยว
├── sketch/sketch.ino # MCU: PWM ให้ servo
└── assets/           # Web UI
06 / คู่มือ

ทดสอบมอเตอร์

  1. วางหุ่นบนกล่องให้ล้อลอยพ้นโต๊ะ
  2. ส่งคำสั่ง drive("T") จาก Python (หรือกด Motor Test ใน Web UI ของภารกิจใบหน้า): ล้อต้องเดินหน้า ถอย หมุนซ้าย หมุนขวา แล้วหยุด
  3. หากล้อยังหมุนช้าๆ ตอนสั่ง S ให้ปรับค่า TRIM_L / TRIM_R ใน robot_base_servo.ino (หรือหมุนสกรูปรับบนตัวเซอร์โว ถ้ามี) จนล้อหยุดสนิท ทดลองหาค่าก่อนได้ในแท็บ "ขับด้วยคำสั่ง" ของแบบ 3 มิติ
  4. หากไม่หมุนเลย ตรวจแรงดันขาออกตัวแปลงไฟ (5.0–5.2 V) ราง 5V/GND สาย GND ร่วม และสายสัญญาณที่ D9/D10
พัลส์ (µs)การทำงานของ servo หมุนต่อเนื่อง
1500หยุด
1000เร็วสุด ทิศทางหนึ่ง
2000เร็วสุด อีกทิศทาง
1500 ± 125ช่วงที่โปรเจกต์ใช้ (MAX_TURN_SPEED = 0.25)
ลองกด Motor Test ในแบบจำลอง 3 มิติ
07 / คู่มือ

ปรับจูนค่า

main.py แปลงตำแหน่งกลางกรอบใบหน้าเป็นคำสั่งเลี้ยวตามลำดับนี้

heading_error = (target_cx - 0.5) * 2.0          # −1 (ซ้ายสุด) … +1 (ขวาสุด)
if abs(heading_error) < CENTER_DEADBAND: heading_error = 0
shaped = copysign(abs(heading_error) ** STEER_CURVE, heading_error)
turn   = clamp(STEER_SIGN * STEER_GAIN * shaped, -MAX_TURN_SPEED, MAX_TURN_SPEED)
left_us  = 1500 + turn * 500
right_us = 1500 - turn * 500
ค่าค่าเริ่มต้นผลเมื่อปรับ
STEER_GAIN0.15มากขึ้น = เลี้ยวเร็วขึ้น แต่เสี่ยงส่ายเลยเป้า
MAX_TURN_SPEED0.25เพดานความเร็วล้อ (~±125 µs) ต้องมากกว่าช่วงตายของ servo
CENTER_DEADBAND0.05มากขึ้น = ยอมให้ใบหน้าเยื้องกลางได้มากขึ้นก่อนเลี้ยว ลดการสั่น
STEER_CURVE0.4ตอบสนองแรงขึ้นเมื่อ error น้อย และนุ่มลงใกล้ขอบภาพ
STEER_SIGN1.0ใช้ −1.0 ถ้าหุ่นหันหนีใบหน้า
DRIVE_BIAS0.0บวก = ค่อยๆ เดินหน้า ลบ = ถอย
TRACKING_TIMEOUT0.5 sเวลาที่ยังเลี้ยวต่อด้วยคำสั่งเดิมเมื่อใบหน้าหายชั่วคราว
FRAME_WIDTH_FALLBACK640ต้องตรงกับความกว้างภาพจริง ไม่อย่างนั้นการเลี้ยวจะเอียงข้าง

ขั้นตอน: เริ่มจากค่าเริ่มต้น เพิ่ม STEER_GAIN ใน Web UI จนหุ่นหันเข้ากลางได้นุ่มนวล ถ้าส่ายซ้าย-ขวาให้ลดลง ได้ค่าที่ดีแล้วจึงแก้ค่าเริ่มต้นใน main.py

ทดลองปรับค่าในแบบจำลอง 3 มิติ
08 / คู่มือ

แก้ปัญหาเบื้องต้น

อาการสาเหตุที่เป็นไปได้วิธีแก้
Web UI เห็น detection แต่ขึ้น “lost target – stopped”TARGET_CLASS ไม่ตรงกับ label ของโมเดลดู log sample_detections แล้วตั้งให้ตรงทุกตัวอักษร
ล้อไม่หมุนเลยไฟ servo สายสัญญาณ หรือ Bridgeส่ง drive("T") เพื่อแยกปัญหา ตรวจตัวแปลงไฟ ราง 5V/GND และ D9/D10
หุ่นหันหนีใบหน้าทิศการเลี้ยวกลับด้านตั้ง STEER_SIGN = -1.0 หรือสลับค่า invert ของล้อ
ส่ายไปมา ไม่นิ่งgain สูงเกินหรือ deadband น้อยเกินลด STEER_GAIN เพิ่ม CENTER_DEADBAND
บอร์ดรีเซ็ตหรือกล้องหลุดตอนล้อเริ่มหมุนกระแสกระชากจาก servoตรวจว่าไฟเซอร์โวมาจากตัวแปลงไฟ ไม่ใช่ขา 5V ของบอร์ด ตรวจตัวเก็บประจุ 470 µF และชาร์จถ่าน 18650 ให้เต็ม
ไม่มีภาพจากกล้องบอร์ดไม่พบกล้องตรวจการเสียบ USB หรือใช้ hub ที่มีไฟเลี้ยง
หยุดฉุกเฉินไม่ทำงานSocket.IO หลุดดูแถบแจ้งข้อผิดพลาดใน Web UI แล้วโหลดหน้าใหม่
09 / คู่มือ

โค้ดตัวอย่าง

ไฟล์อยู่ในโฟลเดอร์ code-examples-face ตรวจโค้ดตามเอกสารแล้ว แต่ยังไม่ได้รันบนบอร์ด UNO Q จริง ไฟล์ .py ที่เป็นตรรกะจำลองรันบนคอมพิวเตอร์ได้

ไฟล์วางที่ใช้กับ
robot_base_servo.inosketch/sketch.inoใช้กับทุกภารกิจ · drive F/B/L/R/S/T · set_wheel_pwm · get_distance · เซอร์โว D9/D10 อัลตราโซนิก D12/D13 · ใบงาน 2.1F, 3.1F
face_follow_sketch.inosketch/sketch.inoไฟล์ต้นฉบับ (D3/D6) เก็บไว้เทียบ · หุ่นฐานใช้ robot_base_servo.ino แทน ซึ่งรับ set_wheel_pwm เหมือนกันที่ D9/D10
face_follow_main.pypython/main.pyฉบับย่อไม่มี Web UI: ตรวจจับ เลี้ยว จำกัดความถี่ watchdog · ใบงาน 3.1F, 4.2F
servo_pulse_test.inosketch/sketch.inoส่งพัลส์ 1300–1700 µs ทีละค่า · ใบงาน 2.2F ตอนที่ 1
steer_calc.pyคอมพิวเตอร์ตรวจผลคำนวณคำสั่งล้อ · ใบงาน 2.2F ตอนที่ 2
decide_distance.pyคอมพิวเตอร์ → main.pyรักษาระยะห่างด้วยขนาดกรอบ · ใบงาน 4.3F
decide_search.pyคอมพิวเตอร์ → main.pystate machine หมุนค้นหา · ใบงาน 4.3F

ฉบับเต็มที่มี Web UI ปรับค่าได้ ใช้ python/main.py จาก GitHub ของโปรเจกต์ต้นฉบับ ซึ่งใช้ sketch เดียวกันนี้ได้

ที่มา: Samuel Alexander, face-following-robot-uno-q (GitHub) · ค่าและโค้ดในคู่มือนี้อ้างอิงจาก README ของโปรเจกต์ ใช้ประกอบรายวิชา ว32210 การออกแบบหุ่นยนต์ขั้นสูง โรงเรียนธัญรัตน์