ESP32 Bluetooth Joystick Example Hướng Dẫn Giao Diện Điều Khiển 2D Tương Tác

Tổng Quan

Ví dụ Bluetooth Joystick cung cấp bộ điều khiển joystick 2D tương tác có thể truy cập thông qua ứng dụng DIYables Bluetooth STEM. Được thiết kế cho board ESP32 với hỗ trợ cả BLE (Bluetooth Low Energy)Classic Bluetooth. Joystick gửi giá trị tọa độ X và Y theo thời gian thực từ -100 đến +100, lý tưởng cho điều khiển robot, điều khiển động cơ, định vị servo và bất kỳ ứng dụng nào cần đầu vào hướng.

Ví dụ này hỗ trợ hai chế độ Bluetooth:

  • ESP32 BLE (Bluetooth Low Energy): Hoạt động trên cả Android và iOS
  • ESP32 Classic Bluetooth: Chỉ hoạt động trên Android. iOS không hỗ trợ Classic Bluetooth. Sử dụng BLE nếu bạn cần hỗ trợ iOS.
ESP32 Bluetooth joystick example - hướng dẫn giao diện Điều khiển 2d tương tác

Tính Năng

  • Điều Khiển 2D: Trục X và Y với giá trị từ -100 đến +100
  • Cập Nhật Thời Gian Thực: Cập nhật vị trí tức thì qua giao tiếp Bluetooth
  • Tùy Chọn Tự Động Về Tâm: Có thể cấu hình tự động về vị trí trung tâm (0, 0)
  • Độ Nhạy Điều Chỉnh: Cấu hình ngưỡng chuyển động tối thiểu để lọc các thay đổi nhỏ
  • Tương Thích Robot: Giá trị dễ dàng ánh xạ đến đầu vào driver động cơ
  • BLE & Classic Bluetooth: Chọn chế độ Bluetooth phù hợp với dự án của bạn
  • Đa Nền Tảng: Chế độ BLE hoạt động trên cả Android và iOS; Classic Bluetooth hoạt động trên Android
  • Tùy Chọn Tiết Kiệm Điện: Chế độ BLE tiêu thụ ít điện hơn Classic Bluetooth

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×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)

Code ESP32

Các Bước Nhanh

Thực hiện theo hướng dẫn từng bước:

  • Nếu đây là lần đầu bạn sử dụng ESP32, hãy tham khảo hướng dẫn ESP32 - Cài Đặt Phần Mềm.
  • Kết nối board ESP32 với máy tính của bạn bằng cáp USB.
  • Mở Arduino IDE trên máy tính.
  • Chọn board ESP32 và cổng COM phù hợp.
  • Điều hướng đến biểu tượng Libraries ở thanh bên trái của Arduino IDE.
  • Tìm kiếm "DIYables Bluetooth", sau đó tìm thư viện DIYables Bluetooth của DIYables
  • Nhấp nút Install để cài đặt thư viện.
ESP32 diyables Bluetooth thư viện
  • Bạn sẽ được hỏi về việc cài đặt một số thư viện phụ thuộc khác
  • Nhấp nút Install All để cài đặt tất cả thư viện phụ thuộc.
ESP32 diyables Bluetooth dependency

Chọn một trong hai chế độ Bluetooth dưới đây tùy thuộc vào nhu cầu của bạn:

Code ESP32 Classic Bluetooth (chỉ hoạt động với ứng dụng trên Android)

Lưu ý: Classic Bluetooth KHÔNG được hỗ trợ trên iOS. Nếu bạn cần hỗ trợ iOS, hãy sử dụng code BLE dưới đây.

  • Trong Arduino IDE, đi đến File Examples DIYables Bluetooth Esp32Bluetooth_Joystick, hoặc sao chép code trên và dán vào trình soạn thảo của Arduino IDE
