Nội dung bài viết
Kim Uyên Bài viết hướng dẫn cách sử dụng cảm biến đo tốc độ IR FC-03 kết hợp với vòng xoay encoder 15 lỗ, để xác định tốc độ của động cơ DC. Khi có tốc độ, ta có thể thực hiện điều chỉnh tốc độ của động cơ để cho xe chạy thẳng, thông qua mạch L298.

Giới thiệu

Bạn muốn:

  • Biết quãng đường mà xe di chuyển bao xa.
  • Cho xe di chuyển một đoạn xác định, rẽ trái, rẽ phải.
  • Điều chỉnh tốc độ của động cơ để xe di chuyển thẳng.

Các bạn đều có thể làm được bằng cách sử dụng cảm biến tốc độ IR FC-03 để xác định tốc độ của động cơ DC quay bánh xe.

Bài viết này sẽ hướng dẫn cho bạn có thể hiểu và sử dụng được cảm biến tốc độ, và dựa vào kiến thức cơ bản này, bạn sẽ làm được những gì bạn muốn.

Tiền đề bài viết

Như vấn đề chúng tôi đã trình bày ở bài viết Điều Khiển Động Cơ Bằng IC L298. Về thông số kĩ thuật các motor được thiết kế với tốc độ bằng nhau, nhưng thực tế mức độ bằng nhau chỉ là tương đối. Và nó còn phụ thuộc vào nguồn điện mà ta cấp cho motor. Vấn đề là chúng tôi muốn hai bánh xe di chuyển với tốc độ bằng nhau để xe có thể chạy thẳng. Để giải quyết vấn đề này, phải lấy được tốc độ của 2 bánh xe, để từ đó, cân bằng tốc độ giữa 2 bánh bằng việc thực hiện điều xung sử dụng IC L298.

Vấn đề thứ 2, khi xe gặp vật cản, xe sẽ xoay trái hay phải một góc 90 độ theo hướng không có vật cản để đi về hướng đó. Vậy phải làm sao để xác định xe đã xoay đến đúng 90 độ để dừng lại không xoay nữa. Ý tưởng ban đầu của chúng tôi là thực hiện gọi hàm delay(delta time). Tuy nhiên, sau khi thử nghiệm thực tế thì kết quả không như chúng tôi mong muốn, việc delay sẽ làm xe xoay một góc khác nhau tùy vào loại sàn (sàn gỗ, sàn gạch men, di chuyển trên thảm). Do mỗi loại sàn trên có độ trơn, nhám khác nhau.

Chúng tôi đã được anh Vũ Quang Huy chỉ ra các nhược điểm ở trên và gợi ý việc sử dụng cảm biến IR FC-03 để giải quyết các vấn đề này.

Đối tượng hướng đến

Bài viết dành cho các bạn có kiến thức lập trình C++ và nắm được cơ bản việc sử dụng Arduino.

Bạn đọc có thể tham khảo các bài viết khác về Arduino trong Chuyên Mục Arduino.

Các linh kiện điện tử cần thiết được đề cập trong bài viết, các bạn có thể tự mua hoặc truy cập STDIO Electronics để đặt hàng.

Thiết bị cần chuẩn bị

Bạn cần chuẩn bị các thiết bị sau:

  • 1 x Arduino Uno R3.
  • 1 x Cảm biến tốc độ IR FC-03.
  • 1 x Đĩa encoder 15 lỗ.

Cảm biến tốc độ IR FC-03

ss1_FC-03   ss2_FC-03

Thành phần cấu tạo

  • 1 x Bộ thu phát ITR9608: Chân số 2 có chứa diode phát tia hồng ngoại, chân số 1 chứa 1 phototransistor để thu nhận tín hiệu hồng ngoại.
  • 1 x IC LM393.

Các chân cắm:

  • VCC: cảm biến chịu được mức điện áp từ 3.3 - 5V. Chân này được nối với pin nguồn 5V của Arduino.
  • GND: nối với pin nguồn GND của arduino.
  • DO: chân cho tín hiệu số đi ra của cảm biến (High / Low).
  • AO: chân cho tín hiệu tương tự đi ra từ cảm biến. Chân này tôi không sử dụng.

Nguyên lý hoạt động

ss3_encoderDisc

Khi motor quay thì đĩa encoder quay, lúc này, giá trị ở chân DO của FC-03 chuyển đổi liên tục từ LOW sang HIGH và từ HIGH sang LOW. Nguyên nhân là do khi FC-03 được cấp điện, diode ở chân số 2 của ITR9608 phát ra tia hồng ngoại, nếu tia hồng ngoại được truyền thông qua lỗ của đĩa encoder, phototransistor nhận được tín hiệu và chuyển output của chân DO lên mức HIGH. Ngược lại, khi tia hồng ngoại bị cản bởi đĩa encoder, phototransistor không nhận được tín hiệu, chân DO được chuyển về mức LOW.

