ESP32 Rotary Encoder
Trong hướng dẫn này, bạn sẽ học cách sử dụng rotary encoder với ESP32. Đây là những gì chúng ta sẽ học:
- Sự khác biệt giữa rotary encoder và biến trở (potentiometer) là gì
- Cách hoạt động của rotary encoder
- Cách kết nối rotary encoder với ESP32
- Cách viết code cho ESP32 để đọc hướng và vị trí từ rotary encoder KHÔNG sử dụng interrupt.
- Cách viết code cho ESP32 để đọc hướng và vị trí từ rotary encoder CÓ sử dụng interrupt.
Linh Kiện Cần Thiết
| 1 | × | mô-đun phát triển ESP-WROOM-32 | ||
| 1 | × | Alternatively, ESP32 Uno-form board | ||
| 1 | × | Alternatively, ESP32 S3 Uno-form board | ||
| 1 | × | USB Cable Type-A to Type-C (for USB-A PC) | ||
| 1 | × | USB Cable Type-C to Type-C (for USB-C PC) | ||
| 1 | × | encoder xoay | ||
| 1 | × | breadboard | ||
| 1 | × | dây jumper | ||
| 1 | × | (Khuyến nghị) Screw Terminal Expansion Board for ESP32 | ||
| 1 | × | (Khuyến nghị) Breakout Expansion Board for ESP32 | ||
| 1 | × | (Khuyến nghị) Power Splitter for ESP32 |
Or you can buy the following kits:
| 1 | × | DIYables ESP32 Starter Kit (ESP32 included) | ||
| 1 | × | DIYables Sensor Kit (30 sensors/displays) | ||
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Giới Thiệu Rotary Encoder
Một núm xoay, giống như trên radio, có thể gửi tín hiệu biến thành điện. Nó giúp chúng ta biết nó đã xoay bao nhiều và đặt ở đâu. Có hai loại chính:
- Incremental encoder: Loại này sử dụng tín hiệu nhanh để đo lượng thay đổi vị trí của vật thể.
- Absolute encoder: Loại này cung cấp mã riêng biệt cho mỗi vị trí, giúp chúng ta tìm ra vị trí của vật thể, ngay cả khi mất điện.
Bài học này chủ yếu về loại đầu tiên, incremental encoder.
Sơ Đồ Chân Rotary Encoder Module

Module rotary encoder có 4 chân:
- CLK pin (Output A): là xung chính cho biết lượng xoay đã xảy ra. Mỗi khi bạn xoay núm một detent (click) theo bất kỳ hướng nào, chân CLK xuất ra tín hiệu hoàn thành một chu kỳ đầy đủ (LOW → HIGH → LOW).
- DT pin (Output B): hoạt động giống chân CLK nhưng xuất ra tín hiệu chậm hơn tín hiệu CLK 90 độ. Nó giúp chúng ta xác định hướng xoay (thuận chiều kim đồng hồ hay ngược chiều kim đồng hồ).
- SW pin: đến từ nút bấm của encoder. Nó thường mở. Khi chúng ta thêm điện trở pull-up vào chân này, chân SW sẽ ở mức HIGH khi núm không được nhấn và LOW khi được nhấn.
- VCC pin (+): cần được kết nối với VCC (giữa 3.3 và 5 volt)
- GND pin: cần được kết nối với GND (0V)
Rotary Encoder so với Potentiometer
Bạn có thể nhầm lẫn rotary encoder với ESP32 - Potentiometer (Biến Trở Xoay). nhưng chúng là các linh kiện khác biệt. Dưới đây là so sánh giữa chúng:
- Rotary encoder giống như phiên bản hiện đại của potentiometer, nhưng chúng có thể làm nhiều việc hơn.
- Rotary encoder có thể xoay vòng tròn hoàn chỉnh mà không dừng lại, trong khi potentiometer chỉ có thể xoay khoảng ba phần tư vòng tròn.
- Rotary encoder xuất ra xung, trong khi potentiometer xuất ra điện áp analog.
- Rotary encoder tiện dụng khi bạn chỉ cần biết núm đã di chuyển bao nhiều, không cần biết chính xác vị trí. Potentiometer hữu ích khi bạn thực sự cần biết chính xác vị trí của núm.
Cách Hoạt Động Của Rotary Encoder

Bên trong encoder, có một đĩa nhỏ với các rãnh được kết nối với chân C, hoạt động như mass chung. Bạn có thêm hai chân A và B.
- Khi bạn xoay núm, chân A và B chạm vào chân mass chung C, nhưng thứ tự chúng chạm phụ thuộc vào hướng bạn xoay núm (thuận chiều kim đồng hồ hay ngược chiều kim đồng hồ).
- Những lần chạm này tạo ra hai tín hiệu. Chúng hơi khác nhau về thời gian vì một chân chạm mass trước chân kia. Những tín hiệu này lệch nhau 90 độ, được gọi là quadrature encoding.
- Nếu bạn xoay núm theo chiều kim đồng hồ, chân A chạm mass trước chân B. Nhưng nếu xoay ngược chiều kim đồng hồ, chân B chạm mass trước chân A.
- Bằng cách kiểm tra khi nào mỗi chân chạm hoặc rời khỏi mass, chúng ta có thể xác định hướng xoay của núm. Chúng ta làm điều này bằng cách kiểm tra chuyện gì xảy ra với chân B khi chân A thay đổi.

