Encoder tuyệt đối: cấu tạo, mã Gray, đơn vòng, đa vòng, cách chế tạo và đọc AS5600 bằng ESP32

Encoder tuyệt đối hoạt động thế nào: đĩa mã nhị phân và mã Gray, đơn vòng, đa vòng, giao tiếp SSI, encoder từ tính, cách chế tạo và đọc cảm biến góc AS5600 bằng ESP32.

Encoder tuyệt đối cho biết vị trí của trục ngay tại thời điểm đọc, kể cả khi vừa cấp nguồn, chứ không chỉ báo phần thay đổi như encoder tương đối. Mỗi góc quay ứng với một mã số riêng được khắc sẵn trên đĩa mã, hoặc được tính từ hướng từ trường của một nam châm. Bài viết giải thích đĩa mã nhị phân và mã Gray, encoder đơn vòng và đa vòng, các chuẩn truyền vị trí như SSI, encoder tuyệt đối từ tính, quy trình chế tạo, và cách đọc cảm biến góc AS5600 bằng ESP32 qua I2C.

1. Encoder tương đối và tuyệt đối khác nhau ở đâu

So sánh encoder tương đối và tuyệt đối: encoder tương đối chỉ phát xung khi quay, mất điện là mất số đếm và phải chạy về gốc khi bật máy; encoder tuyệt đối có mã riêng cho mỗi vị trí, bật máy là biết ngay góc
Khác biệt chính giữa hai loại encoder lúc bật nguồn (hình tự vẽ).

Với encoder tương đối, bộ điều khiển phải đếm xung liên tục; mất điện, khởi động lại hay bỏ sót xung do nhiễu đều làm mất vị trí, và máy phải chạy về điểm gốc. Encoder tuyệt đối loại bỏ bước đó: robot công nghiệp, khớp quay của cánh tay máy, van điều khiển, trục ăng-ten, bàn xoay máy CNC đều cần biết vị trí ngay khi bật máy, kể cả khi trục bị xoay bằng tay lúc tắt điện.

2. Đĩa mã và mã Gray

Đĩa mã tuyệt đối có nhiều vòng vạch đồng tâm, mỗi vòng ứng với một bit. Một hàng đi-ốt quang nằm dọc theo bán kính đọc tất cả các vòng cùng lúc, cho ra một mã số. Đĩa n vòng phân biệt được 2ⁿ vị trí: 10 vòng là 1024 vị trí (khoảng 0,35°), 13 vòng là 8192 vị trí.

Hai đĩa mã 4 bit vẽ cạnh nhau: đĩa mã nhị phân đổi cả bốn bit ở ranh giới giữa vị trí 7 và 8, từ 0111 sang 1000; đĩa mã Gray chỉ đổi một bit, từ 0100 sang 1100; bên dưới là bảng 16 vị trí với mã nhị phân và mã Gray tương ứng
Đĩa mã nhị phân và đĩa mã Gray 4 bit, kèm bảng đối chiếu (hình tự vẽ, mã Gray tính theo đúng thuật toán của chương trình).
  • Vấn đề của mã nhị phân: ở ranh giới từ 7 (0111) sang 8 (1000), cả 4 bit đổi cùng lúc. Các vạch không bao giờ thẳng hàng tuyệt đối, đầu đọc có thể thấy bit cao đổi trước bit thấp và đọc ra 1111 (15) hay 0000 (0) trong khoảnh khắc: sai cả nửa vòng.
  • Mã Gray sắp xếp sao cho hai vị trí liền nhau chỉ khác đúng một bit. Đầu đọc lệch một chút cũng chỉ cho ra vị trí bên này hoặc bên kia ranh giới, không bao giờ nhảy xa.
  • Đổi nhị phân sang Gray: gray = b XOR (b >> 1). Đổi ngược: XOR dồn từ bit cao xuống. Hai hàm này có trong chương trình mẫu.
Encoder tuyệt đối mã Gray 13 vòng được mở ra: phía trên là vỏ nhôm với đĩa thủy tinh có các vòng vạch đồng tâm, phía dưới là mạch in có chip cảm biến quang phản xạ và các IC xử lý
Encoder tuyệt đối mã Gray 13 vòng được mở ra: đĩa thủy tinh có các vòng vạch đồng tâm (trên) và mạch đọc quang (dưới). Ảnh: Mike1024, phạm vi công cộng, Wikimedia Commons, đã thu nhỏ.

3. Đơn vòng, đa vòng và cách truyền vị trí

