ขยับให้เป๊ะ: เซียน Servo Control ด้วย PWM สไตล์รุ่นพี่
Servo motor เนี่ย คือตัวตึงเรื่องการหมุนองศาเป๊ะๆ ในงาน Robot เลยนะน้อง โปรเจกต์นี้พี่จะพาน้องถอดความซับซ้อนของพวก Motor Shield แพงๆ ออกไป แล้วมาลองคุม SG90 Micro-servos 2 ตัว ด้วย Arduino Uno กับ Potentiometer 10k ธรรมดาๆ ดู... ปูพื้นฐาน Mechatronics แบบเท่ๆ จัดไปวัยรุ่น!
Pulse Width Modulation (PWM): สัญญาณสั่งการสุดจ๊าบ
จำไว้ว่า Servo มันไม่ได้กินไฟ DC ดื้อๆ นะ แต่มันคุยด้วยสัญญาณ Digital ที่เรียกว่า PWM (Pulse Width Modulation):
- The Signal Loop: ตัว Servo มันต้องการ Pulse ทุกๆ 20 ms. ความกว้างของ Pulse (ประมาณ 1ms ถึง 2ms) จะบอกตัว Servo Controller ข้างในว่าต้องหมุน Shaft ไปที่กี่องศา (ตั้งแต่ 0 ถึง 180 องศา)
- Firmware Abstraction: ใช้ Library
#include <[Servo](https://s.shopee.co.th/7fUgFAWSki).h>ซะ ชีวิตจะง่ายขึ้นเยอะ เพราะ Arduino จะจัดการเรื่อง Timing ยากๆ ของ Pulse พวกนี้ให้เอง น้องแค่สั่งservo.write(angle)จบเลย หล่อเท่! - Hardware Pins: บน Arduino Uno เราจะใช้ Pins 9 และ 6 เพราะมันมี Hardware-level PWM Timers แยกต่างหาก มอเตอร์จะได้นิ่งๆ ไม่สั่นเวลา CPU กำลังคำนวณ Logic อื่นๆ
Tactical Mapping: เชื่อมต่อโลก Analog เข้ากับ Digital
โปรเจกต์นี้ใช้ Logic การ "Map" ค่าแบบง่ายๆ แต่ทรงพลัง เพื่อเปลี่ยนแรงมือเราให้เป็นการเคลื่อนที่ของหุ่นยนต์:
- Analog Sensing: ต่อ Potentiometer เข้ากับ Analog Pins A0 และ A1 ซึ่งมันจะส่งค่ากลับมาตั้งแต่ 0 ถึง 1023 ตามที่เราหมุน Knob
- Data Transformation: ใช้ฟังก์ชัน
map(val, 0, 1023, 0, 180)เพื่อแปลงค่า 10-bit จาก Analog ให้เหลือแค่ 180 องศา ตามขีดจำกัดของ Servo motor - Real-Time Responsiveness: ใส่
delay(15)ไว้ซักหน่อย เพื่อให้ Servo มีเวลาขยับไปถึงเป้าหมายก่อนจะรับคำสั่งใหม่ จะได้ไม่เกิดอาการ jitter หรืออาการสั่นเป็นเจ้าเข้านั่นแหละน้อง
พื้นฐานสู่ความเทพ
ถึงโปรเจกต์นี้จะดูเป็น "Basics" แต่มันคือรากฐานของ Robotics ขั้นสูงเลยนะ หลักการ Map ค่าจาก Potentiometer ไปยัง Servo แบบนี้แหละ ที่เขาใช้สร้างแขนกลมือเทียม (Prosthetic hands), ระบบ Gimbal คุมกล้อง หรือแม้แต่ "Mimic" Robots ที่ขยับแขนตามคนแบบ Real-time สู้งานนะน้อง!
พี่เคยไปเข้าค่ายเทคโนโลยีเจ๋งๆ มา ได้เรียนทั้ง [Arduino](https://s.shopee.co.th/7fUgFAWSki) และ [Raspberry Pi](https://s.shopee.co.th/6pvZFdZdRf) บอกเลยว่าตอนแรกก็หวานเจี๊ยบสำหรับพี่ เพราะพอมีพื้นฐาน Coding กับ Debugging มาบ้าง แต่พอเห็นเพื่อนๆ หลายคนยังงงเรื่องพื้นฐาน พี่เลยจัดโปรเจกต์เล็กๆ นี้ขึ้นมาแชร์ให้ดูกัน
จริงๆ โปรเจกต์นี้เป็นแค่ส่วนเสี้ยวหนึ่งของโปรเจกต์ยักษ์ที่พี่กำลังทำอยู่ แต่มันอธิบายการทำงานพื้นฐานของ [Servo](https://s.shopee.co.th/7fUgFAWSki) motor ที่คุมด้วย Pot ได้ดีมาก มาดูการต่อ Pins ของโปรเจกต์นี้กัน:
- ขากลางของ Pot 1 - ต่อเข้า A0
- ขากลางของ Pot 2 - ต่อเข้า A1
- สายสีแดงของ Servo 1 และ 2 - ต่อเข้า 5V
- สายสีน้ำตาลของ Servo 1 และ 2 - ต่อเข้า GND (ห้ามช็อตนะตัวนี้)
- สายสีเหลืองของ Servo 1 - ต่อเข้า Pin 9
- สายสีเหลืองของ Servo 2 - ต่อเข้า Pin 6
เราต่อสายสีเหลือง (Pulse Pin) เข้าที่ Pin 9 และ 6 เพราะมันคือ Pins ที่รองรับ PWM (Pulse Width Modulation) ซึ่งเป็นเทคนิคการสร้างสัญญาณ Analog จากขา Digital โดยการสร้างคลื่นสี่เหลี่ยมสลับ On และ Off เพื่อจำลองแรงดันไฟระหว่าง 0 ถึง 5V ถ้าเราปรับช่วงเวลา "On" (เรียกว่า Pulse Width) ให้เร็วพอ ผลลัพธ์ที่ได้ก็จะเหมือนเราคุมความสว่าง LED หรือคุมองศา Servo นั่นแหละน้อง หลักการเดียวกันเป๊ะ!
อธิบาย Code แบบเน้นๆ:
#include
Servo servo1 และ Servo servo2 - ประกาศชื่อตัวแปรให้ Servo แต่ละตัว
int Pot1 และ int Pot2 - กำหนด Pin ของ Potentiometer
int valPot1 และ int valPot2 - สร้าง Variable ไว้เก็บค่าที่อ่านได้จาก Pot
servo1.attach(9); - สั่งให้ Arduino รู้ว่า Servo ตัวนี้ต่ออยู่ที่ Pin 9 (PWM)
[ valPot1 = analogRead(pot1);
valPot1 = map(valPot1, 0, 1023, 0, 180);
servo1.write(valPot1);
delay(15); ]
ท่อนนี้คือการอ่านสัญญาณ Analog จาก Pot แล้วแปลงค่าส่งไปให้ Servo ขยับตามนั่นเอง ง่ายๆ แค่นี้แหละ ลองไปลุยดู!