简介
本实验通过ESP-NOW无线通信协议实现多个ESP32/ESP 8266开发板向ESP32开发板发送数据。例如可以应用于从多个远程传感器上收集数据。
读取ESP32/ESP8266接收方Receiver的MAC地址
读取ESP32开发板的代码
#ifdef ESP32
#include <WiFi.h>
#include <esp_wifi.h>
#else
#include <ESP8266WiFi.h>
#endif
void setup(){
Serial.begin(115200);
Serial.print("ESP Board MAC Address: ");
#ifdef ESP32
WiFi.mode(WIFI_STA);
WiFi.STA.begin();
uint8_t baseMac[6];
esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);
if (ret == ESP_OK) {
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
baseMac[0], baseMac[1], baseMac[2],
baseMac[3], baseMac[4], baseMac[5]);
} else {
Serial.println("Failed to read MAC address");
}
#else
Serial.println(WiFi.macAddress());
#endif
}
void loop(){
}
通过串口打印读取到接收方ESP32开发板1的MAC地址为:54:43:b2:7f:00:60
ESP32/ESP8266发送方Sender程序
把读取到的接收方的MAC地址填入到uint8_t broadcastAddress[]数组中,并修改结构体的中myData.id的值,ESP32开发板1程序中填入myData.id = 1,ESP32开发板2程序中填入myData.id = 2,ESP32开发板3程序中填入myData.id = 3,接收方以此来分辨是哪一个ESP32开发板发过来的数据。
#include <esp_now.h>
#include <WiFi.h>
// REPLACE WITH THE RECEIVER'S MAC Address
uint8_t broadcastAddress[] = {0x54, 0x43, 0xb2, 0x7f, 0x00, 0x60};
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
int id; // must be unique for each sender board
int x;
int y;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// Create peer interface
esp_now_peer_info_t peerInfo;
// 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
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
myData.id = 1;
myData.x = random(0,50);
myData.y = random(0,50);
// 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(10000);
}
ESP32/ESP8266接收方Receiver程序
#include <esp_now.h>
#include <WiFi.h>
// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
int id;
int x;
int y;
}struct_message;
// Create a struct_message called myData
struct_message myData;
// Create a structure to hold the readings from each board
struct_message board1;
struct_message board2;
struct_message board3;
// Create an array with all the structures
struct_message boardsStruct[3] = {board1, board2, board3};
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
char macStr[18];
Serial.print("Packet received from: ");
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.println(macStr);
memcpy(&myData, incomingData, sizeof(myData));
Serial.printf("Board ID %u: %u bytes\n", myData.id, len);
// Update the structures with the new incoming data
boardsStruct[myData.id-1].x = myData.x;
boardsStruct[myData.id-1].y = myData.y;
Serial.printf("x value: %d \n", boardsStruct[myData.id-1].x);
Serial.printf("y value: %d \n", boardsStruct[myData.id-1].y);
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(esp_now_recv_cb_t(OnDataRecv));
}
void loop() {
// Acess the variables for each board
/*int board1X = boardsStruct[0].x;
int board1Y = boardsStruct[0].y;
int board2X = boardsStruct[1].x;
int board2Y = boardsStruct[1].y;
int board3X = boardsStruct[2].x;
int board3Y = boardsStruct[2].y;*/
delay(10000);
}
ESP-NOW通信验证
分别给左边的3个ESP32开发板下载好发送方Sender程序,给右边的ESP32开发板下载好接收方Receiver程序
若接收方接收到数据串口会打印出接收到对应的ESP32开发板的ID号和ESP32开发板的两个随机数
若发送方数据发送成功串口会打印出数据发送完成,数据接收成功
若发送方数据发送成功串口会打印出数据发送完成,数据接收失败
总结
通过以上例程验证了ESP32开发板之间单向多对一的ESP-NOW无线通信。