Bên trái: trục chính có đĩa mã và hai bánh răng giảm tốc mang đĩa phụ đếm số vòng; bên phải: giản đồ giao tiếp SSI với xung CLK do bộ điều khiển phát và đường DATA đưa ra 12 bit vị trí 011000100001 bằng 1569
Đếm vòng bằng bánh răng và giản đồ SSI rút gọn 12 bit (hình tự vẽ).
  • Đơn vòng chỉ biết góc trong một vòng. Quay hết vòng, mã quay lại từ đầu.
  • Đa vòng kiểu cơ: trục chính kéo một chuỗi bánh răng giảm tốc, mỗi bánh mang một đĩa mã phụ; đĩa thứ hai đếm số vòng của trục chính, đĩa thứ ba đếm số vòng của đĩa thứ hai. Không cần pin, nhớ được hàng nghìn vòng kể cả khi mất điện.
  • Đa vòng kiểu điện tử: bộ đếm vòng nuôi bằng pin dự phòng, hoặc dùng cuộn dây Wiegand: một sợi dây từ đặc biệt phát ra xung điện đủ mạnh mỗi khi nam châm quay qua, đủ năng lượng để ghi số vòng vào bộ nhớ mà không cần pin.
  • Truyền vị trí: loại cũ ra song song mỗi bit một dây. Phổ biến hiện nay là SSI: bộ điều khiển phát xung đồng hồ, encoder chốt vị trí rồi đẩy từng bit ra, qua cặp dây vi sai RS-422. Các chuẩn khác: BiSS, EnDat, các mạng công nghiệp như CANopen, PROFINET, EtherCAT, hoặc ngõ ra analog 0–10 V, 4–20 mA.
Bên trong một encoder tuyệt đối 8 bit kiểu cũ: các đĩa và vòng tiếp điểm xếp chồng trên trục kim loại trong vỏ hình trụ
Bên trong một encoder tuyệt đối 8 bit kiểu cũ (sản xuất ở Liên Xô): nhiều đĩa và vòng tiếp điểm xếp chồng trên trục. Ảnh: 155LA3, CC BY 4.0, Wikimedia Commons, đã thu nhỏ.

4. Encoder tuyệt đối từ tính

Encoder tuyệt đối từ tính: nhìn nghiêng là nam châm từ hóa xuyên tâm hai cực N và S gắn trên đầu trục, cách chip AS5600 từ 0,5 đến 3 mm; nhìn từ trên là nam châm hai nửa đỏ xanh với bốn cảm biến Hall quanh tâm chip và vectơ từ trường, góc bằng atan2 của By và Bx
Nam châm xuyên tâm trên đầu trục và chip Hall đo hướng từ trường (hình tự vẽ).

Một nam châm tròn nhỏ, từ hóa xuyên tâm (một nửa là cực N, nửa kia là cực S), được gắn ở đầu trục. Ngay bên dưới, một con chip có các cảm biến Hall bố trí quanh tâm đo hai thành phần của từ trường theo hai trục X và Y. Góc của trục là góc của vectơ từ trường: góc = atan2(By, Bx). Bộ chuyển đổi và bộ xử lý ngay trong chip tính góc 12 bit (4096 bước mỗi vòng, khoảng 0,09°) và đưa ra qua I2C, ngõ ra analog hoặc PWM.

Loại từ tính không có đĩa mỏng manh, chịu bụi, dầu và rung tốt, giá rẻ; độ chính xác tuyệt đối thường khoảng vài phần mười độ, thấp hơn encoder quang cao cấp. Chúng có mặt trong động cơ servo nhỏ, tay ga xe điện, núm xoay, gimbal, khớp robot.

5. Chế tạo encoder tuyệt đối

