ESP8266 Bộ mã hóa quay

Hướng dẫn này sẽ chỉ cho bạn cách sử dụng bộ mã hóa quay tăng dần với ESP8266. Dưới đây là những nội dung chúng ta sẽ đề cập:

Phần cứng cần chuẩn bị

1×ESP8266 NodeMCU ESP-12E
1×Recommended: ESP8266 NodeMCU ESP-12E (Uno-form)
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×dây jumper
1×(Khuyến nghị) Screw Terminal Expansion Board for ESP8266
1×(Khuyến nghị) Power Splitter for ESP8266 Type-C

Or you can buy the following kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Về bộ mã hóa quay

Bộ mã hóa quay là một loại núm có thể chuyển đổi sự quay thành tín hiệu điện. Nó cho bạn biết mức độ quay của một vật và vị trí của nó. Có hai loại chính:

  • Bộ mã hóa gia tăng: Thiết bị này sử dụng tín hiệu nhanh để đo xem một vật đã di chuyển được bao nhiêu.
  • Bộ mã hóa tuyệt đối: Loại này cung cấp một mã đặc biệt cho mỗi vị trí, giúp biết chính xác vị trí của một vật, ngay cả khi nguồn điện bị ngắt.

Hướng dẫn này tập trung vào bộ mã hóa gia tăng.

Bố trí chân của mô-đun mã hóa quay

sơ đồ chân của bộ mã hóa quay

Một mô-đun mã hóa quay có 4 chân:

  • Chân CLK (Đầu ra A): là tín hiệu chính cho biết đã xoay được bao nhiêu. Mỗi khi bạn xoay núm vặn đúng một khấc (nhấp) theo bất kỳ hướng nào, chân CLK phát ra tín hiệu hoàn thành một chu trình đầy đủ (thấp → cao → thấp).
  • Chân DT (Đầu ra B): hoạt động tương tự như chân CLK nhưng phát ra tín hiệu trễ hơn tín hiệu CLK 90 độ. Nó giúp chúng ta xác định hướng quay (kim đồng hồ hay ngược kim đồng hồ).
  • Chân SW: là đầu ra từ nút nhấn bên trong encoder. Nó thường mở. Nếu ta dùng một điện trở kéo lên ở chân này, chân SW sẽ ở mức cao khi núm vặn chưa được nhấn, và thấp khi nó được nhấn.
  • Chân VCC (+): cần được kết nối với nguồn VCC (từ 3.3 đến 5 volt).
  • Chân GND: cần được kết nối với GND (0V).

Bộ mã hóa quay so với biến trở

Bạn có thể nhầm lẫn giữa bộ mã hóa quay và ESP8266 - Biến trở. Nhưng chúng là hai thành phần khác nhau. Dưới đây là sự so sánh giữa chúng:

  • Bộ mã hóa quay giống như phiên bản hiện đại của biến trở, nhưng nó có thể làm được nhiều chức năng hơn.
  • Bộ mã hóa quay có thể quay quanh một vòng đầy đủ mà không dừng lại, trong khi biến trở chỉ có thể quay khoảng ba phần tư vòng tròn.
  • Bộ mã hóa quay xuất xung, trong khi biến trở xuất ra điện áp tương tự.
  • Bộ mã hóa quay tiện khi bạn chỉ cần biết nó đã di chuyển được đến mức nào, chứ không nhất thiết là nó đang ở vị trí nào. Biến trở hữu ích khi bạn thực sự cần biết chính xác vị trí của nút vặn.

Cách hoạt động của bộ mã hóa quay

đầu ra của bộ mã hóa quay

Bên trong bộ mã hóa, có một đĩa với các khe được kết nối với một chân gọi là C, giống như một đất chung. Có hai chân nữa, A và B.

  • Khi bạn xoay núm, các chân A và B chạm vào chân đất chung C, nhưng theo một trình tự nhất định tùy vào hướng xoay núm (theo chiều kim đồng hồ hoặc ngược chiều kim đồng hồ).
  • Những chạm này tạo ra hai tín hiệu. Chúng có chút khác biệt về thời gian vì một chân chạm đất trước chân kia. Hai tín hiệu lệch nhau 90 độ so với nhau. Điều này được gọi là mã hóa vuông góc.
  • Khi bạn quay núm theo chiều kim đồng hồ, chân A chạm đất trước chân B. Khi bạn quay núm theo hướng ngược chiều kim đồng hồ, chân B chạm đất trước chân A.
  • Bằng cách theo dõi thời điểm mỗi chân chạm hoặc rời đất, ta có thể suy ra hướng quay của núm. Ta làm điều này bằng cách kiểm tra xem điều gì xảy ra với chân B khi chân A thay đổi.
