• ESP32 ESP-NOW Kết Nối nhiều ESP32 Với Nhau.

QC

ESP32 ESP-NOW Kết Nối nhiều ESP32 Với Nhau.

ESP32 ESP-NOW  Kết Nối nhiều ESP32 Với Nhau.

PHẦN 1: GIỚI THIỆU.

     Tìm hiểu cách sử dụng ESP-NOW để trao đổi dữ liệu giữa các ESP32 được lập trình với Arduino IDE. ESP-NOW là một giao thức truyền thông không kết nối được phát triển bởi Espressif có tính năng truyền gói tin ngắn. Giao thức này cho phép nhiều thiết bị giao tiếp với nhau một cách dễ dàng.


Các hướng giao tiếp như sau: 

1. Giao tiếp hai chiều ESP-NOW giữa các bo mạch ESP32

2. ESP-NOW với ESP32: Gửi dữ liệu Từ 1 ESP32 đến nhiều ESP32 (một-nhiều)

3.ESP-NOW với ESP32: Nhận dữ liệu từ nhiều BOARD ESP32(nhiều-một)

ESP-NOW hỗ trợ các tính năng sau:

-Giao tiếp unicast được mã hóa và không được mã hóa;

-Các thiết bị ngang hàng được mã hóa và không được mã hóa hỗn hợp;

-Có thể mang tải trọng lên đến 250 byte;

-Gửi chức năng gọi lại có thể được đặt để thông báo cho lớp ứng dụng về truyền thành công hay thất bại.

Công nghệ ESP-NOW cũng có những hạn chế sau:

-Đồng đẳng được mã hóa hạn chế. 10 đồng nghiệp được mã hóa nhiều nhất được hỗ trợ ở chế độ Trạm; Tối đa là 6 ở chế độ SoftAP hoặc SoftAP + Station;

-Nhiều ứng dụng ngang hàng không được mã hóa được hỗ trợ, tuy nhiên, tổng số của chúng phải nhỏ hơn 20, bao gồm cả các đối tượng được mã hóa;

-Tải trọng được giới hạn ở 250 byte.

Phần 1: ESP-NOW One-Way Communication

(ESP - NOW giao tiếp 1 Chiều ).


Nhược điểm của phương thức này là :  Bên nhận có nhận được giữ liệu hay không, bên truyền không biết được.

PHẦN 2 : Một ESP32 “chính - MASTER ” gửi dữ liệu đến nhiều “CON-SLAVES” ESP32.


PHẦN 3 :  Nhiều ESP32 “Phụ- slaver” gửi dữ liệu đến Một “Chính-Master” ESP32.


PHẦN 4 : ESP-NOW GIAO TIẾP 2 CHIỀU.



PHẦN 5 : ESP-NOW GIAO THEO MẠNG LƯỚI.





PHẦN 5 : LẤY ĐỊA CHỈ MAC CỦA ESP32.

- Mỗi esp32 Có mỗi địa chỉ MAC khác nhau và phân biệt. Ta xem như là tên gọi để phân biệt chúng.

BƯỚC 1: CODE LẤY ĐỊA CHỈ MAC.
#include "WiFi.h"
 
void setup(){
  Serial.begin(115200);
  WiFi.mode(WIFI_MODE_STA);
  Serial.println(WiFi.macAddress());
}
 
void loop(){

}
TA NHẬN ĐƯỢC ĐỊA CHỈ MAC NHƯ SAU:





PHẦN 6 : CHƯƠNG TRÌNH GIAO TIẾP 2 ESP32 POINT TO POINT NHƯ SAU.



ESP32 Sender Sketch (ESP-NOW)

(CODE BÊN TRUYỀN )


#include <esp_now.h>
#include <WiFi.h>

// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
  char a[32];
  int b;
  float c;
  String d;
  bool e;
} struct_message;

// Create a struct_message called myData
struct_message myData;

// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("\r\nLast Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
 
void setup() {
  // Init Serial Monitor
  Serial.begin(115200);
 
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  esp_now_peer_info_t peerInfo;
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;
  
  // Add peer        
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
}
 
void loop() {
  // Set values to send
  strcpy(myData.a, "THIS IS A CHAR");
  myData.b = random(1,20);
  myData.c = 1.2;
  myData.d = "Hello";
  myData.e = false;

  // Send message via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
   
  if (result == ESP_OK) {
    Serial.println("Sent with success");
  }
  else {
    Serial.println("Error sending the data");
  }
  delay(2000);
}

ĐỊA CHỈ MAC ESP32 NHẬN:
uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};

Sau đó, tạo một cấu trúc chứa loại dữ liệu mà chúng ta muốn gửi. Chúng tôi gọi cấu trúc này là struct_message và nó chứa 5 kiểu biến khác nhau. Bạn có thể thay đổi điều này để gửi bất kỳ loại biến nào bạn muốn.
typedef struct struct_message { char a[32]; int b; float c; String d; bool e; } struct_message;

Sau đó, tạo một biến mới kiểu struct_message được gọi là myData sẽ lưu trữ các giá trị của biến.
struct_message myData;

   Tiếp theo, xác định hàm OnDataSent (). Đây là một hàm gọi lại sẽ được thực thi khi một tin nhắn được gửi đi. Trong trường hợp này, chức năng này chỉ in ra nếu tin nhắn đã được gửi thành công hay chưa.

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { Serial.print("\r\nLast Packet Send Status:\t"); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); }

