Thư viện Servo.h: điều khiển góc và xung trên Arduino
Servo.h là thư viện tích hợp sẵn trong Arduino IDE, cho phép điều khiển servo motor (như SG90, MG996R) chỉ với vài dòng code. Bài này tổng hợp API đầy đủ và lưu ý khi dùng nhiều servo cùng lúc.
1. Servo hoạt động thế nào?
Servo chuẩn nhận tín hiệu PWM với chu kỳ 20 ms (50 Hz). Độ rộng xung quy định góc:
- 1.0 ms → góc 0°
- 1.5 ms → góc 90° (giữa)
- 2.0 ms → góc 180°
Servo.h tạo và duy trì xung này tự động qua timer phần cứng, bạn chỉ cần gọi write(angle).
2. API cơ bản
#include
Servo myServo;
void setup() {
myServo.attach(9); // Gán chân 9 (PWM)
myServo.write(90); // Quay đến 90°
}
void loop() {
for (int g = 0; g <= 180; g++) {
myServo.write(g);
delay(15);
}
for (int g = 180; g >= 0; g--) {
myServo.write(g);
delay(15);
}
}
3. Tất cả các hàm
| Hàm | Mô tả |
|---|---|
attach(pin) | Gắn servo vào chân (PWM hoặc bất kỳ digital trên AVR) |
attach(pin, min, max) | Custom xung min/max (µs), mặc định 544/2400 |
write(angle) | Đặt góc 0..180° |
writeMicroseconds(us) | Đặt độ rộng xung trực tiếp (500–2500 µs điển hình) |
read() | Lấy góc cuối cùng đã set |
readMicroseconds() | Lấy xung µs cuối cùng |
attached() | Trả về true nếu đã attach |
detach() | Giải phóng chân (servo ngừng giữ) |
4. Hiệu chuẩn servo SG90 hay MG996R
Servo Trung Quốc thường không đạt đúng dải 0°–180°. Hiệu chuẩn bằng writeMicroseconds():
// SG90 nhiều con chỉ đạt từ 600 đến 2400 µs
myServo.attach(9, 600, 2400);
myServo.write(0); // ép về cuối
Quan trọng: ép servo quá giới hạn cơ học sẽ kêu "rè rè" và nhanh cháy. Tăng từ từ, nghe khi nào sạt thì lùi lại.
5. Nhiều servo cùng lúc
Trên Arduino Uno/Nano, Servo.h dùng Timer1 — tối đa 12 servo. Trên Mega: 48 servo qua 5 timer.
Servo s1, s2, s3;
void setup() {
s1.attach(9);
s2.attach(10);
s3.attach(11);
}
Hệ quả của Timer1: mất chức năng PWM trên chân 9, 10 trên Uno. Nếu cần PWM trên đó, đổi sang chân khác hoặc dùng thư viện ServoESP32 trên ESP32 (không đụng timer).
6. Tránh giật khi attach
Lúc gọi attach(), servo có thể giật mạnh về vị trí ngẫu nhiên — gãy linkage rất nguy hiểm. Đặt giá trị trước khi attach:
myServo.write(90); // Set góc mặc định
myServo.attach(9); // Sau đó mới attach
Hoặc dùng writeMicroseconds(1500) trước.
7. Dòng điện và nguồn nuôi
- SG90: ~250 mA khi quay, 6 mA idle. Có thể chạy từ chân 5V của Arduino.
- MG996R: 2.5 A đỉnh khi tải. PHẢI cấp nguồn ngoài 5V/3A, GND chung với Arduino.
- BLDC + ESC: dùng cách khác hẳn (xem thư viện
ESC).
Cấp servo MG996R bằng cổng USB → Arduino reset liên tục vì sụt áp. Luôn tách nguồn cho servo công suất.
8. ESP32 — dùng thư viện riêng
Servo.h gốc chạy trên ESP32 qua compat layer nhưng không ổn định. Khuyến nghị:
#include // cài qua Library Manager
Servo s;
void setup() {
s.setPeriodHertz(50);
s.attach(13, 500, 2500);
s.write(90);
}
ESP32Servo dùng LEDC PWM channel, không đụng timer hệ thống.
9. Servo liên tục (continuous rotation)
Servo "liên tục" (như SG90 360°) không có vị trí — write() điều khiển tốc độ và chiều:
write(0)— quay full một chiều.write(90)— dừng.write(180)— quay full chiều ngược.
Liên quan
Xem dự án Bàn tay robot 5 ngón điều khiển bằng servo hoặc Robot tránh vật cản HC-SR04. Đọc bài Digital, Analog, PWM nếu chưa rõ tại sao chân ~3, ~5, ~6, ~9, ~10, ~11 dùng được PWM.