cách hoạt động của bộ mã hóa quay

Khi A thay đổi trạng thái từ thấp sang cao:

  • Nếu B ở mức thấp, nút vặn quay theo chiều kim đồng hồ.
  • Nếu B ở mức cao, nút vặn quay ngược chiều kim đồng hồ.

※ Lưu ý:

Chân A và B được kết nối với các 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 mã được cung cấp dưới đây đã được thử nghiệm với bộ mã hóa quay từ DIYables.

Cách Lập Trình Cho Bộ Mã Hóa Quay

  • Kiểm tra tín hiệu từ chân CLK
  • Nếu trạng thái thay đổi từ thấp sang cao, kiểm tra trạng thái của chân DT.
    • Nếu trạng thái của chân DT ở mức cao, nút quay được xoay theo chiều ngược kim đồng hồ, tăng bộ đếm lên 1
    • Nếu trạng thái của chân DT ở mức thấp, nút quay được xoay theo chiều kim đồng hồ, giảm bộ đếm đi 1

Sơ đồ đấu dây

sơ đồ đấu nối bộ mã hóa quay ESP8266 NodeMCU

This image is created using Fritzing. Click to enlarge image

Xem thêm Sơ đồ chân ESP8266Cách cấp nguồn cho ESP8266.

Mã ESP8266 – Bộ mã hóa quay

Đoạn mã ESP8266 dưới đây thực hiện:

  • Phát hiện hướng và lượng quay của bộ mã hóa.
    • Nếu phát hiện núm vặn quay được một nấc (nhấp) theo hướng kim đồng hồ, tăng bộ đếm lên một.
    • Nếu phát hiện núm vặn quay được một nấc (nhấp) theo hướng ngược kim đồng hồ, giảm bộ đếm đi một.
  • Phát hiện xem nút có được nhấn hay không.

Để đơn giản hóa mã nguồn cho việc chống rung nút, thư viện ezButton được sử dụng.

/* * Mã ESP8266 NodeMCU này được phát triển bởi newbiely.vn * Mã ESP8266 NodeMCU này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/esp8266/esp8266-rotary-encoder */ #include <ezButton.h> // The library to use for SW pin #define CLK_PIN D7 // The ESP8266 pin D7 connected to the rotary encoder's CLK pin #define DT_PIN D6 // The ESP8266 pin D6 connected to the rotary encoder's DT pin #define SW_PIN D5 // The ESP8266 pin D5 connected to the rotary encoder's SW pin #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction int counter = 0; int direction = DIRECTION_CW; int CLK_state; int prev_CLK_state; ezButton button(SW_PIN); // create ezButton object for pin 7; void setup() { Serial.begin(9600); // Configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // read the initial state of the rotary encoder's CLK pin prev_CLK_state = digitalRead(CLK_PIN); } void loop() { button.loop(); // MUST call the loop() function first // read the current state of the rotary encoder's CLK pin CLK_state = digitalRead(CLK_PIN); // If the state of CLK is changed, then pulse occurred // React to only the rising edge (from LOW to HIGH) to avoid double count if (CLK_state != prev_CLK_state && CLK_state == HIGH) { // if the DT state is HIGH // The encoder is rotating in counter-clockwise direction => decrease the counter if (digitalRead(DT_PIN) == HIGH) { counter--; direction = DIRECTION_CCW; } else { // The encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } Serial.print("Rotary Encoder:: direction: "); if (direction == DIRECTION_CW) Serial.print("CLOCKWISE"); else Serial.print("ANTICLOCKWISE"); Serial.print(" - count: "); Serial.println(counter); } // save last CLK state prev_CLK_state = CLK_state; if (button.isPressed()) { Serial.println("The button is pressed"); } }

Hướng dẫn từng bước

Để bắt đầu với ESP8266 trên Arduino IDE, hãy làm theo các bước sau:

  • Xem hướng dẫn ESP8266 - Cài đặt phần mềm nếu đây là lần đầu bạn sử dụng ESP8266.
  • Nối dây các thành phần như được hiển thị trong sơ đồ.
  • Kết nối bo mạch ESP8266 với máy tính bằng cáp USB.
  • Mở Arduino IDE trên máy tính của bạn.
  • Chọn bo mạch ESP8266 phù hợp, chẳng hạn như NodeMCU 1.0 (ESP-12E Module), và cổng COM tương ứng của nó.
  • Cài đặt thư viện ezButton trên Arduino IDE. Xem Hướng dẫn
  • Sao chép mã ở trên và mở bằng Arduino IDE.
  • Nhấn nút Upload trên Arduino IDE để tải mã lên ESP8266.
  • Xoay núm theo chiều kim đồng hồ, sau đó ngược chiều kim đồng hồ.
  • Nhấn núm.
  • Kiểm tra kết quả trên Serial Monitor.