Initialize ESP-NOW: ( KHỞI TẠO ESP- NOW THẤT BẠI).

if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; }

   Sau khi khởi tạo thành công ESP-NOW, hãy đăng ký chức năng gọi lại sẽ được gọi khi có tin nhắn được gửi đi. Trong trường hợp này, chúng ta đăng ký hàm OnDataSent () đã được tạo trước đó.

esp_now_register_send_cb(OnDataSent);

  Sau đó, chúng ta cần ghép nối với một thiết bị ESP-NOW khác để gửi dữ liệu. Đó là những gì chúng Ta làm trong những dòng tiếp theo:

//Register peer esp_now_peer_info_t peerInfo; memcpy(peerInfo.peer_addr, broadcastAddress, 6); peerInfo.channel = 0; peerInfo.encrypt = false; //Add peer if (esp_now_add_peer(&peerInfo) != ESP_OK){ Serial.println("Failed to add peer"); return; }

  Trong vòng lặp (), chúng tôi sẽ gửi tin nhắn qua ESP-NOW 2 giây một lần (bạn có thể thay đổi thời gian trễ này).Đầu tiên, chúng tôi đặt các giá trị biến như sau:

strcpy(myData.a, "THIS IS A CHAR"); myData.b = random(1,20); myData.c = 1.2; myData.d = "Hello"; myData.e = false;

  Hãy nhớ rằng myData là một cấu trúc. Ở đây chúng tôi gán các giá trị mà chúng tôi muốn gửi bên trong cấu trúc. Ví dụ: dòng đầu tiên gán một ký tự, dòng thứ hai gán một số Int ngẫu nhiên, một Float, một Chuỗi và một biến Boolean.
  Chúng tôi tạo loại cấu trúc này để chỉ cho bạn cách gửi các loại biến phổ biến nhất. Bạn có thể thay đổi cấu trúc để gửi bất kỳ loại dữ liệu nào khác.
Cuối cùng, gửi tin nhắn như sau:

esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

Kiểm tra xem tin nhắn đã được gửi thành công chưa:

if (result == ESP_OK) { Serial.println("Sent with success"); } else { Serial.println("Error sending the data"); }

Vòng lặp () được thực thi sau mỗi 2000 mili giây (2 giây).

delay(2000);

ESP32 Receiver Sketch (ESP-NOW)

(CODE BÊN NHẬN)

#include <esp_now.h>
#include <WiFi.h>

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
    char a[32];
    int b;
    float c;
    String d;
    bool e;
} struct_message;

// Create a struct_message called myData
struct_message myData;

// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("Char: ");
  Serial.println(myData.a);
  Serial.print("Int: ");
  Serial.println(myData.b);
  Serial.print("Float: ");
  Serial.println(myData.c);
  Serial.print("String: ");
  Serial.println(myData.d);
  Serial.print("Bool: ");
  Serial.println(myData.e);
  Serial.println();
}
 
void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);
  
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  
  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {

}

  Tạo cấu trúc để nhận dữ liệu. Cấu trúc này phải được xác định giống nhau trong bản phác thảo của người gửi.


typedef struct struct_message { char a[32]; int b; float c; String d; bool e; } struct_message;


Tạo một biến struct_message được gọi là myData.

struct_message myData;

   Tạo một hàm gọi lại sẽ được gọi khi ESP32 nhận dữ liệu qua ESP-NOW. Hàm được gọi là onDataRecv () và phải chấp nhận một số tham số như sau:

void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {


Chúng ta sao chép nội dung của biến dữ liệu incomingData vào biến myData.


memcpy(&myData, incomingData, sizeof(myData));

    Bây giờ, cấu trúc myData chứa một số biến bên trong với các giá trị được gửi bởi người gửi ESP32. Ví dụ, để truy cập biến a, chúng ta chỉ cần gọi myData.a.

   Trong ví dụ này, chúng tôi chỉ cần in dữ liệu đã nhận, nhưng trong một ứng dụng thực tế, bạn có thể in dữ liệu trên màn hình chẳng hạn.

Serial.print("Bytes received: "); Serial.println(len); Serial.print("Char: "); Serial.println(myData.a); Serial.print("Int: "); Serial.println(myData.b); Serial.print("Float: "); Serial.println(myData.c); Serial.print("String: "); Serial.println(myData.d); Serial.print("Bool: "); Serial.println(myData.e); Serial.println(); }


Khởi tạo Thất bại
if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; }

  Đăng ký một hàm gọi lại sẽ được gọi khi dữ liệu được nhận. Trong trường hợp này, chúng tôi đăng ký hàm OnDataRecv () đã được tạo trước đó.

esp_now_register_recv_cb(OnDataRecv);



Nap Code vào PY32F003 dùng Stlink

 Nap Code vào PY32F003 dùng Stlink Bước 1: Cài đặt  KeilC v5.39 theo link sau ( chú ý 5.39 keil c mới nạp ok). https://edge07.111.ir.cdn.ir/...