Sáu bước chế tạo encoder tuyệt đối: thiết kế đĩa mã mỗi bit một vòng, quang khắc đĩa thủy tinh phủ crôm, đầu đọc nhiều kênh nằm thẳng hàng theo bán kính, căn chỉnh và hiệu chuẩn bằng encoder chuẩn, loại từ tính dùng nam châm xuyên tâm và chip Hall, loại đa vòng dùng bánh răng hoặc bộ đếm có pin hay cuộn Wiegand
Các bước chính chế tạo encoder tuyệt đối quang học và từ tính (hình tự vẽ).
  1. Thiết kế đĩa mã: tính số vòng theo độ phân giải; vòng ứng với bit thấp nhất có vạch mảnh nhất. Encoder độ phân giải rất cao thường dùng thêm một vòng vạch mịn kiểu tương đối, đọc ra tín hiệu sin rồi nội suy để có thêm bit.
  2. Quang khắc: giống làm mạch in hay vi mạch: thủy tinh phủ crôm và chất cản quang, chiếu sáng qua mặt nạ mang hình đĩa mã, rồi ăn mòn. Sai lệch vị trí vạch chỉ vài micromet.
  3. Đầu đọc: một hàng đi-ốt quang, mỗi vòng một đi-ốt, nằm thẳng hàng trên một bán kính. Hàng đi-ốt nghiêng một chút là các bit đổi lệch thời điểm, lý do phải dùng mã Gray.
  4. Căn chỉnh và hiệu chuẩn: lắp chung trục với một encoder chuẩn có độ phân giải cao hơn nhiều, ghi sai số ở từng góc và nạp bảng bù vào bộ nhớ của encoder.
  5. Loại từ tính: chọn nam châm đúng loại từ hóa xuyên tâm, gắn đồng tâm trục, đặt đúng khoảng cách với chip, hiệu chuẩn sau khi lắp để bù độ lệch tâm.
  6. Đa vòng: lắp hộp bánh răng với các đĩa phụ, hoặc bộ đếm vòng điện tử; thử nghiệm quay nhiều vòng khi tắt nguồn rồi kiểm tra số vòng đọc lại.

6. Thực hành: đọc góc tuyệt đối bằng AS5600 và ESP32

Linh kiện

  • ESP32 DevKit V1 30 chân.
  • Một module cảm biến góc AS5600 kèm nam châm tròn từ hóa xuyên tâm (thường đường kính 6 mm).
  • Một trục hoặc núm xoay để gắn nam châm, giá đỡ giữ module đúng tâm, cách nam châm 0,5 đến 3 mm.
  • Dây cắm test board.

Sơ đồ nối

Sơ đồ nối module AS5600 với ESP32: VCC vào 3V3, GND vào GND, SCL vào GPIO22, SDA vào GPIO21, chân DIR nối xuống GND ngay trên module
Sơ đồ nối module AS5600 với ESP32 (hình tự vẽ).
AS5600ESP32
VCC, GND3V3, GND
SDA, SCLGPIO21, GPIO22
DIRGND (không để hở)

Chương trình

Chương trình chỉ dùng thư viện Wire có sẵn, đọc thẳng các thanh ghi của AS5600 (địa chỉ I2C 0x36): trạng thái nam châm 0x0B, góc thô 0x0C–0x0D, hệ số khuếch đại tự động 0x1A.

/*
  PYWORLD.VN - Encoder tuyệt đối từ tính AS5600 với ESP32: đọc góc 12 bit qua I2C bằng Wire, không dùng thư viện riêng
  AS5600: VCC = 3V3, GND = GND, SDA = GPIO21, SCL = GPIO22, DIR nối GND; nam châm từ hóa xuyên tâm đặt trên chip 1–3 mm
  In góc, số vòng đếm thêm bằng phần mềm, mã Gray 8 bit của góc và trạng thái nam châm
*/

#include <Wire.h>

#define CHAN_SDA 21
#define CHAN_SCL 22

const uint8_t DIA_CHI_AS5600 = 0x36;
const uint8_t TG_TRANG_THAI = 0x0B;    // Bit 5 MD: có nam châm, bit 4 ML: quá yếu, bit 3 MH: quá mạnh
const uint8_t TG_GOC_THO = 0x0C;       // 0x0C (4 bit cao) và 0x0D (8 bit thấp): góc thô 0..4095
const uint8_t TG_AGC = 0x1A;           // Hệ số tự động khuếch đại: cho biết khoảng cách nam châm

int32_t soVong = 0;
int goc_truoc = -1;

bool docThanhGhi(uint8_t thanhGhi, uint8_t *dem, uint8_t soByte) {
  Wire.beginTransmission(DIA_CHI_AS5600);
  Wire.write(thanhGhi);
  if (Wire.endTransmission(false) != 0) {
    return false;
  }
  if (Wire.requestFrom(DIA_CHI_AS5600, soByte) != soByte) {
    return false;
  }
  for (uint8_t i = 0; i < soByte; i++) {
    dem[i] = Wire.read();
  }
  return true;
}

// Mã Gray: hai giá trị liền nhau chỉ khác đúng một bit
uint16_t nhiPhanSangGray(uint16_t b) {
  return b ^ (b >> 1);
}

uint16_t graySangNhiPhan(uint16_t g) {
  uint16_t b = g;
  while (g >>= 1) {
    b ^= g;
  }
  return b;
}