/* * DIYables Bluetooth Library - ESP32 Classic Bluetooth Joystick Example * Works with DIYables Bluetooth STEM app on Android * Note: Classic Bluetooth is NOT supported on iOS. Use BLE examples for iOS support. * * This example demonstrates the Bluetooth Joystick feature: * - Interactive joystick control via Bluetooth * - Real-time X/Y coordinate values (-100 to +100) * - Control pins based on joystick position * * Compatible Boards: * - ESP32 (all variants with Classic Bluetooth) * - ESP32-WROOM-32 * - ESP32-DevKitC * - ESP32-WROVER * * Note: Select "Huge APP (3MB No OTA/1MB SPIFFS)" partition scheme * in Arduino IDE: Tools > Partition Scheme * * Setup: * 1. Upload the sketch to your ESP32 * 2. Open Serial Monitor (115200 baud) to see connection status * 3. Use DIYables Bluetooth App to connect and control the joystick * * Tutorial: https://diyables.io/bluetooth-app * Author: DIYables */ #include <DIYables_BluetoothServer.h> #include <DIYables_BluetoothJoystick.h> #include <platforms/DIYables_Esp32Bluetooth.h> // Create Bluetooth instances DIYables_Esp32Bluetooth bluetooth("ESP32_Joystick"); DIYables_BluetoothServer bluetoothServer(bluetooth); // Create Joystick app instance // Configure with autoReturn=false and sensitivity=5 (minimum 5% change to trigger updates) DIYables_BluetoothJoystick bluetoothJoystick(false, 5); // Variables to store current joystick values int currentJoystickX = 0; int currentJoystickY = 0; void setup() { Serial.begin(115200); delay(1000); Serial.println("DIYables Bluetooth - ESP32 Joystick Example"); // TODO: initialize your hardware pins here // Initialize Bluetooth server with platform-specific implementation bluetoothServer.begin(); // Add joystick app to server bluetoothServer.addApp(&bluetoothJoystick); // Set up connection event callbacks bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); }); // Set up joystick callback for position changes bluetoothJoystick.onJoystickValue([](int x, int y) { // Store the received values currentJoystickX = x; currentJoystickY = y; // Print joystick position values (-100 to +100) Serial.print("Joystick - X: "); Serial.print(x); Serial.print(", Y: "); Serial.println(y); // TODO: Add your control logic here based on joystick position // Examples: // - Control motors: if (x > 50) { /* move right */ } // - Control servos: servo.write(map(y, -100, 100, 0, 180)); // - Control LEDs: ledcWrite(channel, map(abs(x), 0, 100, 0, 255)); // - Send commands to other devices via Serial, I2C, SPI, etc. }); // Optional: Handle requests for current joystick values (when app loads) bluetoothJoystick.onGetConfig([]() { // Send the stored joystick values back to the app bluetoothJoystick.send(currentJoystickX, currentJoystickY); Serial.print("App requested values - Sent: X="); Serial.print(currentJoystickX); Serial.print(", Y="); Serial.println(currentJoystickY); }); // You can change configuration at runtime: // bluetoothJoystick.setAutoReturn(false); // Disable auto-return // bluetoothJoystick.setSensitivity(10.0); // Only send updates when joystick moves >10% (less sensitive) Serial.println("Waiting for Bluetooth connection..."); } void loop() { // Handle Bluetooth server communications bluetoothServer.loop(); // TODO: Add your main application code here delay(10); }
  • Nhấp nút Upload trên Arduino IDE để upload code lên ESP32
  • Mở Serial Monitor
  • Kiểm tra kết quả trên Serial Monitor. Nó trông như thế này:
COM6
Send
DIYables Bluetooth - ESP32 Joystick Example Waiting for Bluetooth connection...
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Code ESP32 BLE (hoạt động với ứng dụng trên cả Android và iOS)

  • Trong Arduino IDE, đi đến File Examples DIYables Bluetooth Esp32BLE_Joystick, hoặc sao chép code trên và dán vào trình soạn thảo của Arduino IDE
