Bài 5: esp-now – giao tiếp 2 esp32

Thương hiệu: (Đang cập nhật ...) Loại: (Đang cập nhật ...)

Liên hệ
Bài 5: ESP-NOW – Giao tiếp 2 ESP32 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 p...

Bài 5: ESP-NOW – Giao tiếp 2 ESP32

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.


1. ESP-NOW là gì?

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.


2. Vì sao Drone Mini sử dụng ESP-NOW?

Đố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.

Những ưu điểm đáng chú ý

Đặ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.


3. Kiến trúc giao tiếp của Drone

Toàn bộ hệ thống có thể chia thành hai phần.

Tay cầm


Joystick
   │
   ├── X
   ├── Y
   │
Nút nhấn
   │
   ↓
ESP32 Controller
   │
   ↓
Đóng gói dữ liệu
   │
   ↓
ESP-NOW

Drone


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.


4. ESP-NOW truyền dữ liệu như thế nào?

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:

  • Throttle
  • Roll
  • Pitch
  • Yaw
  • Trạng thái nút
  • Số thứ tự packet

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.


5. MAC Address của ESP32

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.


6. Channel – yếu tố rất quan trọng

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


7. Khởi tạo ESP-NOW

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.


8. Tạo dữ liệu điều khiển

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.


9. Tại sao cần Counter?

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.


10. Tần suất gửi dữ liệu

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.


11. Drone nhận dữ liệu

Ở 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.


12. Failsafe – phần cực kỳ quan trọng

Đâ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:

  • Tay cầm tắt nguồn
  • Drone tắt nguồn
  • Khoảng cách quá xa
  • Nhiễu sóng
  • Firmware bị treo
  • Packet bị mất liên tục

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.


13. Không nên điều khiển motor ngay ở lần test đầu tiên

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à:

Bước 1

Kiểm tra ESP32 Controller:


Joystick
   ↓
Serial Monitor

Bước 2

Kiểm tra ESP-NOW:


Controller
   ↓
ESP-NOW
   ↓
Drone
   ↓
Serial Monitor

Bước 3

Kiểm tra packet:


Throttle
Roll
Pitch
Yaw

Bước 4

Kiểm tra failsafe.

Bước 5

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.


14. Bài test ESP-NOW đầu tiê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.


15. Kiểm tra bằng Serial Monitor

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ế.


16. Sơ đồ hoàn chỉnh của Bài 5


                 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.


17. Những lỗi thường gặp

ESP32 không nhận dữ liệu

Kiểm tra:

  • MAC Address
  • Wi-Fi mode
  • Channel
  • ESP-NOW initialization
  • Peer configuration
  • Packet size
  • Phiên bản Arduino-ESP32

Dữ liệu nhận sai

Kiểm tra:


Struct TX
      =
Struct RX

Hai phía phải thống nhất cấu trúc dữ liệu.

Dữ liệu lúc được lúc mất

Kiểm tra:

  • Channel
  • Khoảng cách
  • Nguồn cấp
  • Nhiễu
  • Tần suất gửi
  • Anten và vị trí lắp đặt

Drone vẫn giữ motor khi mất tay cầm

Kiểm tra ngay phần:


Failsafe

Không nên bỏ qua cơ chế timeout.


18. Thực hành cuối bài

Sau Bài 5, hãy hoàn thành 5 nhiệm vụ:

Bài tập 1

Đọc MAC Address của hai ESP32.

Bài tập 2

Thiết lập ESP-NOW giữa Controller và Drone.

Bài tập 3

Tạo packet:


Throttle
Roll
Pitch
Yaw
Button
Counter

Bài tập 4

Gửi packet khoảng 50 lần/giây và kiểm tra trên Serial Monitor.

Bài tập 5

Tắt tay cầm và kiểm tra Drone có kích hoạt Failsafe hay không.


19. Kết quả cần đạt

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ế.

popup

Số lượng:

Tổng tiền: