编辑
2024-01-06
笔记
0
请注意,本文编写于 480 天前,最后修改于 480 天前,其中某些信息可能已经过时。

目录

什么是 ESP-NOW?
获取设备 MAC 地址
ESP-NOW 数据发送
ESP-NOW 数据接收
实验结果

什么是 ESP-NOW?

ESP-NOW 是由乐鑫开发的另一款无线通信协议,可以使多个设备在没有或不使用 Wi-Fi 的情况下进行通信。这种协议类似常见于无线鼠标中的低功耗 2.4GHz 无线连接——设备在进行通信之前要进行配对。配对之后,设备之间的连接是持续的、点对点的,并且不需要握手协议。它是一种短数据传输、无连接的快速通信技术,可以让低功耗控制器直接控制所有智能设备而无需连接路由器,适用于智能灯、遥控控制、传感器数据回传等场景。

1.png

获取设备 MAC 地址

ESP-NOW 是点对点的通讯方式,在发送数据时需要指定接收设备,这好比你给对方发送 QQ 消息必须知道对方的 QQ 号一样。在这里我们一般通过设备的 MAC 地址作为区分不同接收设备的凭证。那什么是 MAC 地址呢?MAC 地址也叫物理地址、硬件地址,每个设备的 MAC 地址在出厂时都是不同的。

下面我们通过 Arduino 代码来获取 ESP32 开发板的 MAC 地址:

c++
#include <WiFi.h> void setup() { Serial.begin(9600); Serial.println(); #ifdef ESP8266 Serial.print("ESP8266 Board MAC Address: "); Serial.println(WiFi.macAddress()); #elif defined ESP32 WiFi.mode(WIFI_MODE_STA); Serial.print("ESP32 Board MAC Address: "); Serial.println(WiFi.macAddress()); #endif } void loop() { }

打开串口监视器,就可获得接收端开发板的 MAC 地址:

2.png

ESP-NOW 数据发送

获取到 MAC 地址后,我们先来看看如何编写发送数据的程序。

C++
#include <WiFi.h> #include <esp_now.h> // 设置掌控板声音传感器与光线传感器引脚编号 const int soundPin = 36; const int lightPin = 39; // 设置数据结构体 typedef struct struct_message { String board_name; double light; double sound; } struct_message; struct_message myData; // 接收设备的 MAC 地址 uint8_t broadcastAddress[] = { 0xE0, 0x5A, 0x1B, 0x60, 0x29, 0xC0 }; // 数据发送回调函数 void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { char macStr[18]; Serial.print("Packet to: "); 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); Serial.print("Send status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); Serial.println(); } void setup() { Serial.begin(9600); // 初始化 ESP-NOW 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, broadcastAddress, 6); peerInfo.channel = 0; peerInfo.encrypt = false; peerInfo.ifidx = WIFI_IF_STA; //其他例程没这行,造成配对不成功 // 检查设备是否配对成功 if (esp_now_add_peer(&peerInfo) != ESP_OK) { Serial.println("Failed to add peer"); return; } } void loop() { // 设置要发送的数据 myData.board_name = "mPython_#1"; myData.light = analogRead(lightPin); myData.sound = analogRead(soundPin); // 发送数据 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(1000); }

ESP-NOW 数据接收

接下来我们看看接收端的程序如何编写。

C++
#include <WiFi.h> #include <esp_now.h> // 设置数据结构体 typedef struct struct_message { String board_name; double light; double sound; } struct_message; struct_message myData; // 数据接收回调函数 void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len) { memcpy(&myData, incomingData, sizeof(myData)); Serial.print("board_name: "); Serial.println(myData.board_name); Serial.print("light: "); Serial.println(myData.light); Serial.print("sound:"); Serial.println(myData.sound); Serial.println(); } void setup() { Serial.begin(9600); // 初始化 ESP-NOW WiFi.mode(WIFI_STA); if (esp_now_init() != 0) { Serial.println("Error initializing ESP-NOW"); return; } // 设置接收数据回调函数 esp_now_register_recv_cb(OnDataRecv); } void loop() { }

实验结果

在两块 ESP32 开发板中分别上传发送和接收的程序,然后打开串口监视器来查看一下效果。 3.png

本文作者:可乐

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!