ESP-NOW入门(带有Arduino IDE的ESP32)

ESP-NOW入门(带有Arduino IDE的ESP32)

  • 功能介绍


功能介绍

了解如何使用ESP-NOW在使用Arduino IDE编程的ESP32板之间交换数据。 ESP-NOW是由乐鑫开发的无连接通信协议,具有短数据包传输的功能。 该协议使多个设备可以轻松地相互通信。
ESP-NOW入门(带有Arduino IDE的ESP32)_第1张图片


ESP-NOW是Espressif开发的一种协议,在Espressif网站上表示,它使多个设备无需使用Wi-Fi即可相互通信。 该协议类似于低功耗2.4GHz无线连接(…)。 设备之间需要进行配对,然后才能进行通信。 配对完成后,连接安全且点对点,无需握手。”

这意味着在将设备彼此配对后,连接将保持不变。换句话说,如果您的一块板突然断电或复位,则在重新启动时,它将自动连接到其对等端以继续通信。

ESP-NOW支持以下功能:

加密和未加密的单播通信;
混合加密和未加密对等设备;
最多可以承载250字节有效负载;
发送回调函数,可以将其设置为通知应用程序层
传输成功或失败。
ESP-NOW技术还具有以下限制:

有限的加密对等体。工作站模式下最多支持10个加密对等体;在SoftAP或SoftAP + Station模式下最多6个;
支持多个未加密的对等体,但是它们的总数应少于20,其中包括已加密的对等体。
有效负载限制为250个字节。
简而言之,ESP-NOW是一种快速通信协议,可用于在ESP32板之间交换小消息(最大250字节)。

ESP-NOW具有多种用途,您可以在不同的设置中进行单向或双向通信。
ESP-NOW单向通信
例如,在单向通信中,您可能会遇到以下情形:

一个ESP32板向另一个ESP32板发送数据
这种配置非常容易实现,并且很容易将数据从一块板发送到另一块板,例如传感器读数或控制GPIO的ON和OFF命令。
ESP-NOW入门(带有Arduino IDE的ESP32)_第2张图片
一个“主” ESP32将数据发送到多个ESP32“从站”
一块ESP32板向不同的ESP32板发送相同或不同的命令。 此配置是构建遥控器之类的理想选择。 整个房屋中可以有几个由一个主ESP32板控制的ESP32板。
ESP-NOW入门(带有Arduino IDE的ESP32)_第3张图片

一个ESP32“从站”从多个“主站”接收数据
一个ESP32“从站”从多个“主站”接收数据如果要将多个传感器节点的数据收集到一个ESP32板中,则此配置非常理想。 例如,可以将其配置为Web服务器以显示来自所有其他板的数据。

注意:在ESP-NOW文档中,没有“发件人/主人”和“接收者/从属”之类的东西。 每个板都可以是发送者或接收者。 但是,为使内容清楚,我们将使用“发送者”和“接收者”或“主”和“从”这两个术语。
ESP-NOW双向通讯
使用ESP-NOW,每个板都可以同时是发送者和接收者。 因此,您可以在板之间建立双向通信。

例如,您可以使两个板彼此通信。
您可以在此配置中添加更多板卡,并使它们看起来像一个网络(所有ESP32板卡都可以相互通信)。
ESP-NOW入门(带有Arduino IDE的ESP32)_第4张图片

总而言之,ESP-NOW是构建网络的理想选择,在该网络中,您可以有多个ESP32板相互交换数据。

ESP32:获取板的MAC地址
要通过ESP-NOW进行通信,您需要知道ESP32接收器的MAC地址。 这样您才能知道将信息发送到哪个设备。

每个ESP32都有一个唯一的MAC地址,这就是我们识别每块板以使用ESP-NOW向其发送数据的方式(了解如何获取和更改ESP32 MAC地址)。

要获取主板的MAC地址,请上传以下代码。

#include "WiFi.h"
 
void setup(){
  Serial.begin(115200);
  WiFi.mode(WIFI_MODE_STA);
  Serial.println(WiFi.macAddress());
}
 
void loop(){

}

请保存您的板卡MAC地址,因为您需要它通过ESP-NOW将数据发送到正确的板卡。
ESP-NOW单向点对点通信
为了让您开始使用ESP-NOW无线通信,我们将构建一个简单的项目,展示如何将消息从一个ESP32发送到另一个。 一个ESP32将成为“发送方”,另一个ESP32将成为“接收方”。

ESP-NOW入门(带有Arduino IDE的ESP32)_第5张图片

我们将发送一个结构,其中包含char,int,float,String和boolean类型的变量。然后,您可以修改结构以发送适合您项目的任何变量类型(例如传感器读数或布尔变量以打开或关闭某些内容)。

为了更好地理解,我们将ESP32#1称为“发送者”,将ESP32#2称为“接收者”。

这是我们应包含在发件人草图中的内容:

初始化ESP-NOW;
发送数据时注册回调函数–发送消息时将执行OnDataSent函数。这可以告诉我们消息是否成功发送;
添加一个对等设备(接收方)。为此,您需要知道接收者的MAC地址;
向对等设备发送消息。
在接收方,草图应包括:

初始化ESP-NOW;
注册接收回调函数(OnDataRecv)。收到消息后将执行的功能。
在该回调函数内部,将消息保存到变量中以执行具有该信息的任何任务。
ESP-NOW与回调函数一起使用,这些回调函数在设备收到消息或发送消息时调用(您可以确定消息是否已成功发送或失败)。

ESP-NOW有用的功能
以下是最基本的ESP-NOW功能的摘要:

函数名称和说明

esp_now_init()初始化ESP-NOW。 您必须先初始化Wi-Fi,然后再初始化ESP-NOW。
esp_now_add_peer()调用此函数以配对设备并将对等MAC地址作为参数传递。
esp_now_send()使用ESP-NOW发送数据。
esp_now_register_send_cb()注册在发送数据时触发的回调函数。 发送消息后,将调用一个函数–该函数返回传递是否成功。
esp_now_register_rcv_cb()注册在接收数据时触发的回调函数。 通过ESP-NOW接收到数据后,将调用一个函数。

有关这些功能的更多信息,请参阅“阅读文档”中的ESP-NOW文档。
ESP32发件人草图(ESP-NOW)
这是ESP32发送板的代码。 将代码复制到您的Arduino IDE,但尚未上传。 您需要进行一些修改以使其适合您。

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include 
#include 

// 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);
}

代码如何工作
首先,包括esp_now.h和WiFi.h库。

#include
#include

在下一行中,应插入ESP32接收器MAC地址。

uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};

在我们的例子中,接收者的MAC地址是:30:AE:A4:07:0D:64,但是您需要用您自己的MAC地址替换该变量。

然后,创建一个包含我们要发送的数据类型的结构。 我们将此结构称为struct_message,它包含5种不同的变量类型。 您可以更改此设置以发送所需的任何变量类型。

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

然后,创建一个名为myData的struct_message类型的新变量,该变量将存储变量值。
接下来,定义OnDataSent()函数。 这是一个回调函数,将在发送消息时执行。 在这种情况下,此功能仅打印是否成功发送了邮件。

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");
}

ESP32 Receiver Sketch (ESP-NOW)

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include 
#include 

// 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() {

}

你可能感兴趣的:(ESP32,Arduino相关实例,物联网,嵌入式硬件,c++)