Điều khiển động cơ RC servo bằng PWM: chu kỳ, độ rộng xung và cách tạo xung bằng timer
Điều khiển động cơ RC servo bằng PWM nghe thì đơn giản: cứ 20 ms gửi một xung dài khoảng 1–2 ms, trục servo sẽ quay tới góc tương ứng. Nhưng phần lớn sự cố khi tự làm (servo rung khi đứng yên, dồn về một đầu rồi kêu rè, góc lệch, servo nóng) đều do hiểu sai bản chất tín hiệu: nhầm độ rộng xung với duty cycle, chọn sai tần số khung, timer thiếu độ phân giải hoặc xung bị rung (jitter).
Dưới đây là những điểm cốt lõi của tín hiệu điều khiển RC servo: dạng sóng chuẩn, tần số khung, deadband, mức logic, cách tính prescaler cho timer phần cứng, mạch 555, cách đo kiểm và các giao thức thay thế.
Nội dung
- 1. Tín hiệu PWM điều khiển RC servo là gì?
- 2. Tần số khung: 50 Hz cho servo analog, 200–333 Hz cho servo số
- 3. Deadband, độ phân giải và độ chính xác của xung
- 4. Mức logic 3,3 V và 5 V trên dây tín hiệu servo
- 5. Tạo PWM servo bằng timer phần cứng: cách tính prescaler và TOP
- 6. Mạch tạo xung servo bằng IC 555 không cần vi điều khiển
- 7. Đo kiểm tín hiệu PWM servo bằng máy hiện sóng và đồng hồ đo
- 8. Servo 360°: độ rộng xung điều khiển tốc độ, không phải góc
- 9. Giao thức thay thế PWM: PPM, SBUS và xung hẹp 760 µs
- 10. Quy trình xác định dải xung an toàn cho một servo chưa rõ thông số
- 11. Câu hỏi thường gặp về điều khiển động cơ RC servo bằng PWM
- 12. Kết luận
1. Tín hiệu PWM điều khiển RC servo là gì?
Tín hiệu điều khiển RC servo là một chuỗi xung vuông lặp lại, mỗi khung (frame) dài khoảng 20 ms, tức tần số 50 Hz. Trong mỗi khung có một xung mức cao rộng từ khoảng 1 ms đến 2 ms. Mạch bên trong servo đo độ rộng xung, so với vị trí thực của trục (biến trở phản hồi) rồi quay motor cho tới khi hai giá trị khớp nhau.
Dải danh nghĩa 1,0–2,0 ms thường ứng với khoảng 90° hành trình, còn 1,5 ms là vị trí giữa. Phần lớn servo hiện nay quay được rộng hơn, khoảng 180°, khi xung kéo dài ra 500–2500 µs. Bảng dưới chỉ mang tính tham khảo:
| Độ rộng xung | Vị trí trục (servo 180° điển hình) | Duty cycle ở 50 Hz |
| 500 µs | Khoảng 0° (một đầu hành trình) | 2,5 % |
| 1000 µs | Khoảng 45° | 5,0 % |
| 1500 µs | 90° (vị trí giữa) | 7,5 % |
| 2000 µs | Khoảng 135° | 10,0 % |
| 2500 µs | Khoảng 180° (đầu còn lại) | 12,5 % |
Độ rộng xung quyết định góc, không phải duty cycle
Servo chỉ đo thời gian mức cao tính bằng micro giây, gần như không quan tâm khoảng nghỉ mức thấp. Xung 1500 µs lặp ở 50 Hz (duty 7,5 %) và xung 1500 µs lặp ở 333 Hz (duty khoảng 50 %) đều đưa servo số về cùng vị trí giữa. Vì vậy hãy luôn tính theo micro giây rồi mới quy đổi sang thanh ghi; nếu đổi tần số khung mà giữ nguyên phần trăm duty, góc servo sẽ đổi theo.
Cũng vì lý do đó, tín hiệu servo khác hẳn PWM điều khiển tốc độ motor DC thông thường. Với bộ điều tốc motor dùng cho motor chổi than, duty cycle chính là đại lượng điều khiển và tần số thường vài kHz trở lên; đưa loại PWM đó vào chân tín hiệu servo, servo sẽ không hiểu.
2. Tần số khung: 50 Hz cho servo analog, 200–333 Hz cho servo số
Servo analog cấp năng lượng cho motor theo từng xung nhận được. Chạy servo analog ở 333 Hz làm motor bị "đẩy" dày gấp khoảng 6–7 lần so với 50 Hz, servo nóng nhanh, dòng tĩnh tăng, nhiều mẫu dao động quanh điểm đặt. Servo analog phổ thông như SG90 nên giữ 50 Hz.
Servo số (digital) có vi điều khiển riêng tự chạy vòng điều khiển ở tần số cao, tín hiệu PWM chỉ là "lệnh vị trí", nên gửi lệnh dày hơn giúp phản hồi nhanh hơn. Nhiều servo số chấp nhận 200 Hz hoặc 333 Hz; mức tối đa lấy theo thông số của chính servo đó.
Lưu ý với 333 Hz: chu kỳ chỉ còn 3000 µs, nếu ra lệnh xung 2500 µs thì khoảng nghỉ chỉ còn 500 µs. Vì vậy dải xung thường phải thu hẹp khi chạy tần số cao.
3. Deadband, độ phân giải và độ chính xác của xung
Deadband (vùng chết) là gì?
Deadband là mức thay đổi độ rộng xung nhỏ nhất khiến servo phản ứng. Ví dụ thông số MG996R và Hitec HS-311 ghi deadband 5 µs: xung thay đổi dưới 5 µs, servo đứng yên; thay đổi lớn hơn thì servo mới chỉnh vị trí. Servo số tốt thường có deadband 1–2 µs.
Quy đổi micro giây sang độ
Với HS-311, nhà sản xuất cho biết dịch 400 µs về một phía thì trục đi 40°, tức khoảng 0,1°/µs. Một servo 180° dùng dải 500–2500 µs có độ nhạy khoảng 180° / 2000 µs = 0,09°/µs. Như vậy deadband 5 µs tương đương khoảng 0,45–0,5° – đó là giới hạn chính xác lý thuyết, chưa kể khe hở bánh răng.
Độ phân giải timer cần bao nhiêu?
Quy tắc thực tế: bước nhỏ nhất của timer nên bằng hoặc nhỏ hơn deadband của servo, lý tưởng là 1 µs hoặc nhỏ hơn. Nếu bước timer là 64 µs (ví dụ timer 8 bit chia 1024 trên chip 16 MHz), toàn dải 1–2 ms chỉ còn khoảng 16 nấc, servo nhảy từng bậc hơn 5°. Timer bước 0,5 µs cho tới 2000 nấc trong cùng dải.
Jitter – kẻ thù của servo đứng yên
Jitter là sự dao động ngẫu nhiên của độ rộng xung giữa các khung. Nếu xung dao động ±10 µs trong khi deadband chỉ 2–5 µs, servo sẽ liên tục chỉnh qua lại, phát tiếng rè nhỏ, nóng lên và mòn bánh răng dù không có tải. Jitter thường do tạo xung bằng phần mềm hoặc trên hệ điều hành đa nhiệm như Linux; khối PWM của timer phần cứng gần như loại bỏ hoàn toàn vấn đề này.
4. Mức logic 3,3 V và 5 V trên dây tín hiệu servo
Dây tín hiệu servo là ngõ vào logic trở kháng cao, ngưỡng mức cao của đa số servo khoảng 2 V hoặc thấp hơn, nên phần lớn servo chạy tốt với tín hiệu 3,3 V từ ESP32, STM32, Raspberry Pi hay RP2040 dù servo cấp nguồn 5–6 V. Một số ít servo đòi biên độ cao hơn và phản ứng chập chờn với 3,3 V.
Khi gặp trường hợp đó, có ba cách nâng mức tín hiệu lên 5 V:
- Dùng IC đệm không đảo cấp nguồn 5 V như 74HCT125, 74HCT541 hoặc 74LVC1G17: gọn và chắc chắn nhất.
- Dùng một transistor NPN (BC547, 2N3904) mắc phát chung: đơn giản nhưng đảo pha, phải cấu hình timer ở chế độ PWM đảo.
- Cấu hình chân vi điều khiển ở chế độ open-drain có điện trở kéo lên 5 V, chỉ áp dụng với chân có ghi chịu được 5 V (5V-tolerant) trong datasheet.
Ngoài ra nên có ba chi tiết nhỏ trên dây tín hiệu:
- Điện trở nối tiếp 220–470 Ω gần chân vi điều khiển để hạn dòng khi servo được cấp nguồn trước.
- Điện trở kéo xuống 10 kΩ về GND để giữ mức thấp lúc vi điều khiển khởi động; chân "thả nổi" khiến servo nhận xung rác và giật mạnh khi cấp điện.
- GND nguồn servo nối chung với GND mạch tạo xung, nếu không xung mất điểm tham chiếu.
5. Tạo PWM servo bằng timer phần cứng: cách tính prescaler và TOP
Mọi khối PWM phần cứng đều hoạt động theo cùng một nguyên tắc: xung nhịp timer (f_clk) đi qua bộ chia trước (prescaler), bộ đếm đếm từ 0 lên tới giá trị TOP (còn gọi là ARR, period, wrap) rồi quay về 0. Tần số khung và bước thời gian được tính như sau:
- Tần số PWM: f_pwm = f_clk / ((PSC + 1) × (TOP + 1))
- Bước thời gian một nấc đếm: t_tick = (PSC + 1) / f_clk
- Giá trị so sánh (compare) cho xung t: CMP = t / t_tick
Mẹo chọn nhanh: chọn prescaler sao cho một nấc đếm đúng 1 µs hoặc 0,5 µs, khi đó giá trị compare chính là độ rộng xung tính theo micro giây (hoặc gấp đôi), rất dễ đọc và dễ kiểm tra. Các ví dụ dưới đây đều đã được tính lại theo công thức trên.
a. AVR ATmega328P (Arduino Uno, Nano): Timer1 16 bit
Với thạch anh 16 MHz, chọn prescaler 8 thì timer đếm ở 2 MHz, mỗi nấc 0,5 µs. Để có 50 Hz, TOP = 16 000 000 / (8 × 50) − 1 = 39 999, nạp vào thanh ghi ICR1 ở chế độ Fast PWM số 14 (WGM13:10 = 1110). Giá trị so sánh OCR1A = 2 × t (µs), ví dụ 1500 µs ứng với 3000.
// ATmega328P 16 MHz - Timer1 Fast PWM mode 14, TOP = ICR1
// OC1A = chân PB1 (D9), OC1B = chân PB2 (D10)
void servoPwmInit() {
DDRB |= (1 << PB1) | (1 << PB2); // D9, D10 là ngõ ra
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); // prescaler 8
ICR1 = 39999; // 2 MHz / 40000 = 50 Hz
OCR1A = 3000; // 1500 us
OCR1B = 3000;
}
void servoA_us(uint16_t us) { OCR1A = us * 2; } // 0,5 us mỗi nấc| Độ rộng xung | OCR1A (bước 0,5 µs) |
| 500 µs | 1000 |
| 1000 µs | 2000 |
| 1500 µs | 3000 |
| 2000 µs | 4000 |
| 2500 µs | 5000 |
Ở chế độ Fast PWM không đảo, chân ra ở mức cao trong (OCR1A + 1) nấc, tức dài hơn 0,5 µs so với tính toán – nhỏ hơn deadband của mọi servo nên có thể bỏ qua. Muốn chạy servo số ở 200 Hz, đổi ICR1 = 9999 (2 MHz / 10 000 = 200 Hz), OCR1A giữ nguyên.
Timer0 và Timer2 chỉ có 8 bit nên không phù hợp: prescaler 1024 cho khoảng 61 Hz, mỗi nấc 64 µs, cả dải 1–2 ms chỉ còn khoảng 16 nấc. Cách dùng thư viện Servo.h (cũng chiếm Timer1) có trong bài điều khiển động cơ servo bằng Arduino.
b. STM32: chọn PSC để có nấc 1 µs
Trên STM32, xung nhịp cấp cho timer phụ thuộc cây xung nhịp (bus APB và hệ số nhân timer), vì vậy hãy xem giá trị thực trong CubeMX trước khi tính. Chọn PSC = f_timer(MHz) − 1 để timer đếm ở 1 MHz, sau đó ARR = 19 999 cho 50 Hz, CCR bằng đúng độ rộng xung tính bằng µs.
| Chip / xung nhịp timer | PSC | ARR (50 Hz) | ARR (333 Hz) | CCR cho 1500 µs |
| STM32F103, 72 MHz | 71 | 19999 | 2999 | 1500 |
| STM32F401, 84 MHz | 83 | 19999 | 2999 | 1500 |
| STM32F407 (timer APB2), 168 MHz | 167 | 19999 | 2999 | 1500 |
Kiểm tra lại: 72 MHz / (71 + 1) = 1 MHz; 1 MHz / (19 999 + 1) = 50 Hz; 1 MHz / 3000 = 333,3 Hz. Với HAL, sau khi cấu hình kênh ở chế độ PWM Generation, chỉ cần:
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 1500); // 1500 usCác kênh trên cùng timer dùng chung ARR nên phải cùng tần số khung. Nên bật preload (ARPE, OCxPE) để giá trị mới chỉ áp dụng từ khung kế tiếp, tránh xung bị cắt ngang.
c. ESP32: bộ PWM LEDC
ESP32 không có timer PWM kiểu AVR mà dùng khối LEDC. Tần số được tính xấp xỉ: f ≈ f_clk / (bộ chia × 2^độ_phân_giải). Với servo, độ phân giải 14 bit là lựa chọn an toàn vì ESP32-S3, C3, C6 giới hạn tối đa 14 bit (ESP32 đời đầu cho tới 20 bit). Ở 50 Hz, 14 bit cho 16 384 nấc trên 20 000 µs, mỗi nấc khoảng 1,22 µs.
Giá trị duty = t (µs) × 2^bit / 20 000:
| Độ rộng xung | Duty 14 bit (ESP32 mọi dòng) | Duty 16 bit (ESP32 đời đầu) |
| 500 µs | 410 | 1638 |
| 1000 µs | 819 | 3277 |
| 1500 µs | 1229 | 4915 |
| 2000 µs | 1638 | 6554 |
| 2500 µs | 2048 | 8192 |
Với Arduino-ESP32 phiên bản 3.x, API gắn theo chân:
const int PIN = 18;
void setup() {
ledcAttach(PIN, 50, 14); // 50 Hz, 14 bit
}
void servo_us(uint32_t us) {
ledcWrite(PIN, (us * 16384UL) / 20000); // 1500 us -> 1229
}Bản 2.x dùng ledcSetup(kênh, tần số, bit) và ledcAttachPin(chân, kênh). Đừng chọn 8 bit cho servo: mỗi nấc tới 78 µs, và nhiều dòng ESP32 không tạo được 50 Hz ở 8 bit vì bộ chia chạm giới hạn.
d. Raspberry Pi Pico (RP2040/RP2350)
Khối PWM của RP2040 có bộ chia phân số và bộ đếm 16 bit. Với xung nhịp hệ thống 125 MHz, đặt bộ chia = 125 thì mỗi nấc 1 µs; wrap = 19 999 cho 50 Hz; mức so sánh bằng số micro giây. Trên Pico 2 (RP2350, 150 MHz) đặt bộ chia = 150. Trong MicroPython, việc tính toán được làm sẵn:
from machine import Pin, PWM
s = PWM(Pin(15))
s.freq(50)
s.duty_ns(1500000) # 1500 us = 1 500 000 nsNên dùng duty_ns() thay vì duty_u16() vì nó làm việc trực tiếp với độ rộng xung, đổi tần số khung không làm lệch góc.
e. Raspberry Pi chạy Linux: PWM cứng, pigpio và PWM mềm
Raspberry Pi có hai kênh PWM phần cứng, đưa ra các chân GPIO12, GPIO13, GPIO18, GPIO19 (GPIO12 và GPIO18 dùng chung một kênh, GPIO13 và GPIO19 dùng chung kênh còn lại). Thư viện RPi.GPIO và một số cấu hình gpiozero tạo PWM bằng phần mềm, độ rộng xung dao động theo tải CPU – nguyên nhân phổ biến nhất khiến servo nối Raspberry Pi rung giật. Ba hướng khắc phục:
- Dùng PWM cứng qua sysfs: thêm
dtoverlay=pwm-2chanvào config.txt (mặc định ra GPIO18 và GPIO19), sau đó ghi chu kỳ và độ rộng xung theo nano giây. - Dùng daemon pigpio (Pi 4 trở về trước): set_servo_pulsewidth nhận 500–2500 µs ở 50 Hz, định thời bằng DMA nên ổn định, dùng được trên mọi GPIO. pigpio không hỗ trợ Raspberry Pi 5.
- Dùng mạch PWM ngoài như PCA9685 qua I2C (xem mục f).
Ví dụ PWM cứng qua sysfs cho xung 1500 µs ở 50 Hz:
cd /sys/class/pwm/pwmchip0
echo 0 > export
echo 20000000 > pwm0/period # 20 ms = 20 000 000 ns
echo 1500000 > pwm0/duty_cycle # 1500 us
echo 1 > pwm0/enableTrên Raspberry Pi 5, số pwmchip và số kênh có thể khác, hãy liệt kê thư mục /sys/class/pwm để xác định trước khi ghi.
f. Chip PCA9685: PWM 12 bit qua I2C
PCA9685 là IC tạo 16 kênh PWM 12 bit, nhận lệnh qua I2C và tự phát xung liên tục. Mặt dưới module có in rõ dải tần làm việc và mức điện áp, như ảnh dưới đây.

