Atlas Robotics
Điều khiển động cơCơ bản

Encoder là gì? Đôi mắt đo tốc độ và vị trí của động cơ

Atlasbot · 16/8/2026 · 11 phút đọc

Encoder là gì? Đôi mắt đo tốc độ và vị trí của động cơ
Encoder tương đối (incremental) và tín hiệu vuông pha A/B

Đặt cùng một giá trị PWM cho động cơ khi robot chạy trên sàn phẳng và khi leo dốc, tốc độ quay thực tế sẽ khác nhau — PWM chỉ điều khiển điện áp trung bình đặt vào động cơ, không đảm bảo tốc độ quay thực tế. Muốn biết chính xác động cơ đang quay bao nhiêu vòng/giây, hoặc trục đã quay được bao nhiêu độ, cần một cảm biến riêng: encoder.

Khái niệm chính

Encoder gắn trực tiếp vào trục động cơ (hoặc trục bánh xe), phát ra tín hiệu xung mỗi khi trục quay được một góc nhỏ cố định. Đếm số xung trong một khoảng thời gian cho biết tốc độ quay; đếm dồn tổng số xung cho biết đã quay được bao nhiêu so với vị trí ban đầu.

Có hai loại chính:

  • Encoder tương đối (incremental) — chỉ biết đã quay bao nhiêu kể từ lúc bật nguồn, mất điện là mất luôn vị trí tham chiếu, phổ biến và rẻ hơn
  • Encoder tuyệt đối (absolute) — luôn biết chính xác góc quay hiện tại kể cả vừa mất điện, phức tạp và đắt hơn

Hai kênh A/B — biết cả tốc độ lẫn chiều quay

Hầu hết encoder tương đối dùng trong robot có 2 kênh tín hiệu (A và B), đặt lệch pha nhau 90°. Chỉ đếm xung trên 1 kênh cho biết tốc độ nhưng không biết chiều quay; so sánh thứ tự kênh nào lên mức cao trước (A trước B, hay B trước A) sẽ cho biết trục đang quay thuận hay ngược — kỹ thuật gọi là giải mã cầu phương (quadrature decoding).

Tóm lại: Encoder là "đôi mắt" của vòng điều khiển động cơ — không có nó, MCU chỉ biết mình đã ra lệnh quay bao nhiêu, chứ không biết động cơ thực sự đang quay bao nhiêu.

Nguyên lý hoạt động

Kênh A: ┐  ┌──┐  ┌──┐  ┌──┐          (quay thuận: A lên trước B)
        └──┘  └──┘  └──┘  └──
Kênh B:   ┐  ┌──┐  ┌──┐  ┌──┐
          └──┘  └──┘  └──┘  └──

Nhiều dòng MCU (như STM32) có chế độ Timer Encoder Mode — phần cứng Timer tự động đếm và giải mã cầu phương mà không tốn CPU xử lý từng xung ngắt:

// Bật Timer ở chế độ encoder — phần cứng tự đếm, tự nhận biết chiều quay
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);

int32_t count = __HAL_TIM_GET_COUNTER(&htim2);
// count tăng khi quay thuận, giảm khi quay ngược — không cần code xử lý ngắt

Số xung trên mỗi vòng quay được gọi là độ phân giải (PPR/CPR — Pulse/Count Per Revolution) — encoder có độ phân giải càng cao, đo được góc quay càng chính xác.

Kiến thức kỹ thuật

Công thức

Vì hầu hết bộ giải mã cầu phương đếm cả 4 cạnh (lên/xuống của cả 2 kênh A và B) thay vì chỉ 1 cạnh, số đếm thực tế mỗi vòng quay gấp 4 lần PPR gốc — đây gọi là giải mã x4:

Số đếm thực tế mỗi vòng = PPR × 4
Độ phân giải góc (độ/count) = 360° / (PPR × 4)
RPM = (Δcount / Δthời gian(s)) / (PPR × 4) × 60

VD: encoder 13 PPR (trước hộp giảm tốc), giải mã x4
Số đếm/vòng = 13 × 4 = 52
Trong 0.1s đếm được 26 count
RPM = (26 / 0.1) / 52 × 60 = 300 vòng/phút

Thông số

Độ phân giải PPR (trước khi nhân x4) khác nhau rất nhiều tuỳ loại encoder và vị trí gắn (trước hay sau hộp giảm tốc):

Loại encoderPPR điển hình
Encoder từ tính giá rẻ trên động cơ giảm tốc (gắn trên trục motor, trước hộp số)11 – 13
Encoder quang học phổ thông100 – 600
Encoder độ phân giải cao (dùng cho tay máy công nghiệp)1000 – 4096+

Với động cơ có hộp giảm tốc (VD: tỷ số 1:50), độ phân giải thực tế đo được ở trục bánh xe (sau hộp số) cao hơn nhiều lần so với PPR gốc ở trục motor — xem ví dụ tính toán ở mục Lỗi thường gặp.

