【Arduino 动手做】通过 ESP-NOW 实现 ESP32 到 ESP32 双工通信
2025-06-231921
AI 快速预览详细
本文介绍了如何通过 ESP-NOW 实现 ESP32 到 ESP32 的双工通信。核心概念是基于 Wi-Fi 物理层,但无需建立传统连接,直接通过 MAC 地址通信。实现步骤包括初始化 Wi-Fi 和 ESP-NOW、注册对端设备、设置回调函数以及双向通信逻辑。通过这种方式,可以实现高效且低延迟的数据交换,适用于需要快速数据交换的场景。
|
通过 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。 接收端:在回调函数中解析数据并响应。 ![]() ![]() ![]() ![]() |








项目链接: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
[code]//--------------------------------------------
//ESP32 Tranceiver 2 via ESP-NOW Protocol
//Transmit Temp & Humidity - Receive Pot Value
//--------------------------------------------
#include
#include
#include
#include
#include
//------------------------------------------------------------
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);
}
[/code]
[code]//--------------------------------------------
//ESP32 Tranceiver 1 via ESP-NOW Protocol
//Transmit Pot Value - Receive Temp & Humidity
//--------------------------------------------
#include
#include
#include
#include
#include
//------------------------------------------------------------
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();
}[/code]