企业介绍微网站怎么做,俄语网站叫什么yandex,seo网站优化网站编辑招聘,搜素引擎排名优化计费方式目录 介绍ESP-NOW 协议概述在 ESP32 上配置 ESP-NOW使用 ESP-NOW 进行一对多通信在 ESP32 上存储发件人的 MAC 地址代码结论 介绍
ESP32 是一款功能强大的 Wi-Fi 和蓝牙双模模块#xff0c;可用于使用 ESP-NOW 协议实现低功耗、高效率的一对多通信。本文将介绍如何使用ESP-NO… 目录 介绍ESP-NOW 协议概述在 ESP32 上配置 ESP-NOW使用 ESP-NOW 进行一对多通信在 ESP32 上存储发件人的 MAC 地址代码结论 介绍
ESP32 是一款功能强大的 Wi-Fi 和蓝牙双模模块可用于使用 ESP-NOW 协议实现低功耗、高效率的一对多通信。本文将介绍如何使用ESP-NOW协议进行一对多通信并在接收端存储发送方的MAC地址。
本文主要实现在使用ESP-NOW协议进行一对多通信以及接收端存储发送方的MAC地址当esp32上电后检测有无存储MAC地址有则将MAC添加到对等点peer当接收到now信息时将发送端的MAC存储到flash中方便下次直接发送信息。
看本次代码直接划到最后即可ESP-NOW 协议概述
ESP-NOW 协议是乐鑫开发的一种快速高效的无线通信协议专门用于 ESP8266 和 ESP32 模块之间的点对点或点对多点通信。它支持单播和组播两种传输模式能够在网状网络中支持多达 20 个节点。与 Wi-Fi 和蓝牙等其他无线通信协议相比ESP-NOW 特点如下
低延迟ESP-NOW协议不需要进行TCP/IP协议栈处理因此具有很低的延迟适合实时性要求较高的应用场景。高吞吐量ESP-NOW协议使用帧广播方式发送数据传输效率高可以同时向多个节点发送相同的信息。低功耗ESP-NOW协议在数据传输过程中使用的功耗非常低适合电池供电场景。简单易用ESP-NOW协议配置简单只需定义通道、加密密钥和数据结构等基本参数即可实现无线通信。支持多播ESP-NOW协议支持一对多或一对所有节点的通信方式提高了网络的灵活性。可扩展性ESP-NOW协议支持多种数据类型的传输可以通过自定义数据结构来实现更复杂的通信功能。
在 ESP32 上配置 ESP-NOW
本次开发IDEarduino2.0.4 要在 ESP32 上配置 ESP-NOW通过以下几步
安装ESP32开发环境在Arduino IDE中依次选择“文件”-“首选项”在“附加开发板管理器网址”中添加以下链接并单击“确定”按钮 https://dl.espressif.com/dl/package_esp32_index.json然后打开“工具”-“开发板”-“开发板管理器”搜索“esp32”安装ESP32开发板支持。引入ESP-NOW库在Arduino IDE中添加esp-now协议头文件。编写代码只是简单使用now不是本次重点
#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;bool d;
} struct_message;// Create a struct_message called myData
struct_message myData;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 MonitorSerial.begin(115200);// Set device as a Wi-Fi StationWiFi.mode(WIFI_STA);// Init ESP-NOWif (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 packetesp_now_register_send_cb(OnDataSent);// Register peermemcpy(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 sendstrcpy(myData.a, THIS IS A CHAR);myData.b random(1,20);myData.c 1.2;myData.d false;// Send message via ESP-NOWesp_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);
}
不知道如何获取MAC地址
#include WiFi.hvoid setup(){Serial.begin(115200);WiFi.mode(WIFI_MODE_STA);Serial.println(WiFi.macAddress());
}void loop(){}上传代码将代码上传到ESP32板子上。打开串口监视器可以看到ESP32发送的数据。
使用 ESP-NOW 进行一对多通信
要使用 ESP-NOW 协议实现一对多通信首先需要配置发送端和接收端。在发送端只需要读取有无存储到flash的MAC信息如果有就添加到peer中如果没有就等待接收到now信息然后添加到flash以及peer中。通过now信息发送将已添加到now里的对等点(peer)发送now信息。
esp_err_t result esp_now_send(0, (uint8_t *)test, sizeof(test_struct));uint8_t* dest_mac: 目标设备的MAC地址。如果传递NULL则消息将广播到所有已配对的设备。uint8_t* data: 指向要发送的数据缓冲区的指针。size_t len: 要发送的数据字节数。 此外esp_now_send()函数返回一个esp_err_t类型的错误代码以指示发送操作是否成功。如果返回值为ESP_OK则表明发送操作成功否则将返回对应的错误代码。 一般情况下使用arduino IDE开启esp-now模式一次只能同时发送3到4个消息然后就会报错ESP_ERR_ESPNOW_INTERNAL提示发送失败 这是因为arduino上配置WiFi的原因你需要做的就是强制 Arduino 使用默认的 sdkconfig WiFi 设置。
WiFi.useStaticBuffers(true);在 ESP32 上存储发件人的 MAC 地址
在一对多通信场景中跟踪发件人的 MAC 地址通常很有用。可以通过在接收方创建一个列表来存储所有发送方的 MAC 地址。每当收到新消息时都可以从消息中提取发件人的 MAC 地址并将其添加到列表中。这样就可以跟踪所有发件人及其相应的 MAC 地址。 在这里将MAC地址存储进入flash中使用库是ArduinoNvs.h该库可以使存储信息到flash中简单化 库地址如下 https://github.com/rpolitex/ArduinoNvs 打开不了 来资源里下载点击这里https://download.csdn.net/download/hongyun1221/87712695
代码
附上代码
#include WiFi.h
#include esp_now.h
#include ArduinoNvs.h#define MAX_MAC_ADDRESSES 10 //最大20个esp_now_peer_info_t peerInfo;typedef struct test_struct {int x;int y;
} test_struct;
test_struct test;void printMacAddress(const uint8_t *macBytes) {for (int i 0; i 6; i) {Serial.print(macBytes[i], HEX);if (i 5) {Serial.print(:);}}Serial.println();
}// Helper function to convert a MAC address array to a string
String macToString(const uint8_t *mac) {String address ;for (int i 0; i 6; i) {address String(mac[i], HEX);if (i 5) {address :;}}return address;
}bool addPeer(const String macAddress) {uint8_t macBytes[6];peerInfo.channel 0;peerInfo.encrypt false;if (sscanf(macAddress.c_str(), %02X:%02X:%02X:%02X:%02X:%02X, macBytes[0], macBytes[1], macBytes[2], macBytes[3], macBytes[4], macBytes[5]) ! 6) {Serial.println(Failed to parse MAC address);return false;}memcpy(peerInfo.peer_addr, macBytes, 6);if (esp_now_add_peer(peerInfo) ! ESP_OK) {Serial.println(Failed to add peer);return false;}return true;
}// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {char macStr[18];Serial.print(Packet to: );// Copies the sender mac address to a stringsnprintf(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.print(macStr);Serial.print( 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) {Serial.print(received MAC: );Serial.print(macToString(mac));Serial.print(Bytes received: );Serial.println(len);// Check if MAC already exists in NVSString macAddress macToString(mac);int count NVS.getInt(count, 0);bool macExists false;for (int i 0; i count; i) {String storedMac NVS.getString(mac String(i));if (storedMac.equals(macAddress)) {macExists true;Serial.println(macExists);break;}}if (!macExists) {if (count MAX_MAC_ADDRESSES) {for (int i 0; i count; i) {String nextMac NVS.getString(mac String(i 1));NVS.setString(mac String(i), nextMac);}// Store the MAC address in NVS and add it to ESP-NOW peer node listNVS.setString(mac String(count-1), macToString(mac));NVS.setInt(count, count);Serial.println(打印已存储的mac);for (int i 0; i count; i) {String macAddress NVS.getString(mac String(i));Serial.print(i);Serial.print(. );Serial.println(macAddress);}ESP.restart();} else {// Store the MAC address in NVS and add it to ESP-NOW peer node listNVS.setString(mac String(count), macToString(mac));NVS.setInt(count, count 1);memcpy(peerInfo.peer_addr, mac, 6);peerInfo.channel 1;peerInfo.encrypt false;if (esp_now_add_peer(peerInfo) ! ESP_OK) {Serial.println(Failed to add peer);ESP.restart();}}}
}void setup() {Serial.begin(115200);// Initialize WiFi and ESP-NOWWiFi.useStaticBuffers(true); //非常重要强制 Arduino 使用默认的 sdkconfigWiFi.mode(WIFI_STA);// 初始化 ESP-NOWif (esp_now_init() ESP_OK) {Serial.println(ESPNow Init Success);} else {Serial.println(ESPNow Init Failed);ESP.restart();}// Initialize NVSNVS.begin(my-app);// Print the stored MAC addressesint count NVS.getInt(count, 0);Serial.printf(Stored %d MAC addresses:\n, count);for (int i 0; i count; i) {String macAddress NVS.getString(mac String(i));Serial.print(i);Serial.print(. );Serial.println(macAddress);if (addPeer(macAddress)) {// 成功添加对等节点 -- 处理} else {// 添加对等节点失败 -- 处理}}esp_now_register_send_cb(OnDataSent);esp_now_register_recv_cb(OnDataRecv);//信息初始化test.x 5123;test.y 12345;
}void loop() {delay(5000);int count NVS.getInt(count, 0);//向已存在的同等体发送信息if (0 count) {Serial.println(No peer);} else {esp_err_t result esp_now_send(0, (uint8_t *)test, sizeof(test_struct));if (result ESP_OK) {Serial.println(Sent with success);} else {Serial.println(Error sending the data);}Serial.print(Peer count: );Serial.println(count);}
}输出展示 以下是函数的讲解 printMacAddress(const uint8_t *macBytes)打印 MAC 地址数组。 macToString(const uint8_t *mac)将 MAC 地址数组转换为字符串类型。 addPeer(const String macAddress)将设备添加到 ESP NOW 对等节点列表中。 OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)发送数据回调函数。如果数据发送成功将打印“Delivery Success”否则将打印“Delivery Fail”。 OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len)接收数据回调函数。将检查是否已经存在该设备的 MAC 地址并根据需要将其添加到 ESP NOW 对等节点列表中。 setup()初始化 Wi-Fi、ESP NOW 和 NVS。该函数还会打印存储的 MAC 地址并注册了发送和接收数据的回调函数。 loop()每隔五秒钟向已配对的设备发送测试结构体 test 中的数据。该函数还会显示当前已存储的对等节点数量。
#define MAX_MAC_ADDRESSES 10 // 最大允许存储的 MAC 地址数量esp_now_peer_info_t peerInfo; // 定义 ESP-NOW 的对等节点信息结构体
部分函数讲解 定义两个辅助函数一个将MAC地址数组打印为十六进制字符串另一个将MAC地址数组转换为字符串类型。
void printMacAddress(const uint8_t *macBytes) {for (int i 0; i 6; i) {Serial.print(macBytes[i], HEX);if (i 5) {Serial.print(:);}}Serial.println();
}// Helper function to convert a MAC address array to a string
String macToString(const uint8_t *mac) {String address ;for (int i 0; i 6; i) {address String(mac[i], HEX);if (i 5) {address :;}}return address;
}定义将MAC地址添加到ESP-NOW对等体结构体变量中的函数。
bool addPeer(const String macAddress) {uint8_t macBytes[6];peerInfo.channel 0;peerInfo.encrypt false;if (sscanf(macAddress.c_str(), %02X:%02X:%02X:%02X:%02X:%02X, macBytes[0], macBytes[1], macBytes[2], macBytes[3], macBytes[4], macBytes[5]) ! 6) {Serial.println(Failed to parse MAC address);return false;}memcpy(peerInfo.peer_addr, macBytes, 6);if (esp_now_add_peer(peerInfo) ! ESP_OK) {Serial.println(Failed to add peer);return false;}return true;
}结论
总之ESP-NOW 协议是一种强大的无线通信协议可用于使用 ESP32 模组实现一对多通信。通过将发射器和接收器配置为使用 ESP-NOW 协议您可以实现与多个节点的低延迟、高吞吐量和低功耗通信。此外通过存储发送方的 MAC 地址您可以跟踪网络中的所有节点。通过限制存储的 MAC 地址数量可以防止内存溢出问题并确保 ESP32 模组的高效运行。