/* * DIYables Bluetooth Library - ESP32 BLE Joystick Example * Works with DIYables Bluetooth STEM app on Android and iOS * * This example demonstrates the Bluetooth Joystick feature: * - Interactive joystick control via Bluetooth * - Real-time X/Y coordinate values (-100 to +100) * - Control pins based on joystick position * * Compatible Boards: * - ESP32-WROOM-32 * - ESP32-DevKitC * - ESP32-WROVER * - ESP32-S3 * - ESP32-C3 * - Any ESP32 board supporting BLE * * Note: Select "Huge APP (3MB No OTA/1MB SPIFFS)" partition scheme * in Arduino IDE: Tools > Partition Scheme * * Setup: * 1. Upload the sketch to your ESP32 * 2. Open Serial Monitor (115200 baud) to see connection status * 3. Use DIYables Bluetooth App to connect and control the joystick * * Tutorial: https://diyables.io/bluetooth-app * Author: DIYables */ #include <DIYables_BluetoothServer.h> #include <DIYables_BluetoothJoystick.h> #include <platforms/DIYables_Esp32BLE.h> // BLE Configuration const char* DEVICE_NAME = "ESP32BLE_Joystick"; const char* SERVICE_UUID = "19B10000-E8F2-537E-4F6C-D104768A1214"; const char* TX_UUID = "19B10001-E8F2-537E-4F6C-D104768A1214"; const char* RX_UUID = "19B10002-E8F2-537E-4F6C-D104768A1214"; // Create Bluetooth instances DIYables_Esp32BLE bluetooth(DEVICE_NAME, SERVICE_UUID, TX_UUID, RX_UUID); DIYables_BluetoothServer bluetoothServer(bluetooth); // Create Joystick app instance DIYables_BluetoothJoystick bluetoothJoystick(false, 5); // Variables to store current joystick values int currentJoystickX = 0; int currentJoystickY = 0; void setup() { Serial.begin(115200); delay(1000); Serial.println("DIYables Bluetooth - ESP32 BLE Joystick Example"); // Initialize Bluetooth server with platform-specific implementation bluetoothServer.begin(); // Add joystick app to server bluetoothServer.addApp(&bluetoothJoystick); // Set up connection event callbacks bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); }); // Set up joystick callback for position changes bluetoothJoystick.onJoystickValue([](int x, int y) { currentJoystickX = x; currentJoystickY = y; Serial.print("Joystick - X: "); Serial.print(x); Serial.print(", Y: "); Serial.println(y); // TODO: Add your control logic here based on joystick position }); bluetoothJoystick.onGetConfig([]() { bluetoothJoystick.send(currentJoystickX, currentJoystickY); Serial.print("App requested values - Sent: X="); Serial.print(currentJoystickX); Serial.print(", Y="); Serial.println(currentJoystickY); }); Serial.println("Waiting for Bluetooth connection..."); } void loop() { bluetoothServer.loop(); delay(10); }
  • Nhấp nút Upload trên Arduino IDE để upload code lên ESP32
  • Mở Serial Monitor
  • Kiểm tra kết quả trên Serial Monitor. Nó trông như thế này:
COM6
Send
DIYables Bluetooth - ESP32 BLE Joystick Example Waiting for Bluetooth connection...
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Ứng Dụng Di Động

  • Cài đặt ứng dụng DIYables Bluetooth trên smartphone của bạn: Android | iOS
  • Nếu bạn đang sử dụng code ESP32 Classic Bluetooth, bạn cần ghép nối ESP32 với điện thoại Android trước khi mở ứng dụng:
    • Đi đến Cài Đặt > Bluetooth trên điện thoại
    • Đảm bảo Bluetooth đã được bật
    • Điện thoại của bạn sẽ quét các thiết bị có sẵn
    • Tìm và nhấn "ESP32_Joystick" trong danh sách thiết bị có sẵn
    • Xác nhận yêu cầu ghép nối (không cần PIN)
    • Đợi cho đến khi nó hiển thị "Paired" dưới tên thiết bị
  • Nếu bạn đang sử dụng code ESP32 BLE, không cần ghép nối. Chỉ cần tiến hành bước tiếp theo.
  • Mở ứng dụng DIYables Bluetooth
  • Khi mở ứng dụng lần đầu tiên, nó sẽ yêu cầu quyền. Vui lòng cấp các quyền sau:
    • Quyền Nearby Devices (Android 12+) / Bluetooth (iOS) - cần thiết để quét và kết nối với thiết bị Bluetooth
    • Quyền Location (chỉ Android 11 trở xuống) - được yêu cầu bởi các phiên bản Android cũ để quét thiết bị BLE
  • Đảm bảo Bluetooth đã được bật trên điện thoại của bạn
  • Trên màn hình chính, nhấn nút Connect. Ứng dụng sẽ quét cả thiết bị BLE và Classic Bluetooth.
diyables Bluetooth app - màn hình chính với nút quét
  • Tìm và nhấn thiết bị của bạn trong kết quả quét để kết nối:
    • Cho Classic Bluetooth: nhấn "ESP32_Joystick"
    • Cho BLE: nhấn "ESP32BLE_Joystick"
  • Sau khi kết nối, ứng dụng tự động quay về màn hình chính. Chọn ứng dụng Joystick từ menu ứng dụng.
diyables Bluetooth app - màn hình chính với Ứng dụng joystick

Lưu ý: Bạn có thể nhấn biểu tượng cài đặt trên màn hình chính để ẩn/hiện các ứng dụng trên màn hình chính. Để biết thêm chi tiết, xem Hướng Dẫn Sử Dụng DIYables Bluetooth App.

  • Di chuyển joystick theo bất kỳ hướng nào để gửi giá trị tọa độ X/Y
diyables Bluetooth app - màn hình joystick

Bây giờ hãy nhìn lại Serial Monitor trên Arduino IDE. Bạn sẽ thấy:

COM6
Send
Bluetooth connected! Joystick - X: 50, Y: 0 Joystick - X: 75, Y: -30 Joystick - X: 0, Y: 100 Joystick - X: -60, Y: 45 Joystick - X: 0, Y: 0
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Di chuyển joystick trong ứng dụng và xem các giá trị X/Y theo thời gian thực trong Serial Monitor

Tùy Chỉnh Sáng Tạo - Điều Chỉnh Code Cho Dự Án Của Bạn

Cấu Hình Auto-Return và Sensitivity

Thiết lập hành vi joystick với các tham số constructor:

// Tạo instance ứng dụng Joystick // Tham số: autoReturn (bool), sensitivity (float - % thay đổi tối thiểu để kích hoạt cập nhật) DIYables_BluetoothJoystick bluetoothJoystick(false, 5); // Hoặc thay đổi trong thời gian chạy: bluetoothJoystick.setAutoReturn(true); // Bật auto-return về tâm bluetoothJoystick.setSensitivity(10.0); // Chỉ gửi cập nhật khi joystick di chuyển >10% // Đọc cấu hình hiện tại: bool autoReturn = bluetoothJoystick.getAutoReturn(); float sensitivity = bluetoothJoystick.getSensitivity();

Xử Lý Thay Đổi Vị Trí Joystick

Sử dụng callback onJoystickValue() để nhận tọa độ X/Y:

bluetoothJoystick.onJoystickValue([](int x, int y) { // x từ -100 (trái) đến +100 (phải) // y từ -100 (xuống) đến +100 (lên) Serial.print("X: "); Serial.print(x); Serial.print(", Y: "); Serial.println(y); // TODO: Thêm logic điều khiển của bạn ở đây });

Xử Lý Yêu Cầu Cấu Hình Từ Ứng Dụng

Khi ứng dụng kết nối và mở màn hình Joystick, nó yêu cầu cấu hình joystick từ ESP32. Bạn có thể sử dụng callback onGetConfig() để gửi giá trị joystick hiện tại cho ứng dụng tại thời điểm đó:

bluetoothJoystick.onGetConfig([]() { // Được gọi khi ứng dụng yêu cầu cấu hình joystick // Gửi giá trị joystick hiện tại để ứng dụng hiển thị đúng bluetoothJoystick.send(currentJoystickX, currentJoystickY); Serial.println("Ứng dụng yêu cầu cấu hình - đã gửi giá trị hiện tại"); });

Gửi Giá Trị Đến Ứng Dụng

Bạn có thể gửi giá trị tọa độ joystick từ ESP32 đến ứng dụng:

// Gửi giá trị tọa độ X/Y đến ứng dụng bluetoothJoystick.send(currentJoystickX, currentJoystickY); // Gửi tin nhắn văn bản bluetoothJoystick.send("Joystick đã được hiệu chỉnh");

Xử Lý Sự Kiện Kết Nối

Bạn có thể phát hiện khi ứng dụng kết nối hoặc ngắt kết nối với ESP32:

// Được gọi khi ứng dụng kết nối với ESP32 bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth đã kết nối!"); bluetoothJoystick.send(currentJoystickX, currentJoystickY); }); // Được gọi khi ứng dụng ngắt kết nối với ESP32 bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth đã ngắt kết nối!"); // Dừng động cơ khi mất kết nối stopAllMotors(); }); // Kiểm tra trạng thái kết nối ở bất cứ đâu trong code if (bluetoothServer.isConnected()) { // Làm gì đó chỉ khi đã kết nối }

Cách Sử Dụng Joystick

Điều Khiển Giao Diện Ứng Dụng

Giao diện joystick trong ứng dụng DIYables Bluetooth cung cấp:

  • Bảng Joystick Ảo: Chạm và kéo để điều khiển vị trí
  • Hiển Thị Giá Trị X: Hiển thị vị trí ngang hiện tại (-100 đến +100)
  • Hiển Thị Giá Trị Y: Hiển thị vị trí dọc hiện tại (-100 đến +100)

Phạm Vi Giá Trị

Joystick cung cấp:

  • Trục X: -100 (hoàn toàn trái) đến 0 (giữa) đến +100 (hoàn toàn phải)
  • Trục Y: -100 (hoàn toàn xuống) đến 0 (giữa) đến +100 (hoàn toàn lên)
  • Vị Trí Trung Tâm: (0, 0) khi joystick ở trạng thái nghỉ

Ví Dụ Lập Trình

Handler Joystick Cơ Bản

void setup() { bluetoothJoystick.onJoystickValue([](int x, int y) { currentJoystickX = x; currentJoystickY = y; Serial.print("Joystick - X: "); Serial.print(x); Serial.print(", Y: "); Serial.println(y); }); }

Điều Khiển Robot Hai Bánh

const int MOTOR_LEFT_PWM = 16; const int MOTOR_LEFT_DIR1 = 18; const int MOTOR_LEFT_DIR2 = 19; const int MOTOR_RIGHT_PWM = 17; const int MOTOR_RIGHT_DIR1 = 21; const int MOTOR_RIGHT_DIR2 = 22; void setup() { // Cấu hình chân động cơ pinMode(MOTOR_LEFT_PWM, OUTPUT); pinMode(MOTOR_LEFT_DIR1, OUTPUT); pinMode(MOTOR_LEFT_DIR2, OUTPUT); pinMode(MOTOR_RIGHT_PWM, OUTPUT); pinMode(MOTOR_RIGHT_DIR1, OUTPUT); pinMode(MOTOR_RIGHT_DIR2, OUTPUT); bluetoothJoystick.onJoystickValue([](int x, int y) { // Differential drive: kết hợp X (rẽ) và Y (tốc độ) int leftSpeed = constrain(y + x, -100, 100); int rightSpeed = constrain(y - x, -100, 100); // Đặt hướng và tốc độ động cơ trái if (leftSpeed >= 0) { digitalWrite(MOTOR_LEFT_DIR1, HIGH); digitalWrite(MOTOR_LEFT_DIR2, LOW); } else { digitalWrite(MOTOR_LEFT_DIR1, LOW); digitalWrite(MOTOR_LEFT_DIR2, HIGH); } analogWrite(MOTOR_LEFT_PWM, map(abs(leftSpeed), 0, 100, 0, 255)); // Đặt hướng và tốc độ động cơ phải if (rightSpeed >= 0) { digitalWrite(MOTOR_RIGHT_DIR1, HIGH); digitalWrite(MOTOR_RIGHT_DIR2, LOW); } else { digitalWrite(MOTOR_RIGHT_DIR1, LOW); digitalWrite(MOTOR_RIGHT_DIR2, HIGH); } analogWrite(MOTOR_RIGHT_PWM, map(abs(rightSpeed), 0, 100, 0, 255)); Serial.print("Trái: "); Serial.print(leftSpeed); Serial.print("%, Phải: "); Serial.print(rightSpeed); Serial.println("%"); }); }

Điều Khiển Servo Pan-Tilt

#include <ESP32Servo.h> Servo panServo; // Ngang (trục X) Servo tiltServo; // Dọc (trục Y) const int PAN_PIN = 13; const int TILT_PIN = 14; void setup() { panServo.attach(PAN_PIN); tiltServo.attach(TILT_PIN); panServo.write(90); // Vị trí giữa tiltServo.write(90); bluetoothJoystick.onJoystickValue([](int x, int y) { // Ánh xạ giá trị joystick (-100 đến +100) sang góc servo (0 đến 180) int panAngle = map(x, -100, 100, 0, 180); int tiltAngle = map(y, -100, 100, 0, 180); panServo.write(panAngle); tiltServo.write(tiltAngle); Serial.print("Pan: "); Serial.print(panAngle); Serial.print("°, Tilt: "); Serial.print(tiltAngle); Serial.println("°"); }); }

Chỉ Thị Hướng LED Matrix

// 4 LED chỉ hướng const int LED_UP = 16; const int LED_DOWN = 17; const int LED_LEFT = 18; const int LED_RIGHT = 19; const int THRESHOLD = 30; // Giá trị joystick tối thiểu để kích hoạt LED void setup() { pinMode(LED_UP, OUTPUT); pinMode(LED_DOWN, OUTPUT); pinMode(LED_LEFT, OUTPUT); pinMode(LED_RIGHT, OUTPUT); bluetoothJoystick.onJoystickValue([](int x, int y) { // Bật LED dựa trên hướng joystick digitalWrite(LED_UP, y > THRESHOLD ? HIGH : LOW); digitalWrite(LED_DOWN, y < -THRESHOLD ? HIGH : LOW); digitalWrite(LED_RIGHT, x > THRESHOLD ? HIGH : LOW); digitalWrite(LED_LEFT, x < -THRESHOLD ? HIGH : LOW); // Hiển thị hướng trong Serial String direction = ""; if (y > THRESHOLD) direction += "LÊN "; if (y < -THRESHOLD) direction += "XUỐNG "; if (x > THRESHOLD) direction += "PHẢI "; if (x < -THRESHOLD) direction += "TRÁI "; if (direction == "") direction = "GIỮA"; Serial.println("Hướng: " + direction); }); }

Kỹ Thuật Lập Trình Nâng Cao

Bộ Lọc Dead Zone

const int DEAD_ZONE = 15; // Bỏ qua giá trị joystick trong phạm vi ±15 bluetoothJoystick.onJoystickValue([](int x, int y) { // Áp dụng bộ lọc dead zone int filteredX = (abs(x) > DEAD_ZONE) ? x : 0; int filteredY = (abs(y) > DEAD_ZONE) ? y : 0; // Sử dụng giá trị đã lọc để điều khiển controlMotors(filteredX, filteredY); });

Tăng Tốc Độ Dần

int targetX = 0, targetY = 0; int currentX = 0, currentY = 0; const int RAMP_RATE = 5; // Thay đổi tối đa mỗi lần cập nhật void setup() { bluetoothJoystick.onJoystickValue([](int x, int y) { targetX = x; targetY = y; }); } void loop() { bluetoothServer.loop(); // Tăng dần đến giá trị mục tiêu if (currentX < targetX) currentX = min(currentX + RAMP_RATE, targetX); else if (currentX > targetX) currentX = max(currentX - RAMP_RATE, targetX); if (currentY < targetY) currentY = min(currentY + RAMP_RATE, targetY); else if (currentY > targetY) currentY = max(currentY - RAMP_RATE, targetY); controlMotors(currentX, currentY); delay(20); }

Tính Toán Độ Lớn và Góc

bluetoothJoystick.onJoystickValue([](int x, int y) { // Tính độ lớn (khoảng cách từ tâm, 0-100) float magnitude = sqrt(x * x + y * y); magnitude = constrain(magnitude, 0, 100); // Tính góc theo độ (0° = phải, 90° = lên) float angle = atan2(y, x) * 180.0 / PI; Serial.print("Độ lớn: "); Serial.print(magnitude, 1); Serial.print(", Góc: "); Serial.print(angle, 1); Serial.println("°"); // Sử dụng độ lớn cho tốc độ và góc cho hướng int speed = map((int)magnitude, 0, 100, 0, 255); // Áp dụng vào phần cứng... });

Ví Dụ Tích Hợp Phần Cứng

Robot Bánh Mecanum

// Robot bánh Mecanum cần 4 động cơ const int MOTOR_FL = 16; // Front-Left (Trước-Trái) const int MOTOR_FR = 17; // Front-Right (Trước-Phải) const int MOTOR_BL = 18; // Back-Left (Sau-Trái) const int MOTOR_BR = 19; // Back-Right (Sau-Phải) void setupMecanumRobot() { bluetoothJoystick.onJoystickValue([](int x, int y) { // Động học bánh Mecanum int fl = constrain(y + x, -100, 100); int fr = constrain(y - x, -100, 100); int bl = constrain(y - x, -100, 100); int br = constrain(y + x, -100, 100); setMotor(MOTOR_FL, fl); setMotor(MOTOR_FR, fr); setMotor(MOTOR_BL, bl); setMotor(MOTOR_BR, br); }); } void setMotor(int pin, int speed) { // Ánh xạ -100..100 sang PWM với hướng analogWrite(pin, map(abs(speed), 0, 100, 0, 255)); }

Điều Khiển Vị Trí Stepper Motor

#include <AccelStepper.h> AccelStepper stepperX(AccelStepper::DRIVER, 16, 17); AccelStepper stepperY(AccelStepper::DRIVER, 18, 19); void setup() { stepperX.setMaxSpeed(1000); stepperX.setAcceleration(500); stepperY.setMaxSpeed(1000); stepperY.setAcceleration(500); bluetoothJoystick.onJoystickValue([](int x, int y) { // Ánh xạ joystick sang tốc độ stepper (-1000 đến +1000 bước/giây) int speedX = map(x, -100, 100, -1000, 1000); int speedY = map(y, -100, 100, -1000, 1000); stepperX.setSpeed(speedX); stepperY.setSpeed(speedY); }); } void loop() { bluetoothServer.loop(); stepperX.runSpeed(); stepperY.runSpeed(); }

BLE vs Classic Bluetooth - Chọn Cái Nào?