Register / Bit / Byte

Chế độ Timer Encoder Mode trên STM32 được bật qua thanh ghi TIMx_SMCR (Slave Mode Control Register) — chọn giữa 3 chế độ giải mã: chỉ đếm cạnh của TI1 (x1), chỉ TI2 (x1), hoặc cả 2 tín hiệu (x2 hoặc x4 tuỳ cấu hình chi tiết). Giá trị đếm hiện tại nằm trong thanh ghi TIMx_CNT — đây chính là thanh ghi mà hàm __HAL_TIM_GET_COUNTER() đọc ra, tự động tăng/giảm hoàn toàn bởi phần cứng Timer mà không cần ngắt phần mềm.

Ứng dụng thực tế

Dữ liệu encoder của cả bánh trái và bánh phải là đầu vào cơ bản nhất để tính odometry — ước lượng quãng đường robot đã di chuyển bằng cách chuyển số đếm encoder thành khoảng cách thực tế: quãng đường = (số count / số count mỗi vòng) × chu vi bánh xe. Đây là nguồn dữ liệu vị trí đầu tiên mà hầu như mọi AMR đều có sẵn, dùng làm input cho thuật toán SLAM/localization trước khi kết hợp thêm IMU hoặc LiDAR để tăng độ chính xác. Ngoài ra, dữ liệu encoder cũng là tín hiệu phản hồi bắt buộc cho vòng điều khiển PID giữ tốc độ động cơ ổn định — chủ đề của bài viết PID trong chuyên mục này.

Ví dụ thực tế

#include <stdio.h>

int main() {
    int ppr = 13;
    int decode_factor = 4;
    int gear_ratio = 50;   // hộp giảm tốc 1:50
    float wheel_diameter_cm = 6.5;

    int counts_per_wheel_rev = ppr * decode_factor * gear_ratio;
    float wheel_circumference = 3.1416 * wheel_diameter_cm;

    int delta_count = 2600;   // số count đọc được trong 1 khoảng thời gian
    float distance_cm = ((float)delta_count / counts_per_wheel_rev) * wheel_circumference;

    printf("So count/vong banh xe = %d\n", counts_per_wheel_rev);
    printf("Quang duong di chuyen = %.2f cm\n", distance_cm);
    return 0;
}
Output:
So count/vong banh xe = 2600
Quang duong di chuyen = 20.42 cm

delta_count = 2600 vừa đúng bằng counts_per_wheel_rev — nghĩa là bánh xe vừa quay đúng 1 vòng, và quãng đường tính ra (20.42cm) khớp với chu vi bánh xe đường kính 6.5cm — một cách tự kiểm tra công thức tính có đúng hay không trước khi tin tưởng dùng cho odometry thật.

Lỗi thường gặp

  • Nhầm PPR ở trục motor với PPR hiệu dụng ở trục bánh xe — như ví dụ ở trên, PPR ghi trên datasheet encoder (13) thường đo trước hộp giảm tốc — quên nhân với tỷ số truyền (gear ratio) khi tính odometry sẽ cho quãng đường sai lệch hàng chục lần.
  • Dùng giải mã x1 thay vì x4 mà không biết — một số thư viện mặc định chỉ đếm 1 cạnh (x1), giảm độ phân giải hiệu dụng xuống 4 lần so với khả năng thực tế của encoder — kiểm tra đúng cấu hình chế độ giải mã trong tài liệu thư viện/HAL đang dùng.
  • Nhiễu điện gây đếm sai (đếm dư hoặc thiếu xung) — dây tín hiệu encoder dài, không có shielding, chạy gần dây động cơ công suất lớn dễ bị nhiễu cảm ứng gây đếm sai — nên dùng cáp xoắn đôi có shielding và đi dây tách biệt khỏi dây động cơ khi có thể.
  • Kỳ vọng encoder tương đối "nhớ" vị trí sau khi mất điện — như đã nói ở phần Khái niệm chính, encoder incremental luôn khởi động lại từ số đếm 0, cần một quy trình "về vị trí gốc" (homing) riêng nếu ứng dụng cần biết vị trí tuyệt đối ngay sau khi bật nguồn.

Kết luận

Encoder chuyển đổi điều khiển động cơ từ "mù" (chỉ biết đã ra lệnh gì) sang có phản hồi thực tế (biết chính xác động cơ đang làm gì) — nền tảng bắt buộc cho cả odometry lẫn vòng điều khiển PID. Luôn tính đúng hệ số giải mã và tỷ số truyền khi chuyển số đếm encoder thành đơn vị vật lý thực tế (vòng/phút, cm). Bài tiếp theo trong chuyên mục nói về Servo Motor — loại động cơ có sẵn cơ chế điều khiển vị trí tích hợp, khác cách tiếp cận với DC motor + encoder rời vừa học.

Encoder là gì? Đôi mắt đo tốc độ và vị trí của động cơ — Atlasbot