Hiểu cách hệ thống hoạt động
Điện thoại gửi các ký tự F, B, L, R và S qua Bluetooth để yêu cầu xe tiến, lùi, rẽ trái, rẽ phải hoặc dừng. ESP32 nhận ký tự rồi điều khiển hai động cơ thông qua mạch điều khiển động cơ. Khi rẽ, một bánh quay tiến và bánh còn lại quay lùi, giúp xe xoay tại chỗ.
Hướng dẫn này dùng Bluetooth Classic SPP với thư viện BluetoothSerial và thành phần BluetoothClient của MIT App Inventor. Hãy dùng bo ESP32 có hỗ trợ Bluetooth Classic, chẳng hạn bo dùng ESP32 nguyên bản; không dùng trực tiếp chương trình này cho ESP32-S2, ESP32-S3 hoặc ESP32-C3. Ứng dụng được thiết kế cho Android.
Chuẩn bị linh kiện và nối dây
Chuẩn bị một bo ESP32 phù hợp, mạch điều khiển động cơ TB6612FNG, hai động cơ DC gắn bánh xe, khung xe, nguồn phù hợp với động cơ, nguồn cấp ổn định cho ESP32 và dây nối. Trong bài này, PWMA và PWMB được đặt mức HIGH để xe chạy ở tốc độ cố định; chưa có chức năng chỉnh tốc độ.
Nối ESP32 với TB6612FNG như sau: GPIO26 → AIN1, GPIO27 → AIN2, GPIO25 → PWMA; GPIO32 → BIN1, GPIO33 → BIN2, GPIO14 → PWMB; GPIO13 → STBY. Nối động cơ bên trái vào AO1/AO2 và động cơ bên phải vào BO1/BO2. Nối chân VCC của TB6612FNG với 3,3 V, chân VM với nguồn động cơ phù hợp, và nối chung GND của mạch điều khiển, ESP32 và các nguồn.
Không cấp nguồn động cơ từ chân 3,3 V của ESP32 và không đưa điện áp 5 V vào GPIO. Kiểm tra điện áp định mức của động cơ, giới hạn của mạch điều khiển và cực tính nguồn trước khi bật điện. Có thể cấp nguồn cho ESP32 qua cổng USB trong lúc lắp ráp và thử nghiệm.
Nạp chương trình cho ESP32
Trong Arduino IDE, cài gói bo ESP32 phù hợp, chọn đúng bo và cổng kết nối, rồi nạp chương trình dưới đây. Mỗi lệnh hợp lệ sẽ được ghi nhận; nếu quá 500 mili giây không nhận thêm lệnh, xe tự dừng. Đây là biện pháp dự phòng khi kết nối hoặc ứng dụng bị gián đoạn, không thay thế việc giám sát xe.
#include <BluetoothSerial.h>
BluetoothSerial SerialBT;
const int AIN1 = 26, AIN2 = 27, PWMA = 25;
const int BIN1 = 32, BIN2 = 33, PWMB = 14;
const int STBY = 13;
unsigned long lastCommand = 0;
void stopMotors() {
digitalWrite(PWMA, LOW);
digitalWrite(PWMB, LOW);
}
void moveMotors(bool leftForward, bool rightForward) {
stopMotors();
digitalWrite(AIN1, leftForward ? HIGH : LOW);
digitalWrite(AIN2, leftForward ? LOW : HIGH);
digitalWrite(BIN1, rightForward ? HIGH : LOW);
digitalWrite(BIN2, rightForward ? LOW : HIGH);
digitalWrite(PWMA, HIGH);
digitalWrite(PWMB, HIGH);
}
void setup() {
const int pins[] = {AIN1, AIN2, PWMA, BIN1, BIN2, PWMB, STBY};
for (int pin : pins) {
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
digitalWrite(STBY, HIGH);
SerialBT.begin("ESP32_Robot_STEM");
}
void loop() {
while (SerialBT.available()) {
char command = SerialBT.read();
switch (command) {
case 'F': moveMotors(true, true); break;
case 'B': moveMotors(false, false); break;
case 'L': moveMotors(false, true); break;
case 'R': moveMotors(true, false); break;
case 'S': stopMotors(); break;
default: continue;
}
lastCommand = millis();
}
if (millis() – lastCommand > 500) stopMotors();
}
Nếu bánh quay ngược hướng dự kiến, ngắt nguồn trước khi đổi hai dây của động cơ tương ứng. Không cần sửa bảng chân hoặc ký tự lệnh chỉ để đảo chiều một động cơ.
Tạo giao diện trong MIT App Inventor
Tạo một dự án mới với một ListPicker để chọn thiết bị, năm Button mang nhãn Tiến, Lùi, Trái, Phải, Dừng, cùng hai thành phần không hiển thị BluetoothClient và Clock. Đặt TimerInterval của Clock là 100 mili giây và TimerEnabled ban đầu là false.
Trong sự kiện BeforePicking của ListPicker, đặt Elements bằng BluetoothClient1.AddressesAndNames. Trong AfterPicking, gọi BluetoothClient1.Connect với Selection; nếu kết nối thành công, đặt biến toàn cục lenh thành "S" và bật Clock.TimerEnabled. Nếu không kết nối được, giữ bộ hẹn giờ ở trạng thái tắt và kiểm tra việc ghép đôi trong cài đặt Bluetooth của Android.
Lập trình các nút điều khiển
Tạo biến toàn cục lenh, giá trị ban đầu là "S". Với mỗi nút hướng, dùng sự kiện TouchDown để đổi lenh tương ứng thành "F", "B", "L" hoặc "R"; dùng TouchUp để đổi lenh trở lại "S". Với nút Dừng, đặt lenh thành "S" khi nhấn. Trong sự kiện Clock.Timer, nếu BluetoothClient1.IsConnected là true, gọi BluetoothClient1.SendText với lenh.
Nhờ gửi lặp lại khoảng 100 mili giây một lần, ESP32 tiếp tục chạy khi người dùng giữ nút và dừng khi thả. Nếu việc gửi lệnh bị ngắt, bộ hẹn giờ 500 mili giây trên ESP32 sẽ cho xe dừng. Chỉ gửi một ký tự cho mỗi lệnh; không thêm dấu xuống dòng hoặc khoảng trắng.
Thử xe theo từng bước
Đặt xe sao cho hai bánh không chạm sàn. Bật nguồn, ghép đôi điện thoại Android với thiết bị có tên ESP32_Robot_STEM trong cài đặt Bluetooth, rồi mở ứng dụng để chọn và kết nối thiết bị. Nếu Android yêu cầu quyền sử dụng Bluetooth hoặc thiết bị ở gần, hãy cấp quyền cần thiết cho ứng dụng.
Giữ từng nút hướng trong thời gian ngắn để quan sát chiều quay hai bánh; thả nút và xác nhận bánh dừng. Sau đó đặt xe xuống một khu vực trống, thử ở khoảng cách gần và luôn sẵn sàng ngắt nguồn. Không thử xe gần mép bàn, cầu thang hoặc vật dễ vỡ.
Xử lý lỗi thường gặp và mở rộng bài học
Nếu không thấy thiết bị trong danh sách, hãy kiểm tra bo có hỗ trợ Bluetooth Classic, ESP32 đã được cấp nguồn và điện thoại đã ghép đôi với thiết bị. Nếu ứng dụng kết nối được nhưng động cơ không chạy, kiểm tra nguồn VM, chân STBY, dây GND chung và các chân nối theo sơ đồ. Nếu xe tự dừng dù vẫn giữ nút, kiểm tra sự kiện Clock.Timer có đang gửi lệnh liên tục hay không.
Khi xe đã chạy ổn định, học sinh có thể mở rộng bằng cách tạo các mức tốc độ với PWM và giao diện chọn tốc độ. Trước khi sửa chương trình, hãy vẽ bảng dự đoán trạng thái của hai động cơ cho từng lệnh; sau khi sửa, thử lại từng lệnh với bánh xe được nhấc khỏi sàn.