Tần số PWM được đặt bằng thanh ghi PRE_SCALE theo công thức: prescale = round(f_osc / (4096 × f)) − 1. Với dao động nội danh định 25 MHz và f = 50 Hz: 25 000 000 / (4096 × 50) = 122,07, làm tròn 122, trừ 1 được prescale = 121. Tần số thực khi đó là 25 000 000 / (4096 × 122) ≈ 50,03 Hz, chu kỳ khoảng 19 988 µs, mỗi nấc khoảng 4,88 µs. Prescale cho phép từ 3 đến 255, tương ứng khoảng 1526 Hz xuống khoảng 24 Hz.
| Độ rộng xung | Giá trị OFF (bắt đầu ON = 0), 50 Hz |
| 500 µs | 102 |
| 1000 µs | 205 |
| 1500 µs | 307 |
| 2000 µs | 410 |
| 2500 µs | 512 |
Dao động nội PCA9685 không chính xác 25 MHz
Dao động nội của nhiều module đo được khoảng 26–27 MHz. Khi đó prescale 121 cho ra khoảng 54 Hz, các xung theo bảng trên ngắn hơn dự kiến khoảng 7–8 %, servo không tới hết hành trình. Cách xử lý là đo tần số ngõ ra, tính ngược f_osc thực = f_đo × 4096 × (prescale + 1), rồi dùng giá trị này trong công thức. Thư viện Adafruit PWM Servo Driver có hàm setOscillatorFrequency() để hiệu chuẩn. Ví dụ với f_osc thực 27 MHz, prescale = round(27 000 000 / 204 800) − 1 = 131, tần số ra khoảng 49,94 Hz.
Mặt trước module có cầu đấu nguồn servo V+, tụ lọc và các pad hàn chọn địa chỉ I2C.

