通过 ESP-NOW 实现 ESP32 到 ESP32 的双工通信 是一种高效且低延迟的无线通信方式,适用于需要快速数据交换的场景。以下是实现双工通信的简要步骤和关键点:
1. 核心概念
ESP-NOW 是乐鑫开发的协议,基于 Wi-Fi 物理层,但无需建立传统连接,直接通过 MAC 地址通信。
双工通信:两个 ESP32 设备既能发送也能接收数据,实现双向实时交互。
2. 实现步骤
硬件准备
两个 ESP32 开发板(如 ESP32-WROOM-32)。
确保两者处于同一 Wi-Fi 信道(默认 2.4GHz)。
软件配置
初始化 Wi-Fi 和 ESP-NOW
设置 Wi-Fi 为 STA 模式(不连接路由器,仅启用射频)。
初始化 ESP-NOW 协议栈。
注册对端设备(Peer)
双方需预先知道对方的 MAC 地址(可通过 WiFi.macAddress() 获取)。
使用 esp_now_add_peer() 注册对端设备,启用加密(可选)。
设置回调函数
发送回调:确认数据是否成功发送。
接收回调:处理接收到的数据。
双向通信逻辑
发送端:通过 esp_now_send() 发送数据到对端 MAC。
接收端:在回调函数中解析数据并响应。




收发器1 代码
//--------------------------------------------
//ESP32 Tranceiver 1 via ESP-NOW Protocol
//Transmit Pot Value - Receive Temp & Humidity
//--------------------------------------------
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//------------------------------------------------------------
Adafruit_SSD1306 display(128, 64, &Wire, -1);
//------------------------------------------------------------
uint8_t RxMACaddress[] = {0x7C, 0x9E, 0xBD, 0xF5, 0xBE, 0x30};
//------------------------------------------------------------
typedef struct TxStruct
{
int potVal;
}TxStruct;
TxStruct sentData;
//------------------------------------------------------------
typedef struct RxStruct
{
float temp; int humidity;
}RxStruct;
RxStruct receivedData;
//------------------------------------------------------------
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 OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len)
{
memcpy(&receivedData, incomingData, sizeof(receivedData));
}
//======================================================================================
void setup()
{
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
display.clearDisplay();
//----------------------------------------------------------
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
//----------------------------------------------------------
esp_now_register_send_cb(OnDataSent);
//----------------------------------------------------------
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, RxMACaddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
//----------------------------------------------------------
if(esp_now_add_peer(&peerInfo) != ESP_OK)
{
Serial.println("Failed to add peer");
return;
}
//----------------------------------------------------------
esp_now_register_recv_cb(OnDataRecv);
}
//======================================================================================
void loop()
{
sentData.potVal = analogRead(A0);
//----------------------------------------------------------
esp_err_t result = esp_now_send(RxMACaddress, (uint8_t *) &sentData, sizeof(sentData));
//----------------------------------------------------------
if (result == ESP_OK) Serial.println("Sent with success");
else Serial.println("Error sending the data");
//----------------------------------------------------------
display.setTextColor(WHITE); display.clearDisplay();
display.setTextSize(2); display.setCursor(0,0); display.print("--DHT 11--");
display.setCursor(0,25); display.print("T: ");
display.print(receivedData.temp); display.print("C");
display.setCursor(0,50); display.print("H: ");
display.print(receivedData.humidity); display.print("%");
display.display();
}
收发器 2 代码
//--------------------------------------------
//ESP32 Tranceiver 2 via ESP-NOW Protocol
//Transmit Temp & Humidity - Receive Pot Value
//--------------------------------------------
#include <esp_now.h>
#include <WiFi.h>
#include<Wire.h>
#include<Adafruit_SSD1306.h>
#include <DHT.h>
//------------------------------------------------------------
Adafruit_SSD1306 display(128, 64, &Wire, -1);
DHT dht(32, DHT11);
//------------------------------------------------------------
uint8_t RxMACaddress[] = {0x7C, 0x9E, 0xBD, 0xF1, 0x85, 0xCC};
//------------------------------------------------------------
typedef struct TxStruct
{
float temp; int humidity;
}TxStruct;
TxStruct sentData;
//------------------------------------------------------------
typedef struct RxStruct
{
int potVal;
}RxStruct;
RxStruct receivedData;
//------------------------------------------------------------
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len)
{
memcpy(&receivedData, incomingData, sizeof(receivedData));
}
//------------------------------------------------------------
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()
{
Serial.begin(115200);
dht.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
display.clearDisplay();
//----------------------------------------------------------
WiFi.mode(WIFI_STA);
//----------------------------------------------------------
if(esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
//----------------------------------------------------------
esp_now_register_send_cb(OnDataSent);
//----------------------------------------------------------
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, RxMACaddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
//----------------------------------------------------------
if(esp_now_add_peer(&peerInfo) != ESP_OK)
{
Serial.println("Failed to add peer");
return;
}
//----------------------------------------------------------
esp_now_register_recv_cb(OnDataRecv);
}
//======================================================================================
void loop()
{
sentData.temp = dht.readTemperature(false);
sentData.humidity = dht.readHumidity();
//----------------------------------------------------------
display.setTextColor(WHITE); display.clearDisplay();
display.setTextSize(2); display.setCursor(10,0); display.print("POT Value");
display.setCursor(5,18); display.print(" 0-->4095 ");
display.setTextSize(3); display.setCursor(25,42); display.print(receivedData.potVal);
display.display();
//----------------------------------------------------------
esp_err_t result = esp_now_send(RxMACaddress, (uint8_t *) &sentData, sizeof(sentData));
//----------------------------------------------------------
if (result == ESP_OK) Serial.println("Sent with success");
else Serial.println("Error sending the data");
//----------------------------------------------------------
delay(1000);
}
【Arduino 动手做】通过 ESP-NOW 实现 ESP32 到 ESP32 双工通信
项目链接:https://akuzechie.blogspot.com/2021/05/esp32-to-esp32-duplex-communication-via.html
项目作者:阿纳斯·库泽奇
项目视频 :https://www.youtube.com/watch?v=PxGWEg4i6q4
项目代码:https://akuzechie.blogspot.com/2021/05/esp32-to-esp32-duplex-communication-via.html


评论