Khi A thay đổi trạng thái từ LOW sang HIGH:
- Nếu B ở mức HIGH, núm được xoay ngược chiều kim đồng hồ.
- Nếu B ở mức LOW, núm được xoay theo chiều kim đồng hồ.
※ Lưu ý:
Chân A và B được kết nối với chân CLK và DT. Tuy nhiên, tùy thuộc vào nhà sản xuất, thứ tự có thể khác nhau. Các đoạn code được cung cấp dưới đây đã được thử nghiệm với rotary encoder từ DIYables
Cách Lập Trình Cho Rotary Encoder
- ESP32 đọc tín hiệu từ chân CLK
- Nếu trạng thái thay đổi từ LOW sang HIGH, thì ESP32 đọc trạng thái của chân DT.
- Nếu chân DT ở mức HIGH, núm được xoay ngược chiều kim đồng hồ, ESP32 tăng bộ đếm lên 1
- Nếu chân DT ở mức LOW, núm được xoay theo chiều kim đồng hồ, ESP32 giảm bộ đếm đi 1
Sơ Đồ Kết Nối

This image is created using Fritzing. Click to enlarge image
Nếu bạn chưa rõ cách cấp nguồn cho ESP32 và các linh kiện khác, xem: Cách Cung Cấp Nguồn Điện Cho ESP32.
Code ESP32 – Rotary Encoder
Code ESP32 dưới đây thực hiện:
- Phát hiện hướng và lượng xoay của encoder.
- Nếu phát hiện núm xoay một detent (click) theo chiều kim đồng hồ, tăng bộ đếm lên một.
- Nếu phát hiện núm xoay một detent (click) ngược chiều kim đồng hồ, giảm bộ đếm đi một.
- Phát hiện nếu nút được nhấn.
Để đơn giản hóa code cho button debouncing, thư viện ezButton được sử dụng.
Các Bước Thực Hiện
Nếu đây là lần đầu bạn sử dụng ESP32, hãy xem ESP32 - Cài Đặt Phần Mềm.
- Cài đặt thư viện ezButton trên Arduino IDE.
- Copy code trên và mở bằng Arduino IDE
- Click nút Upload trên Arduino IDE để upload code lên ESP32
- Xoay núm theo chiều kim đồng hồ, sau đó ngược chiều kim đồng hồ
- Nhấn núm
- Xem kết quả trên Serial Monitor.
Giải Thích Code
Xem các comment từng dòng trong code
Code ESP32 – Rotary Encoder với Interrupt
Trong code trước, việc sử dụng polling để liên tục kiểm tra trạng thái chân có thể lãng phí tài nguyên ESP32 và dẫn đến bỏ lỡ đếm nếu việc thực thi code khác chậm.
Một giải pháp hiệu quả là sử dụng interrupt, loại bỏ sự cần thiết của polling. Điều này cho phép ESP32 thực hiện các tác vụ khác mà không bỏ lỡ việc đếm. Dưới đây là code ESP32 sử dụng interrupt để đọc hướng và vị trí từ rotary encoder.
Bây giờ, khi bạn xoay núm, bạn sẽ thấy thông tin xuất hiện trên Serial Monitor, giống như những gì bạn đã thấy trong code trước đó.
※ Lưu ý:
- Bạn có thể gặp phải các hướng dẫn trên các trang web khác sử dụng hai interrupt cho một encoder, nhưng điều này không cần thiết và lãng phí. Chỉ cần một interrupt là đủ.
- Quan trọng là phải sử dụng từ khóa volatile cho các biến global được sử dụng trong interrupt. Bỏ qua điều này có thể dẫn đến các vấn đề không mong muốn.
- Giữ code trong interrupt đơn giản nhất có thể. Tránh sử dụng Serial.print() hoặc Serial.println() bên trong interrupt.
Ứng Dụng ESP32 Rotary Encoder
Với Rotary Encoder, chúng ta có thể thực hiện các ứng dụng sau nhưng không giới hạn:
- ESP32 - Rotary Encoder điều khiển Vị trí của Servo Motor
- ESP32 - Rotary Encoder điều khiển Độ sáng của LED
- ESP32 - Rotary Encoder điều khiển Tốc độ của Stepper Motor
Video Tutorial
Việc sản xuất video tốn rất nhiều thời gian. Nếu video hướng dẫn hữu ích cho việc học của bạn, hãy đăng ký kênh YouTube để ủng hộ. Nếu nhu cầu đủ cao, chúng tôi sẽ cố gắng làm thêm nhiều video.