Ở 50 Hz, nấc 4,88 µs của PCA9685 xấp xỉ deadband của servo analog nên đủ dùng. Với servo số, tăng tần số lên 200 Hz sẽ rút nấc xuống khoảng 1,22 µs, chuyển động mịn hơn. Cả 16 kênh dùng chung một tần số, nên không trộn servo analog và servo số chạy 200 Hz trên cùng chip.
6. Mạch tạo xung servo bằng IC 555 không cần vi điều khiển
Khi chỉ cần chỉnh góc servo bằng tay, một IC 555 mắc dao động đa hài là đủ. Mạch 555 cơ bản luôn có mức cao dài hơn mức thấp, trong khi servo cần mức cao ngắn (1–2 ms) và mức thấp dài (khoảng 18 ms). Cách giải quyết là thêm một diode (1N4148) song song với RB để tụ nạp chỉ qua RA và xả chỉ qua RB:
- Thời gian mức cao: t_H ≈ 0,693 × RA × C
- Thời gian mức thấp: t_L ≈ 0,693 × RB × C
Chọn C = 100 nF (tụ phim hoặc gốm ổn định nhiệt):
| Linh kiện | Giá trị | Kết quả tính |
| RA = 12 kΩ + biến trở 20 kΩ (mắc kiểu chiết áp biến trở) | 12–32 kΩ | t_H ≈ 0,83–2,22 ms |
| RB | 270 kΩ | t_L ≈ 18,7 ms |
| Chu kỳ khung | Khoảng 19,5–20,9 ms (khoảng 48–51 Hz) |
Kiểm tra: 0,693 × 12 000 × 100 × 10⁻⁹ = 0,83 ms; 0,693 × 32 000 × 100 × 10⁻⁹ = 2,22 ms; 0,693 × 270 000 × 100 × 10⁻⁹ = 18,7 ms. Chu kỳ khung thay đổi nhẹ theo biến trở nhưng không ảnh hưởng góc.
Vài lưu ý khi lắp mạch:
- Điện áp rơi trên diode làm t_H thực tế dài hơn tính toán một chút; đo lại và chỉnh RA cố định để dải xung không vượt hành trình servo.
- Nên dùng bản CMOS (TLC555, ICM7555) vì ngõ ra lên sát nguồn; đặt tụ 100 nF sát chân nguồn 555 và tụ 100–470 µF trên nguồn servo để dòng khởi động servo không kéo lệch thời gian.
- Phương án chính xác hơn là IC 556: nửa thứ nhất tạo nhịp 50 Hz, nửa thứ hai mắc đơn ổn với t = 1,1 × R × C. Với C = 100 nF, R = 8,2 kΩ + biến trở 10 kΩ cho t ≈ 0,90–2,0 ms.
7. Đo kiểm tín hiệu PWM servo bằng máy hiện sóng và đồng hồ đo
Trước khi nối servo đắt tiền, hãy đo tín hiệu. Chỉ cần ba thông số: biên độ (V), chu kỳ khung (ms hoặc Hz) và độ rộng xung (µs).
Máy hiện sóng (oscilloscope)
Đặt 5 ms/ô để đo chu kỳ, rồi 500 µs/ô và dùng phép đo +Width để đọc độ rộng xung. Bật chế độ lưu vệt (persistence): cạnh xuống "nhòe" thành một dải thì độ rộng dải đó chính là jitter.
Máy phân tích logic giá rẻ
Bộ phân tích logic 8 kênh 24 MHz kết hợp PulseView/sigrok đo độ rộng xung với độ phân giải khoảng 0,04 µs, tiện khi kiểm tra nhiều kênh hoặc giải mã PPM, SBUS.
Đồng hồ vạn năng có thang Hz và %
Thang Hz phải đọc khoảng 50 Hz (hoặc 200, 333 Hz). Thang % cho phép suy ra độ rộng xung: t = duty × chu kỳ. Ví dụ đọc 7,5 % ở 50 Hz nghĩa là 0,075 × 20 ms = 1,5 ms.
Đồng hồ chỉ có thang điện áp DC
Đo điện áp DC trung bình giữa dây tín hiệu và GND: V_tb ≈ V_cao × duty. Với tín hiệu 5 V ở 50 Hz, xung 1,5 ms cho khoảng 0,375 V; xung 1 ms cho 0,25 V; xung 2 ms cho 0,5 V. Với tín hiệu 3,3 V, các con số tương ứng là 0,25 V, 0,165 V và 0,33 V. Cách này chỉ để kiểm tra xung có nằm đúng vùng hay không.
8. Servo 360°: độ rộng xung điều khiển tốc độ, không phải góc
Servo quay liên tục (FS90R, FS5103R, MG996R bản 360°) đã bị bỏ liên kết giữa trục ra và biến trở phản hồi. Mạch điều khiển vẫn hiểu xung như cũ nhưng không bao giờ "tới đích", nên:
- Khoảng 1500 µs: đứng yên.
- Xung ngắn hơn 1500 µs: quay một chiều, càng ngắn càng nhanh.
- Xung dài hơn 1500 µs: quay chiều ngược lại, càng dài càng nhanh.
Với FS90R, 1000 µs và 2000 µs là tốc độ tối đa hai chiều, khoảng 110 vòng/phút ở 4,8 V và 130 vòng/phút ở 6 V khi không tải. Quan hệ xung – tốc độ không tuyến tính và có vùng chết khá rộng quanh điểm dừng.
Điểm dừng thực tế hiếm khi đúng 1500 µs. Nếu servo bò chậm khi ra lệnh dừng, có hai cách: chỉnh biến trở trim (lỗ nhỏ ở vỏ, nếu có) trong khi đang gửi xung 1500 µs cho tới khi trục đứng yên, hoặc dò bằng phần mềm – tăng giảm xung từng 2–5 µs để tìm vùng dừng rồi lấy giá trị giữa vùng.
Servo 360° không có phản hồi vị trí, không thể điều khiển "quay đúng 3 vòng" chỉ bằng thời gian. Khi cần vị trí hoặc tốc độ chính xác, nên dùng motor DC có encoder hoặc các loại motor 12V kèm cảm biến và mạch điều khiển vòng kín.
9. Giao thức thay thế PWM: PPM, SBUS và xung hẹp 760 µs
a. PPM (CPPM)
PPM ghép nhiều kênh vào một dây: mỗi kênh là khoảng 1–2 ms giữa hai xung phân cách ngắn, sau kênh cuối là khoảng nghỉ dài để đồng bộ. Khung phổ biến dài 22,5 ms, tối đa 8 kênh. PPM không đưa thẳng vào servo mà dùng giữa receiver và mạch bay hoặc vi điều khiển, sau đó tách lại thành từng tín hiệu PWM.
b. SBUS
SBUS là giao thức nối tiếp số: UART 100 000 baud, 8 bit dữ liệu, parity chẵn, 2 bit stop (8E2), mức logic bị đảo. Mỗi khung 25 byte bắt đầu bằng byte 0x0F, chứa 16 kênh tỷ lệ mỗi kênh 11 bit và 2 kênh số, gửi lại sau mỗi 14 ms (chế độ thường) hoặc 7 ms (chế độ nhanh). Giá trị 11 bit thường được tay khiển phát trong khoảng 172–1811, quy đổi xấp xỉ 988–2012 µs. Đọc SBUS cần UART hỗ trợ đảo mức hoặc một transistor đảo bên ngoài.
c. Servo xung hẹp 760 µs
Một số servo đuôi trực thăng dùng chuẩn xung hẹp với điểm giữa 760 µs thay cho 1500 µs, kết hợp tần số khung cao để phản ứng nhanh. Không bao giờ cấp xung chuẩn 1500 µs cho servo 760 µs: lệnh này nằm xa ngoài dải, servo sẽ dồn hết về một đầu, đè vào cữ chặn cơ khí và có thể hỏng. Gyro hoặc bộ điều khiển bay luôn có tùy chọn chọn điểm giữa 760 µs hoặc 1520/1500 µs, phải chọn đúng trước khi lắp servo.
10. Quy trình xác định dải xung an toàn cho một servo chưa rõ thông số
Thay vì ra lệnh thẳng 500 µs hoặc 2500 µs cho servo không rõ thông số, hãy dò theo các bước:
1) Tháo cần servo (horn) hoặc để trục quay tự do, không lắp vào cơ cấu.
2) Cấp nguồn có giới hạn dòng (khoảng 1 A cho servo micro, 2–3 A cho servo standard).
3) Phát xung 1500 µs ở 50 Hz, kiểm tra servo đứng yên ở giữa, không rung.
4) Giảm dần xung mỗi bước 20–50 µs. Khi trục ngừng quay thêm, hoặc nghe tiếng rè và dòng tăng vọt, đó là cữ chặn; lùi lại 30–50 µs và ghi làm giới hạn dưới.
5) Làm tương tự phía xung dài để tìm giới hạn trên.
6) Đo góc thực ở hai giới hạn, tính hệ số °/µs cho servo đó.
Với servo 1,0–2,0 ms danh nghĩa, giới hạn tìm được thường nằm khoảng 600–2400 µs; nhưng có servo chỉ chịu được 900–2100 µs. Cách chọn servo theo mô-men, tốc độ, điện áp có trong bài điều khiển động cơ RC servo.
Cách điều khiển này chỉ áp dụng cho RC servo nhỏ. Các bộ motor servo AC công nghiệp cũng nhận "xung" nhưng là chuỗi xung vị trí (xung + hướng, hàng trăm kHz), hoàn toàn khác PWM 50 Hz của RC servo.
11. Câu hỏi thường gặp về điều khiển động cơ RC servo bằng PWM
Tín hiệu PWM điều khiển RC servo có tần số bao nhiêu?
Chuẩn là 50 Hz, tức một xung mỗi 20 ms, ứng với duty 7,5 % khi xung 1,5 ms. Servo số thường chấp nhận 200 Hz hoặc 333 Hz, servo analog nên giữ 50 Hz để không nóng.
Có dùng analogWrite() của Arduino để điều khiển servo được không?
Không. analogWrite() trên Uno xuất PWM khoảng 490 Hz hoặc 980 Hz, chu kỳ chỉ 1–2 ms, servo không nhận ra khung 20 ms và có thể giật hoặc đè về một đầu. Phải dùng timer 16 bit cấu hình 50 Hz.
Xung 1500 µs có luôn là vị trí giữa chính xác không?
Gần đúng nhưng không tuyệt đối. Futaba lấy điểm giữa 1520 µs, JR/Spektrum lấy 1500 µs, và sai số cơ khí của từng servo cũng làm lệch vài độ. Hãy chỉnh điểm giữa bằng phần mềm thay vì lắp lệch răng cần servo.
Vi điều khiển 3,3 V có điều khiển trực tiếp RC servo được không?
Có, trong đa số trường hợp. Ngưỡng mức cao của phần lớn servo khoảng 2 V hoặc thấp hơn nên tín hiệu 3,3 V đủ dùng. Nếu servo phản ứng chập chờn, thêm IC đệm 74HCT125 cấp 5 V để nâng mức tín hiệu.
Vì sao servo rung nhẹ, kêu rè khi đứng yên dù không có tải?
Thường do xung bị jitter vượt quá deadband của servo. PWM mềm trên Raspberry Pi hoặc nhiễu nguồn thường gây ra; chuyển sang PWM phần cứng và kiểm tra bằng máy hiện sóng.
Ra lệnh xung 500–2500 µs có an toàn với mọi servo không?
Không. Nhiều servo chỉ đi được khoảng 600–2400 µs hoặc hẹp hơn; vượt quá thì servo đè vào cữ chặn, dòng tăng cao, dễ hỏng bánh răng hoặc mạch.
Khi ngừng phát xung PWM, servo sẽ làm gì?
Tùy loại. Servo analog thường thả lỏng motor ngay; servo số có thể giữ vị trí cuối hoặc thả lỏng tùy hãng và cấu hình. Với servo 360°, ngừng phát xung là cách dừng chắc chắn nhất.
Đo độ rộng xung có biết được góc thực của servo không?
Không. Xung chỉ là lệnh góc; nếu servo bị kẹt, quá tải hoặc thiếu nguồn, trục không tới vị trí đã ra lệnh mà tín hiệu vẫn y nguyên. Muốn biết vị trí thực phải dùng servo có dây phản hồi hoặc gắn cảm biến góc riêng.
Timer cần độ phân giải bao nhiêu để điều khiển servo mịn?
Khoảng 1 µs mỗi nấc là lý tưởng, tối đa nên bằng deadband của servo (khoảng 2–5 µs).
Raspberry Pi có bao nhiêu kênh PWM phần cứng cho servo?
Hai kênh độc lập, đưa ra các chân GPIO12, GPIO13, GPIO18, GPIO19 (từng cặp dùng chung kênh). Cần nhiều kênh hơn thì dùng PCA9685.
Một chân PWM có thể điều khiển nhiều servo cùng lúc không?
Có, nếu các servo cần cùng một góc. Ngõ vào servo trở kháng cao nên nối song song dây tín hiệu được, miễn nguồn đủ dòng; muốn mỗi servo một góc thì cần kênh riêng.
Vì sao servo quay hết về một đầu và đứng im kêu khi vừa cấp xung?
Thường do độ rộng xung nằm ngoài dải: tính sai prescaler/TOP, nhầm đơn vị (nano giây với micro giây), dùng phần trăm duty cố định sau khi đổi tần số, hoặc cấp xung chuẩn cho servo xung hẹp 760 µs.
12. Kết luận
Điều khiển động cơ RC servo bằng PWM xoay quanh ba con số: chu kỳ khung (20 ms với servo analog), độ rộng xung (500–2500 µs, giữa 1500 µs) và độ ổn định của xung (jitter nhỏ hơn deadband). Nắm công thức f_pwm = f_clk / ((PSC + 1) × (TOP + 1)) và chọn bước đếm 0,5–1 µs, việc tạo xung trên mọi vi điều khiển chỉ còn là điền đúng thanh ghi. Luôn đo tín hiệu trước khi nối servo và dò dải xung an toàn cho từng mẫu.






