-
-
-
Tổng tiền thanh toán:
-
Thương hiệu: (Đang cập nhật ...) Loại: (Đang cập nhật ...)
Trong hệ thống Drone Mini ESP32, tay cầm và drone cần trao đổi dữ liệu điều khiển liên tục: joystick, nút nhấn, throttle, trạng thái hệ thống… Vì vậy, chúng ta cần một phương thức truyền dữ liệu nhanh, độ trễ thấp và không phụ thuộc router Wi-Fi.
Một giải pháp phù hợp với ESP32 là ESP-NOW.
ESP-NOW là giao thức giao tiếp không dây do Espressif phát triển, cho phép các thiết bị ESP32 trao đổi dữ liệu trực tiếp mà không cần kết nối qua Access Point/Router.
Mô hình cơ bản:
TAY CẦM ESP32
┌──────────────┐
│ Joystick │
│ Nút nhấn │
│ ↓ │
│ ESP32 │
└──────┬───────┘
│
ESP-NOW
│
↓
┌──────────────┐
│ ESP32 │
│ Drone │
│ ↓ │
│ Motor Driver │
│ 4 Motors │
└──────────────┘
Điểm quan trọng là ESP-NOW không phải Wi-Fi Internet. Hai ESP32 có thể giao tiếp trực tiếp với nhau thông qua phần radio Wi-Fi tích hợp.
Đối với drone điều khiển bằng tay cầm, dữ liệu cần được truyền liên tục và nhanh.
Ví dụ:
Joystick trái
↓
ESP32 tay cầm
↓
ESP-NOW
↓
ESP32 Drone
↓
Xử lý điều khiển
↓
Motor
So với việc truyền dữ liệu thông qua server hoặc router, ESP-NOW giúp kiến trúc hệ thống đơn giản hơn.
| Đặc điểm | ESP-NOW |
|---|---|
| Router Wi-Fi | Không bắt buộc |
| Kết nối trực tiếp | Có |
| Độ trễ | Thấp |
| Truyền dữ liệu nhỏ | Phù hợp |
| Điều khiển thiết bị | Phù hợp |
| IoT | Phù hợp |
| Robot | Phù hợp |
| Drone | Phù hợp |
Với khóa học này, ESP-NOW đóng vai trò là cầu nối giữa tay cầm ESP32 và Drone ESP32.
Toàn bộ hệ thống có thể chia thành hai phần.
Joystick
│
├── X
├── Y
│
Nút nhấn
│
↓
ESP32 Controller
│
↓
Đóng gói dữ liệu
│
↓
ESP-NOW
ESP-NOW
↓
ESP32 Drone
│
├── Throttle
├── Roll
├── Pitch
└── Yaw
│
↓
Motor Mixing
↓
Motor Driver
↓
4 Motor
Đây chính là kiến trúc quan trọng mà chúng ta sẽ xây dựng trong các bài tiếp theo.
Thay vì gửi từng biến riêng lẻ, chúng ta nên đóng gói dữ liệu thành một packet.
Ví dụ:
struct DroneControl {
int16_t throttle;
int16_t roll;
int16_t pitch;
int16_t yaw;
uint8_t button1;
uint8_t button2;
uint32_t counter;
};
Một packet có thể chứa:
Ví dụ:
┌───────────────────────────────┐
│ DroneControl │
├───────────────────────────────┤
│ Throttle │
│ Roll │
│ Pitch │
│ Yaw │
│ Button 1 │
│ Button 2 │
│ Counter │
└───────────────────────────────┘
Cách này giúp chương trình dễ mở rộng khi sau này cần thêm dữ liệu.
Mỗi ESP32 có một địa chỉ MAC riêng.
Ví dụ:
AA:BB:CC:11:22:33
Trong hệ thống Drone, tay cầm cần biết địa chỉ của ESP32 trên drone để gửi dữ liệu đến đúng thiết bị.
Có thể đọc MAC của ESP32 bằng:
#include <WiFi.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
Serial.println(WiFi.macAddress());
}
void loop() {
}
Mở Serial Monitor và có thể nhận được:
AA:BB:CC:11:22:33
Lưu ý: MAC thực tế của board sẽ khác nhau.
ESP-NOW hoạt động trên channel Wi-Fi.
Hai ESP32 giao tiếp với nhau cần sử dụng channel phù hợp.
Ví dụ:
ESP32 Controller
│
Channel 6
│
ESP-NOW
│
Channel 6
│
ESP32 Drone
Nếu hai thiết bị không cùng channel, việc giao tiếp có thể không hoạt động như mong muốn.
Do đó, khi xây dựng hệ thống thực tế cần xác định rõ:
Controller Channel
=
Drone Channel
Với Arduino-ESP32 hiện nay, Espressif cung cấp API ESP-NOW ở mức Arduino khá thuận tiện.
Khung khởi tạo cơ bản:
#include <Arduino.h>
#include <WiFi.h>
#include <ESP32_NOW.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (!ESP_NOW.begin()) {
Serial.println("ESP-NOW init failed");
while (true) {
delay(1000);
}
}
Serial.println("ESP-NOW Ready");
}
void loop() {
}
Tên thư viện/API có thể thay đổi tùy phiên bản Arduino-ESP32 đang sử dụng. Khi triển khai firmware thực tế, nên kiểm tra đúng phiên bản ESP32 core.
Ví dụ tay cầm tạo packet:
struct DroneControl {
int16_t throttle;
int16_t roll;
int16_t pitch;
int16_t yaw;
uint8_t button1;
uint8_t button2;
uint32_t counter;
};
Sau đó cập nhật dữ liệu:
DroneControl control;
control.throttle = 1200;
control.roll = 0;
control.pitch = 50;
control.yaw = -20;
control.button1 = 1;
control.button2 = 0;
control.counter++;
Packet lúc này chứa toàn bộ thông tin điều khiển drone.
Một trường rất hữu ích là:
uint32_t counter;
Ví dụ:
Packet 100
Packet 101
Packet 102
Packet 103
Packet 104
Drone có thể kiểm tra dữ liệu nhận được.
Nếu nhận:
100
101
103
104
thì có khả năng packet 102 đã bị mất.
Điều này đặc biệt hữu ích khi phát triển hệ thống điều khiển thời gian thực.
Tay cầm không nên gửi dữ liệu bằng tốc độ không kiểm soát.
Có thể xây dựng vòng lặp dạng:
Đọc joystick
↓
Đọc nút
↓
Tạo packet
↓
Gửi ESP-NOW
↓
Chờ một khoảng thời gian
↓
Đọc lại joystick
Ví dụ:
const uint32_t SEND_INTERVAL = 20;
uint32_t lastSend = 0;
void loop() {
if (millis() - lastSend >= SEND_INTERVAL) {
lastSend = millis();
// Đọc joystick
// Tạo packet
// Gửi ESP-NOW
}
}
20 ms tương đương khoảng:
1000 / 20 = 50 lần/giây
Tức khoảng 50 packet/giây.
Đây chỉ là giá trị khởi đầu để thử nghiệm. Tần suất thực tế cần được lựa chọn dựa trên firmware, tải xử lý và yêu cầu điều khiển của drone.
Ở phía drone:
ESP-NOW
↓
Receive Callback
↓
Kiểm tra packet
↓
Lưu dữ liệu điều khiển
↓
Control System
Ví dụ dữ liệu nhận được:
Throttle = 1200
Roll = 20
Pitch = -15
Yaw = 5
ESP32 drone sẽ sử dụng những giá trị này cho thuật toán điều khiển ở các bài tiếp theo.
Đây là một trong những phần không nên bỏ qua khi thiết kế drone.
Giả sử:
Tay cầm
↓
ESP-NOW
X
Drone
Mất kết nối có thể xảy ra do:
Nếu drone tiếp tục sử dụng giá trị throttle cuối cùng thì rất nguy hiểm.
Do đó cần có timeout.
Ví dụ:
Nhận packet
↓
Cập nhật lastPacketTime
↓
Không nhận packet
↓
Kiểm tra timeout
↓
Quá thời gian cho phép?
↓
Có → Failsafe
↓
Đưa motor về trạng thái an toàn
Ví dụ logic:
if (millis() - lastPacketTime > 500) {
// Failsafe
throttle = 0;
}
Giá trị 500 ms chỉ là ví dụ. Với hệ thống thực tế cần thiết kế và kiểm thử timeout phù hợp.
Khi kiểm tra ESP-NOW, không nên vừa test truyền dữ liệu vừa gắn cánh quạt.
Quy trình nên là:
Kiểm tra ESP32 Controller:
Joystick
↓
Serial Monitor
Kiểm tra ESP-NOW:
Controller
↓
ESP-NOW
↓
Drone
↓
Serial Monitor
Kiểm tra packet:
Throttle
Roll
Pitch
Yaw
Kiểm tra failsafe.
Sau khi dữ liệu ổn định mới chuyển sang bài toán điều khiển motor.
Khi thử motor nên tháo cánh quạt để tránh tai nạn ngoài ý muốn.
Mục tiêu của bài test:
Controller ESP32
│
│ ESP-NOW
↓
Drone ESP32
│
↓
Serial Monitor
Tay cầm gửi:
Throttle = 1000
Roll = 100
Pitch = -50
Yaw = 20
Drone nhận:
Throttle: 1000
Roll: 100
Pitch: -50
Yaw: 20
Nếu dữ liệu nhận đúng và ổn định, phần giao tiếp cơ bản đã hoạt động.
Nên in dữ liệu theo dạng:
RX Packet
----------------
Throttle : 1000
Roll : 100
Pitch : -50
Yaw : 20
Counter : 125
----------------
Sau đó di chuyển joystick.
Ví dụ:
Joystick trái
↓
Throttle thay đổi
hoặc:
Joystick phải
↓
Roll/Pitch thay đổi
Tùy theo cách bố trí joystick trên tay cầm thực tế.
TAY CẦM
┌─────────────────────┐
│ Joystick │
│ Nút nhấn │
└─────────┬───────────┘
↓
ESP32 TX
↓
Đóng gói Packet
↓
ESP-NOW
↓
ESP32 RX
↓
Kiểm tra Packet
↓
Failsafe
↓
Dữ liệu điều khiển
↓
Motor Control
Ở Bài 5, chúng ta chưa cần hoàn thiện thuật toán bay. Mục tiêu chính là xây dựng đường truyền dữ liệu ổn định giữa hai ESP32.
Kiểm tra:
Kiểm tra:
Struct TX
=
Struct RX
Hai phía phải thống nhất cấu trúc dữ liệu.
Kiểm tra:
Kiểm tra ngay phần:
Failsafe
Không nên bỏ qua cơ chế timeout.
Sau Bài 5, hãy hoàn thành 5 nhiệm vụ:
Đọc MAC Address của hai ESP32.
Thiết lập ESP-NOW giữa Controller và Drone.
Tạo packet:
Throttle
Roll
Pitch
Yaw
Button
Counter
Gửi packet khoảng 50 lần/giây và kiểm tra trên Serial Monitor.
Tắt tay cầm và kiểm tra Drone có kích hoạt Failsafe hay không.
Sau khi hoàn thành bài học, học viên cần hiểu được:
ESP-NOW là gì?
Tại sao Drone Mini ESP32 sử dụng ESP-NOW?
MAC Address có vai trò gì?
Channel ảnh hưởng như thế nào đến kết nối?
Packet dữ liệu được xây dựng ra sao?
Làm thế nào để truyền Joystick từ tay cầm sang Drone?
Tại sao phải có Counter và Failsafe?
Quan trọng nhất, học viên phải hoàn thành được đường truyền:
JOYSTICK
↓
ESP32 TAY CẦM
↓
ESP-NOW
↓
ESP32 DRONE
↓
DỮ LIỆU ĐIỀU KHIỂN
Đây chính là nền tảng để bước sang phần điều khiển drone thực tế.