void inBit(char *chuoi, uint16_t giaTri, int soBit) {
  for (int i = 0; i < soBit; i++) {
    chuoi[i] = (giaTri >> (soBit - 1 - i)) & 1 ? '1' : '0';
  }
  chuoi[soBit] = '\0';
}

const char *trangThaiNamCham(uint8_t tt) {
  if (!(tt & 0x20)) return "khong thay nam cham";
  if (tt & 0x10) return "nam cham qua yeu (xa qua)";
  if (tt & 0x08) return "nam cham qua manh (gan qua)";
  return "tot";
}

void setup() {
  Serial.begin(115200);
  Wire.begin(CHAN_SDA, CHAN_SCL, 400000);
  Serial.println("\nAS5600: goc tuyet doi 12 bit (4096 buoc/vong)");
}

void loop() {
  uint8_t tt, agc, raw[2];
  if (!docThanhGhi(TG_TRANG_THAI, &tt, 1) || !docThanhGhi(TG_AGC, &agc, 1) || !docThanhGhi(TG_GOC_THO, raw, 2)) {
    Serial.println("Khong doc duoc AS5600: kiem tra SDA, SCL, nguon 3V3");
    delay(1000);
    return;
  }
  int goc = ((raw[0] & 0x0F) << 8) | raw[1];

  // Đếm vòng bằng phần mềm: góc nhảy hơn nửa vòng giữa hai lần đọc nghĩa là vừa đi qua điểm 0
  if (goc_truoc >= 0) {
    int thayDoi = goc - goc_truoc;
    if (thayDoi < -2048) soVong++;
    if (thayDoi > 2048) soVong--;
  }
  goc_truoc = goc;

  uint16_t tam = goc >> 4;                  // 8 bit cao của góc, như đĩa mã 8 vạch
  uint16_t gray = nhiPhanSangGray(tam);
  char chuoiGray[9];
  inBit(chuoiGray, gray, 8);
  Serial.printf("Tho %4d | Goc %6.2f do | Vong %ld | Gray8 %s -> %3u | AGC %3u | %s\n",
                goc, goc * 360.0f / 4096, (long)soVong, chuoiGray, graySangNhiPhan(gray), agc, trangThaiNamCham(tt));
  delay(200);
}

Giải thích

  • Góc thô 12 bit ghép từ 4 bit thấp của thanh ghi 0x0C và 8 bit của 0x0D; nhân 360/4096 ra độ.
  • Bit 5 của thanh ghi trạng thái báo có nam châm; bit 4 báo từ trường quá yếu (nam châm xa), bit 3 báo quá mạnh (quá gần).
  • AGC là hệ số khuếch đại chip tự chỉnh: nam châm đặt đúng khoảng cách thì AGC nằm quanh giữa dải (khoảng 64 khi chạy 3,3 V); AGC lên tới 128 nghĩa là nam châm quá xa.
  • Số vòng được đếm bằng phần mềm: nếu góc nhảy hơn nửa vòng giữa hai lần đọc nghĩa là vừa đi qua điểm 0. Đây là đa vòng "mềm", mất khi tắt điện; đa vòng thật cần bánh răng hoặc bộ đếm có nguồn dự phòng.
  • Chương trình lấy 8 bit cao của góc, đổi sang mã Gray rồi đổi ngược, để thấy một đĩa mã Gray 8 vòng sẽ đọc ra mã gì ở góc đó.

Kết quả mong đợi

Hình minh họa Serial Monitor đọc AS5600 bằng ESP32: góc thô, góc theo độ, số vòng, mã Gray 8 bit và giá trị đổi ngược, hệ số AGC và trạng thái nam châm; số vòng tăng khi quay qua điểm 0; báo nam châm quá yếu khi nhấc ra xa
Kết quả mong đợi trên Serial Monitor (hình minh họa; các góc là ví dụ).

Tắt nguồn, xoay núm sang vị trí khác rồi bật lại: dòng đầu tiên đã cho đúng góc mới. Đó là khác biệt rõ nhất so với encoder tương đối.

7. Xử lý lỗi thường gặp

Hiện tượngNguyên nhân thường gặpCách xử lý
"Khong doc duoc AS5600"Sai chân SDA, SCL; thiếu nguồnChạy chương trình quét I2C, phải thấy địa chỉ 0x36
Báo không thấy nam châmNam châm từ hóa dọc trục (loại thường) thay vì xuyên tâmDùng nam châm đi kèm module, loại từ hóa xuyên tâm
Góc chỉ thay đổi trong một khoảng hẹpNam châm lệch tâm chipCăn nam châm đúng tâm, cách mặt chip 0,5 đến 3 mm
Góc chạy ngược chiều mong muốnChân DIR nối nhầm mứcNối DIR lên VCC để đảo chiều, hoặc lấy 4096 trừ góc trong chương trình
Góc rung vài bước khi đứng yênNhiễu, nam châm yếuLấy trung bình vài lần đọc; đưa nam châm lại gần hơn