COM6
Send
Rotary Encoder:: direction: CLOCKWISE - count: 1 Rotary Encoder:: direction: CLOCKWISE - count: 2 Rotary Encoder:: direction: CLOCKWISE - count: 3 Rotary Encoder:: direction: CLOCKWISE - count: 4 Rotary Encoder:: direction: CLOCKWISE - count: 5 Rotary Encoder:: direction: ANTICLOCKWISE - count: 4 Rotary Encoder:: direction: ANTICLOCKWISE - count: 3 Rotary Encoder:: direction: ANTICLOCKWISE - count: 2 Rotary Encoder:: direction: ANTICLOCKWISE - count: 1 Rotary Encoder:: direction: ANTICLOCKWISE - count: 0 The button is pressed
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Giải thích mã nguồn

Hãy xem các chú thích theo từng dòng trong mã nguồn.

Mã ESP8266 – Bộ mã hóa quay có ngắt

Trong mã trước đó, việc kiểm tra trạng thái của chân liên tục bằng cách dò (polling) có thể lãng phí tài nguyên và có thể không đếm đúng nếu các tác vụ khác mất nhiều thời gian. Ngắt (interrupts) cung cấp một giải pháp bằng cách tránh việc dò liên tục, cho phép ESP8266 xử lý các tác vụ khác nhau mà không bỏ lỡ bất kỳ sự kiện nào.

Đây là một ví dụ ESP8266 về cách đọc encoder quay bằng ngắt.

/* * Mã ESP8266 NodeMCU này được phát triển bởi newbiely.vn * Mã ESP8266 NodeMCU này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/esp8266/esp8266-rotary-encoder */ #include <ezButton.h> // The library to use for SW pin #define CLK_PIN D7 // The ESP8266 pin D7 connected to the rotary encoder's CLK pin #define DT_PIN D6 // The ESP8266 pin D6 connected to the rotary encoder's DT pin #define SW_PIN D5 // The ESP8266 pin D5 connected to the rotary encoder's SW pin #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction volatile int counter = 0; volatile int direction = DIRECTION_CW; volatile unsigned long last_time; // for debouncing int prev_counter; ezButton button(SW_PIN); // create ezButton object for pin 7; void ICACHE_RAM_ATTR INTERRUPT_handler() { if ((millis() - last_time) < 50) // debounce time is 50ms return; if (digitalRead(DT_PIN) == HIGH) { // The encoder is rotating in counter-clockwise direction => decrease the counter counter--; direction = DIRECTION_CCW; } else { // The encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } last_time = millis(); } void setup() { Serial.begin(9600); // Configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // use interrupt for CLK pin is enough // call INTERRUPT_handler() when CLK pin changes from LOW to HIGH attachInterrupt(digitalPinToInterrupt(CLK_PIN), INTERRUPT_handler, RISING); } void loop() { button.loop(); // MUST call the loop() function first if (prev_counter != counter) { Serial.print("Rotary Encoder:: direction: "); if (direction == DIRECTION_CW) Serial.print("CLOCKWISE"); else Serial.print("ANTICLOCKWISE"); Serial.print(" - count: "); Serial.println(counter); prev_counter = counter; } if (button.isPressed()) { Serial.println("The button is pressed"); } // TO DO: your other work here }

Bây giờ, khi bạn xoay núm, bạn sẽ thấy thông tin hiển thị trên Serial Monitor, giống như những gì bạn đã thấy trong mã trước đó.

※ Lưu ý:

  • Bạn có thể gặp các hướng dẫn trên các trang web khác sử dụng hai ngắt cho một bộ mã hóa duy nhất, nhưng điều này là không cần thiết và lãng phí. Chỉ cần một ngắt là đủ.
  • Việc sử dụng từ khóa volatile cho các biến toàn cục được sử dụng trong ngắt là rất quan trọng. Bỏ qua điều này có thể dẫn đến các vấn đề bất ngờ.
  • Giữ mã trong ngắt càng đơn giản càng tốt. Tránh sử dụng Serial.print() hoặc Serial.println() trong ngắt.

Ứng dụng bộ mã hóa quay ESP8266

Với bộ mã hóa quay, chúng ta có thể thực hiện các ứng dụng sau đây nhưng không giới hạn:

  • ESP8266 - Bộ mã hóa quay điều khiển vị trí của động cơ servo
  • ESP8266 - Bộ mã hóa quay điều khiển độ sáng của đèn LED
  • ESP8266 - Bộ mã hóa quay điều khiển tốc độ của động cơ bước

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.

Tham khảo hàm

Bài hướng dẫn liên quan