Dựa vào nguyên lý ngày, để lấy được số vòng quay của động cơ trong một khoảng thời gian, ta chỉ cần đếm số lỗ mà FC-03 bắt được trong khoảng thời gian đó. Tức là ta sẽ đếm số lần mà pin 2 của Arduino chuyển từ HIGH sang LOW.

Hiện thực với code

Để bắt được sự thay đổi trạng thái của đầu ra DO trên FC-03, ta phải sử dụng kĩ thuật interrupt. Tác vụ được gọi bởi interrupt do sự thay đổi nào đó ở phần cứng, tác vụ này được gọi ngầm định bởi chương trình. Arduino đã hỗ trợ hàm cho chúng ta thực hiện gọi interrupt, biến lưu số lỗ mà FC-03 bắt được sẽ tăng một đơn vị khi ngắt xảy ra (pin 2 có hiện tượng chuyển từ HIGHT sang LOW).

Chương trình dưới đây thực hiện tính số vòng quay của motor trong một phút và in kết quả đến terminal.

#define PIN_DO 2
volatile unsigned int pulses;
float rpm;
unsigned long timeOld;
#define HOLES_DISC 15

void counter()
{
  pulses++;
}

void setup()
{
  Serial.begin(9600);
  pinMode(PIN_DO, INPUT);
  pulses = 0;
  timeOld = 0;
  attachInterrupt(digitalPinToInterrupt(PIN_DO), counter, FALLING);
}

void loop()
{
  if (millis() - timeOld >= 1000)
  {
    detachInterrupt(digitalPinToInterrupt(PIN_DO));
    rpm = (pulses * 60) / (HOLES_DISC);
    Serial.println(rpm);
    
    timeOld = millis();
    pulses = 0;
    attachInterrupt(digitalPinToInterrupt(PIN_DO), counter, FALLING);  
  }
}

Chi tiết:

Dòng 1: Định nghĩa pin 2 trên Arduino cho interrupt để nhận tín hiệu từ chân DO. Đối với board Arduino UNO, chỉ có 2 pin được sử dụng cho interrupt là pin 2 và pin 3.

Dòng 2: Khai báo biến lưu số lỗ mà FC-03 bắt được trong một giây. Biến được khai báo ở dạng volatile có nghĩa là ra lệnh cho trình biên dịch biết rằng giá trị của biến có thể bị thay đổi bởi một lời gọi hàm ngầm định nào đó. Vì thế, mỗi lần biến pulses được truy xuất, chương trình sẽ thực hiện load lại giá trị từ ô nhớ của pulses vào thanh ghi.

Dòng 3: Biến lưu giá trị tốc độ tính được: số vòng trên phút.

Dòng 4: Biến lưu giá trị thời điểm trước đó bắt đầu tính số lỗ đã đi qua.

Dòng 5: Số lỗ trên đĩa encoder.

Dòng 7 - 10: Hàm được gọi khi có interrupt xảy ra. Để tăng số lỗ mà cảm biến bắt được.

Dòng 15: Khai báo sử dụng pin 2 để nhận giá trị từ chân DO của FC-03.

Dòng 18: Ra lệnh khởi động interrupt. Hàm attachInterrupt có 3 tham số:

  1. Pin interrupt: sử dụng hàm số digitalPinToInterrupt để chuyển từ pin trên Arduino sang pin của interrupt. Pin 2: pin 0 của interrupt; Pin 3: pin 1 của interrupt.
  2. ISR: Hàm để gọi khi interrupt xảy ra. Hàm phải không chứa tham số và giá trị trả về là void.
  3. Mode: Xác định khi nào interrupt sẽ được khởi động. LOW - bất cứ khi nào pin interrupt ở mức LOW; CHANGE- bất cứ khi nào pin interrupt thay đổi giá trị; RISING - khi pin interrupt chuyển từ LOW sang HIGH; FALLING - khi pin interrupt chuyển từ HIGH sang LOW.

Dòng 23: Mỗi một giây, tốc độ được thực hiện tính toán.

Dòng 25: Ra lệnh ngưng quá trình interrupt để thực hiện tính toán.

Dòng 26: Tính toán giá trị tốc độ dựa vào thời gian và số lỗ đếm được.

Dòng 31: Khởi động lại interrupt.

Hình ảnh bên dưới là phần chúng tôi sử dụng cảm biến FC-03 trong xe. Chúng tôi sử dụng mạch điều khiển động cơ L298 để điều khiển motor DC. Bạn có thể tham khảo bài viết tại Điều Khiển Động Cơ Bằng IC L298. Để demo kết quả cho các bạn xem, tôi sử dụng hệ thống này và cho ra kết quả được trình bày bên dưới.

ss4_demo

Kết quả

ss5_result

THẢO LUẬN
ĐÓNG