8. Xem thêm


Tin tức liên quan

Modbus TCP/IP (phần 2): ESP32 làm máy khách và cổng chuyển đổi Modbus TCP sang RTU
Modbus TCP/IP (phần 2): ESP32 làm máy khách và cổng chuyển đổi Modbus TCP sang RTU

Hướng dẫn dùng ESP32 làm máy khách Modbus TCP đọc thanh ghi của một thiết bị trong mạng, và làm cổng chuyển đổi Modbus TCP sang Modbus RTU qua RS-485: cách đổi khung, mã thiết bị, thời gian chờ, mã lỗi 0x0B.

Các nguồn sai số khi đo lực bằng load cell: lệch tâm, rão, trễ, nhiệt độ và ngân sách sai số
Các nguồn sai số khi đo lực bằng load cell: lệch tâm, rão, trễ, nhiệt độ và ngân sách sai số

Vì sao đo lực thực tế sai hơn phiếu thông số load cell: lệch tâm và gá lắp, rão, trễ, phi tuyến, nhiệt độ, cáp và bộ đọc; ví dụ ngân sách sai số và danh sách kiểm tra nhanh.

Vali đựng máy ảnh, ống kính chống sốc: chọn cỡ theo bộ máy và cách xếp xốp
Vali đựng máy ảnh, ống kính chống sốc: chọn cỡ theo bộ máy và cách xếp xốp

Chọn vali đựng máy ảnh, ống kính: liệt kê những gì bộ máy cần chỗ, xếp xốp, đặt ống kính đứng hay nằm, gợi ý cỡ vali chống nước theo bộ máy, chống ẩm và mang lên xe, máy bay.

Tổng quan các chuẩn giao tiếp cho vi điều khiển: UART, I2C, SPI, RS-485, CAN và cách chọn
Tổng quan các chuẩn giao tiếp cho vi điều khiển: UART, I2C, SPI, RS-485, CAN và cách chọn

So sánh các chuẩn giao tiếp thường gặp với vi điều khiển: UART, I2C, SPI, 1-Wire, RS-485, CAN, Ethernet và không dây. Giải thích tín hiệu vi sai, ba lớp của một hệ giao tiếp và cách chọn chuẩn theo nhu cầu.

Modbus RTU (phần 1): khung tin, mã hàm, CRC và ESP32 làm thiết bị chủ
Modbus RTU (phần 1): khung tin, mã hàm, CRC và ESP32 làm thiết bị chủ

Giải thích Modbus RTU ở mức từng byte: khung tin, bốn vùng dữ liệu, mã hàm đọc ghi, khung báo lỗi. Kèm chương trình ESP32 làm thiết bị chủ đọc thanh ghi và ghi cuộn qua RS-485, không dùng thư viện.

Hướng dẫn nạp file .bin vào ESP32 bằng Flash Download Tool
Hướng dẫn nạp file .bin vào ESP32 bằng Flash Download Tool

Hướng dẫn lấy đúng file và offset theo từng ESP32, nạp bằng Flash Download Tool, xử lý lỗi boot và xóa flash an toàn.

Gá lắp gia tốc kế theo ISO 5348: tần số cộng hưởng, dải tần dùng được và các sai số khi đo rung
Gá lắp gia tốc kế theo ISO 5348: tần số cộng hưởng, dải tần dùng được và các sai số khi đo rung

Cách gá gia tốc kế theo ISO 5348: vít cấy, keo, sáp, nam châm, đầu dò cầm tay; tần số cộng hưởng lắp đặt, dải tần dùng được, ảnh hưởng khối lượng cảm biến và các điểm kỹ thuật khi gắn.

Cảm biến ánh sáng: quang trở, photodiode, BH1750 – cấu tạo, nguyên lý, chế tạo và đo lux bằng ESP32
Cảm biến ánh sáng: quang trở, photodiode, BH1750 – cấu tạo, nguyên lý, chế tạo và đo lux bằng ESP32

Cảm biến ánh sáng hoạt động thế nào: độ rọi và lux, quang trở CdS, photodiode, phototransistor, cảm biến số BH1750, cách chế tạo và đo lux bằng BH1750, quang trở với ESP32.


Bình luận
Đã thêm vào giỏ hàng