Hướng dẫn dùng thanh cảm biến dò line 5 kênh TCRT5000 với ESP32
- 1. Tìm hiểu thanh dò line 5 kênh TCRT5000
- 2. Cảm biến phân biệt vạch đen và nền trắng như thế nào?
- 3. Linh kiện cần chuẩn bị
- 4. Sơ đồ nối thanh dò line với ESP32
- 5. Cài đặt Arduino IDE
- 6. Chương trình 1: đọc trạng thái 5 kênh
- 7. Chương trình 2: tính vị trí vạch và gợi ý hướng lái
- 8. Giải thích các lệnh chính
- 9. Lắp đặt và canh chỉnh
- 10. Xử lý lỗi thường gặp
Hướng dẫn nối thanh dò line 5 kênh TCRT5000 (BFD-1000) với ESP32 DevKit V1, đọc trạng thái 5 kênh trên Serial Monitor, tính vị trí vạch và gợi ý hướng lái cho xe dò line.
Thanh dò line 5 kênh TCRT5000 (model BFD-1000) gồm năm cảm biến phản xạ hồng ngoại hướng xuống sàn, một cảm biến hồng ngoại phát hiện vật cản phía trước và một công tắc hành trình báo va chạm. Mọi ngõ ra đều là tín hiệu số 0/1 nên ESP32 đọc trực tiếp bằng chân GPIO. Bài viết hướng dẫn nối thanh cảm biến với ESP32 DevKit V1, đọc trạng thái năm kênh trên Serial Monitor, sau đó đổi trạng thái này thành vị trí vạch và gợi ý hướng lái cho xe dò line bằng Arduino IDE.
1. Tìm hiểu thanh dò line 5 kênh TCRT5000
| Thông số | Giá trị |
|---|---|
| Model | BFD-1000 |
| Cảm biến dò line | 5 cảm biến phản xạ hồng ngoại TCRT5000 (S1–S5), hướng xuống sàn |
| Cảm biến phụ | Cảm biến hồng ngoại phát hiện vật cản phía trước (Near) và công tắc hành trình báo va chạm (CLP) |
| Tín hiệu ra | 7 ngõ ra số, mỗi ngõ ra ở mức 0 hoặc 1 |
| Hàng chân | 9 chân, in theo thứ tự VCC, GND, S1, S2, S3, S4, S5, CLP, Near |
| Nguồn cấp | Dùng 3,3 V khi nối với ESP32. Dải thường được công bố cho model BFD-1000 là 3,0–5,5 V; kiểm tra thông tin của lô hàng |
| Chiều dài thanh | Khoảng 128 mm |
Năm cảm biến TCRT5000 được hàn ở mặt dưới của mạch. Mặt trên có hàng chân, IC xử lý tín hiệu và các LED báo: mỗi kênh S1–S5 có một LED, ngoài ra còn LED nguồn (PWR), LED của công tắc hành trình (CLP) và LED của cảm biến vật cản (Near). Cảm biến S3 nằm giữa và nhô về phía trước so với bốn cảm biến còn lại. Biến trở trên mạch dùng để chỉnh tầm phát hiện của cảm biến vật cản; năm kênh dò line không có biến trở chỉnh độ nhạy.
2. Cảm biến phân biệt vạch đen và nền trắng như thế nào?
Mỗi TCRT5000 gồm một LED phát hồng ngoại (bước sóng 950 nm) và một phototransistor đặt cạnh nhau trong cùng một vỏ, có lớp lọc ánh sáng nhìn thấy. LED chiếu tia hồng ngoại xuống sàn. Nền trắng phản xạ phần lớn tia trở lại nên phototransistor dẫn mạnh. Vạch đen hấp thụ phần lớn tia nên phototransistor gần như ngắt.
Mạch trên module đổi hai trạng thái đó thành mức logic ở chân S tương ứng và làm LED báo của kênh đổi trạng thái theo. Với model BFD-1000, thông tin thường gặp là: kênh nằm trên nền trắng cho mức 1 (HIGH), kênh nằm trên vạch đen hoặc không có vật phản xạ cho mức 0 (LOW). Mức logic có thể khác nhau giữa các lô hàng, vì vậy hãy xác nhận trên module của bạn bằng chương trình ở mục 6 trước khi viết chương trình điều khiển xe.
Theo datasheet, TCRT5000 nhạy nhất khi cách bề mặt khoảng 2,5 mm và còn làm việc trong khoảng 0,2–15 mm. Vì vậy thanh cảm biến phải đặt sát mặt sàn, không dùng để phát hiện vạch từ xa.
3. Linh kiện cần chuẩn bị
- ESP32 DevKit V1 30 chân và cáp USB có truyền dữ liệu.
- Thanh dò line 5 kênh TCRT5000 (BFD-1000).
- 9 dây jumper cái – cái; nếu ESP32 cắm trên breadboard thì dùng dây cái – đực.
- Một tờ giấy trắng và băng keo đen để làm vạch thử.
- Máy tính đã cài Arduino IDE 2.x.
- Tùy chọn: đế ra chân ESP32 loại 30 chân để bắt dây chắc chắn khi lắp lên xe.
4. Sơ đồ nối thanh dò line với ESP32
| Thanh dò line | ESP32 DevKit V1 | Ghi chú |
|---|---|---|
| VCC | 3V3 | Nguồn 3,3 V, để ngõ ra của module cùng mức logic với ESP32. |
| GND | GND | Mass chung. |
| S1 | D4 / GPIO4 | Kênh ngoài cùng bên trái. |
| S2 | RX2 / GPIO16 | Chân in chữ RX2 trên bo. |
| S3 | TX2 / GPIO17 | Kênh giữa. Chân in chữ TX2 trên bo. |
| S4 | D18 / GPIO18 | Bỏ qua chân D5 nằm giữa TX2 và D18. |
| S5 | D19 / GPIO19 | Kênh ngoài cùng bên phải. |
| CLP | D21 / GPIO21 | Công tắc hành trình. Chưa dùng thì có thể chưa nối. |
| Near | D22 / GPIO22 | Cảm biến vật cản. Chưa dùng thì có thể chưa nối. |
Chín dây đều nằm ở hàng chân bên phải của ESP32 DevKit V1, theo đúng thứ tự in trên module. Luôn nối theo tên chân in trên mạch, không nối theo màu dây.
Vì sao cấp nguồn 3,3 V?
GPIO của ESP32 chỉ làm việc với mức 3,3 V và không chịu được 5 V. Mức cao ở ngõ ra của module xấp xỉ điện áp cấp vào chân VCC. Nếu cấp 5 V từ chân VIN, ngõ ra sẽ lên gần 5 V và có thể làm hỏng chân GPIO. Cấp 3,3 V thì nối trực tiếp được; đổi lại LED hồng ngoại phát yếu hơn nên cần đặt cảm biến gần mặt sàn hơn. Nếu bắt buộc dùng 5 V, phải hạ áp từng ngõ ra bằng cầu phân áp hoặc mạch chuyển mức trước khi đưa vào ESP32.
Vì sao bỏ trống D15, D2, D5, RX0, TX0?
- D2, D5, D15 (GPIO2, GPIO5, GPIO15) là chân strapping: ESP32 đọc mức của các chân này lúc khởi động. GPIO2 phải ở mức thấp hoặc thả nổi thì ESP32 mới vào được chế độ nạp chương trình. Nếu một kênh cảm biến đang giữ chân này ở mức cao, việc nạp sẽ thất bại. GPIO2 còn nối với LED trên bo.
- RX0, TX0 (GPIO3, GPIO1) dùng cho việc nạp chương trình và Serial Monitor.
Khi cần đổi chân, chọn trong các chân D13, D14, D23, D25, D26, D27, D32, D33 và sửa lại số chân trong chương trình. Tránh D12 vì đây cũng là chân strapping. Các chân D34, D35, VP, VN chỉ là đầu vào và không có điện trở kéo bên trong, chỉ nên dùng khi thiếu chân. D21 và D22 là cặp chân I2C mặc định; nếu sau này gắn thêm màn hình OLED I2C, chuyển CLP và Near sang hai chân khác.
5. Cài đặt Arduino IDE
- Mở Tools > Board > Boards Manager, tìm esp32 và cài gói esp32 by Espressif Systems.
- Chọn Tools > Board > esp32 > DOIT ESP32 DEVKIT V1 (hoặc ESP32 Dev Module), sau đó chọn đúng cổng COM trong Tools > Port.
Bài này không cần cài thêm thư viện: hai chương trình chỉ dùng các hàm có sẵn pinMode(), digitalRead() và Serial. Bài dùng gói esp32 phiên bản 3.3.10.
6. Chương trình 1: đọc trạng thái 5 kênh
Nạp chương trình dưới đây rồi mở Serial Monitor ở tốc độ 115200 baud:
/*
PYWORLD.VN - ESP32 DevKit V1 + thanh dò line 5 kênh TCRT5000 (BFD-1000)
Chương trình 1: đọc 5 kênh dò line S1..S5, công tắc hành trình CLP và cảm biến vật cản Near
Nguồn module: VCC nối 3V3, GND nối GND của ESP32
*/
// Khai báo chân (không dùng các chân strapping GPIO2, GPIO5, GPIO15)
#define S1_PIN 4 // D4
#define S2_PIN 16 // RX2
#define S3_PIN 17 // TX2
#define S4_PIN 18 // D18
#define S5_PIN 19 // D19
#define CLP_PIN 21 // D21 - Công tắc hành trình báo va chạm
#define NEAR_PIN 22 // D22 - Cảm biến hồng ngoại phát hiện vật cản
void setup() {
// Khởi tạo Serial
Serial.begin(115200);
// Ngõ ra của module là tín hiệu số, chỉ cần cấu hình input
pinMode(S1_PIN, INPUT);
pinMode(S2_PIN, INPUT);
pinMode(S3_PIN, INPUT);
pinMode(S4_PIN, INPUT);
pinMode(S5_PIN, INPUT);
pinMode(CLP_PIN, INPUT);
pinMode(NEAR_PIN, INPUT);
Serial.println("=== Test cam bien line + CLP + NEAR ===");
}
void loop() {
// Đọc mức logic của từng ngõ ra
int s1 = digitalRead(S1_PIN);
int s2 = digitalRead(S2_PIN);
int s3 = digitalRead(S3_PIN);
int s4 = digitalRead(S4_PIN);
int s5 = digitalRead(S5_PIN);
int clp = digitalRead(CLP_PIN);
int near = digitalRead(NEAR_PIN);
// In ra Serial Monitor
Serial.print("Line: ");
Serial.print(s1); Serial.print(" ");
Serial.print(s2); Serial.print(" ");
Serial.print(s3); Serial.print(" ");
Serial.print(s4); Serial.print(" ");
Serial.print(s5);
Serial.print(" | CLP: ");
Serial.print(clp);
Serial.print(" | NEAR: ");
Serial.println(near);
delay(200); // In chậm lại cho dễ đọc
}
Cứ 0,2 giây Serial Monitor in một dòng gồm mức logic của năm kênh theo thứ tự S1 đến S5, tiếp theo là CLP và NEAR. Ví dụ khi thanh cảm biến đặt trên nền trắng, chỉ S3 nằm trên vạch đen và module cho mức 0 khi gặp vạch (giá trị CLP, NEAR trên module của bạn có thể khác):
=== Test cam bien line + CLP + NEAR ===
Line: 1 1 0 1 1 | CLP: 0 | NEAR: 0
Line: 1 1 0 1 1 | CLP: 0 | NEAR: 0
Xác định mức logic của từng ngõ ra
- Đặt thanh cảm biến trên tờ giấy trắng, mặt cảm biến cách giấy khoảng 5–10 mm. Giá trị của năm kênh lúc này là mức ứng với nền trắng.
- Kéo vạch đen lần lượt qua dưới từng cảm biến. Kênh nằm trên vạch đổi sang mức ngược lại, LED báo của kênh đó cũng đổi trạng thái. Đây là mức ứng với vạch.
- Nhấc thanh cảm biến lên cao khỏi mặt giấy. Không còn tia phản xạ nên cả năm kênh thường cho cùng mức với vạch đen.
- Nhấn công tắc hành trình và xem giá trị CLP đổi mức.
- Đưa bàn tay lại gần cặp LED hồng ngoại phía trước và xem giá trị NEAR đổi mức. Vặn biến trở từng chút để thay đổi khoảng cách phát hiện.
Ghi lại mức của kênh khi nằm trên vạch đen: chương trình 2 cần giá trị này. Nếu vạch đen cho mức 0 thì giữ nguyên chương trình 2; nếu vạch đen cho mức 1 thì sửa hằng số LINE_LEVEL thành HIGH.
7. Chương trình 2: tính vị trí vạch và gợi ý hướng lái
Gán cho năm kênh S1 đến S5 các trọng số −2, −1, 0, +1, +2. Vị trí của vạch bằng tổng trọng số của các kênh đang thấy vạch chia cho số kênh thấy vạch. Kết quả nằm trong khoảng −2 đến +2: số âm nghĩa là vạch lệch về bên trái xe, số dương là lệch về bên phải, 0 là vạch ở giữa.
/*
PYWORLD.VN - ESP32 DevKit V1 + thanh dò line 5 kênh TCRT5000 (BFD-1000)
Chương trình 2: đổi trạng thái 5 kênh thành vị trí vạch (-2 ... +2) và gợi ý hướng lái
Lắp thanh cảm biến sao cho S1 nằm bên trái, S5 nằm bên phải của xe
*/
const int LINE_PINS[5] = {4, 16, 17, 18, 19}; // S1, S2, S3, S4, S5
const int WEIGHTS[5] = {-2, -1, 0, 1, 2}; // Trọng số: S1 = -2 (trái) ... S5 = +2 (phải)
// Mức logic của một kênh khi cảm biến nằm trên vạch (xem kết quả chương trình 1).
// Đổi thành HIGH nếu module cho mức 1 khi gặp vạch.
const int LINE_LEVEL = LOW;
const float CENTER_BAND = 0.25; // |vị trí| không vượt quá giá trị này thì coi như vạch ở giữa
float lastPosition = 0; // Vị trí gần nhất khi còn thấy vạch
void setup() {
Serial.begin(115200);
for (int i = 0; i < 5; i++) {
pinMode(LINE_PINS[i], INPUT);
}
Serial.println("=== Tinh vi tri vach tu 5 kenh do line ===");
}
void loop() {
char pattern[6]; // 5 ký tự '0'/'1' và ký tự kết thúc chuỗi
int sum = 0; // Tổng trọng số của các kênh thấy vạch
int count = 0; // Số kênh thấy vạch
for (int i = 0; i < 5; i++) {
bool onLine = (digitalRead(LINE_PINS[i]) == LINE_LEVEL);
pattern[i] = onLine ? '1' : '0'; // 1 = kênh thấy vạch, 0 = kênh thấy nền
if (onLine) {
sum += WEIGHTS[i];
count++;
}
}
pattern[5] = '\0';
Serial.print("Mau: ");
Serial.print(pattern);
if (count == 0) {
// Không kênh nào thấy vạch: dựa vào vị trí gần nhất để tìm lại
Serial.print(" | Mat vach -> ");
if (lastPosition < 0) {
Serial.println("quay trai de tim lai");
} else if (lastPosition > 0) {
Serial.println("quay phai de tim lai");
} else {
Serial.println("dung lai");
}
} else if (count == 5) {
Serial.println(" | Ca 5 kenh thay vach -> vach ngang hoac giao lo");
} else {
float position = (float)sum / count; // Trung bình trọng số, từ -2.0 đến +2.0
lastPosition = position;
Serial.print(" | Vi tri: ");
if (position > 0) Serial.print("+");
Serial.print(position, 1);
if (position < -CENTER_BAND) {
Serial.println(" | Vach lech trai -> re trai");
} else if (position > CENTER_BAND) {
Serial.println(" | Vach lech phai -> re phai");
} else {
Serial.println(" | Vach o giua -> di thang");
}
}
delay(200); // In chậm lại cho dễ đọc
}
Kéo vạch đen qua lại dưới thanh cảm biến, Serial Monitor hiển thị tương tự các dòng sau (chuỗi Mau gồm 5 ký tự ứng với S1 đến S5, 1 là kênh thấy vạch):
=== Tinh vi tri vach tu 5 kenh do line ===
Mau: 00100 | Vi tri: 0.0 | Vach o giua -> di thang
Mau: 01100 | Vi tri: -0.5 | Vach lech trai -> re trai
Mau: 01000 | Vi tri: -1.0 | Vach lech trai -> re trai
Mau: 00011 | Vi tri: +1.5 | Vach lech phai -> re phai
Mau: 00000 | Mat vach -> quay phai de tim lai
Mau: 11111 | Ca 5 kenh thay vach -> vach ngang hoac giao lo
Dòng Ca 5 kenh thay vach cũng xuất hiện khi xe bị nhấc khỏi mặt sàn, vì lúc đó cả năm kênh đều không nhận được tia phản xạ.
8. Giải thích các lệnh chính
pinMode(S1_PIN, INPUT): ngõ ra của module đã là tín hiệu số nên chân ESP32 chỉ cần cấu hình là đầu vào.digitalRead(): trả về 0 hoặc 1 theo mức điện áp tại chân. Chương trình 1 in thẳng giá trị này để biết module đang xuất mức nào.LINE_LEVELvà phép so sánhdigitalRead(LINE_PINS[i]) == LINE_LEVEL: biếnonLinebằngtruekhi kênh thấy vạch, dù module cho mức 0 hay mức 1 khi gặp vạch. Nhờ vậy phần tính toán phía sau không phải sửa khi đổi loại module hoặc đổi sang vạch trắng trên nền đen.WEIGHTS,sumvàcount: cộng trọng số của các kênh thấy vạch rồi chia cho số kênh. Ví dụ S2 và S3 cùng thấy vạch thì vị trí là (−1 + 0) / 2 = −0,5.CENTER_BAND: vị trí trong khoảng −0,25 đến +0,25 được coi là vạch ở giữa. Ngoài khoảng này chương trình gợi ý rẽ trái hoặc rẽ phải.lastPosition: lưu vị trí gần nhất khi còn thấy vạch. Khi cả năm kênh đều không thấy vạch, chương trình dựa vào dấu của biến này để gợi ý quay về phía vạch vừa biến mất.count == 5: cả năm kênh thấy vạch, thường là vạch ngang hoặc giao lộ. Chương trình điều khiển xe có thể dùng trường hợp này để dừng hoặc đếm vạch.delay(200): chỉ để dòng chữ trên Serial Monitor dễ đọc. Khi điều khiển xe thật, bỏ lệnh này hoặc giảm còn vài mili giây để xe phản ứng kịp.
Giá trị position có thể dùng trực tiếp để điều khiển: giá trị càng xa 0 thì chênh lệch tốc độ giữa hai bánh càng lớn. Trọng số trong bài là số thứ tự của kênh; nếu cần chính xác hơn, đo khoảng cách từ từng cảm biến tới S3 trên mạch và dùng số đo đó làm trọng số.
9. Lắp đặt và canh chỉnh
- Hướng lắp: mặt có chữ hướng lên, phần có công tắc hành trình hướng về phía trước xe. Khi đó S1 nằm bên trái và S5 nằm bên phải theo hướng xe chạy. Nếu lắp ngược lại, đảo thứ tự chân trong mảng
LINE_PINS. - Độ cao: bắt đầu với khoảng cách 5–10 mm giữa mặt cảm biến và mặt sàn, giữ thanh song song với sàn để năm kênh cách sàn như nhau. Chạy chương trình 1 rồi hạ thấp hoặc nâng dần cho tới khi cả năm kênh đổi mức dứt khoát giữa nền và vạch.
- Vạch và nền: dùng vạch đen mờ trên nền trắng hoặc nền sáng màu. Bề mặt bóng có thể phản xạ tia hồng ngoại làm kênh đọc sai.
- Bề rộng vạch: nên gần bằng khoảng cách giữa hai cảm biến kề nhau. Vạch hẹp hơn nhiều thì sẽ có lúc vạch lọt vào khe giữa hai cảm biến và không kênh nào thấy vạch dù xe vẫn ở trên đường.
- Ánh sáng: tránh để nắng hoặc đèn sợi đốt chiếu thẳng vào gầm xe. TCRT5000 có lớp lọc ánh sáng nhìn thấy nhưng vẫn bị ảnh hưởng bởi nguồn hồng ngoại mạnh.
- Cảm biến vật cản: đặt vật cản ở khoảng cách muốn phát hiện rồi vặn biến trở tới khi giá trị NEAR vừa đổi mức. Tầm phát hiện phụ thuộc màu và kích thước vật cản, nên đo lại bằng chương trình 1.
10. Xử lý lỗi thường gặp
- Cả năm kênh không đổi mức khi kéo vạch qua: kiểm tra LED PWR có sáng không, dây VCC và GND, sau đó hạ thấp thanh cảm biến. Đặt quá cao thì kênh luôn báo như đang ở trên vạch đen.
- LED báo của kênh đổi trạng thái nhưng giá trị trên Serial Monitor đứng yên: dây tín hiệu của kênh đó bị hở hoặc cắm nhầm chân. Đối chiếu lại bảng nối dây ở mục 4.
- Giá trị một kênh nhảy lung tung: chân đầu vào đang thả nổi do dây lỏng, hoặc ESP32 và module chưa nối chung GND.
- Kênh nhấp nháy 0/1 khi vạch nằm ngay mép cảm biến: đây là vùng chuyển tiếp. Chỉnh lại độ cao; trong chương trình điều khiển có thể đọc vài lần liên tiếp rồi mới kết luận.
- Chương trình 2 báo ngược, đặt trên nền trắng lại in Ca 5 kenh thay vach: hằng số
LINE_LEVELchưa đúng với module. Đổi giữaLOWvàHIGH. - Vạch ở bên phải nhưng chương trình báo lệch trái: thanh cảm biến đang lắp ngược chiều. Đảo thứ tự chân trong
LINE_PINS. - Không nạp được chương trình: dùng cáp USB có truyền dữ liệu, chọn đúng cổng COM. Nếu IDE dừng ở dòng Connecting..., giữ nút BOOT trên ESP32 cho đến khi bắt đầu nạp. Kiểm tra không có dây cảm biến nào cắm vào D2, RX0 hoặc TX0.
- Serial Monitor hiện ký tự lạ: chọn đúng tốc độ 115200 baud.
Xem thêm: ESP32 điều khiển module relay 4 kênh và nạp file .bin vào ESP32 bằng Flash Download Tool. Linh kiện liên quan: ESP32 DevKit V1 30 chân dùng chip CH340 và các loại cảm biến khác trong danh mục Cảm biến.
Xem thêm