文章目录
- ESP-NOW库
- ESP-NOW库使用
- 获取MAC地址
- 数据发送
- 接收数据
ESP-NOW库
ESP-NOW 是由乐鑫开发的另一款协议,可以使多个设备在没有或不使用 Wi-Fi 的情况下进行通信。这种协议类似常见于无线鼠标中的低功耗
2.4GHz 无线连接——设备在进行通信之前要进行配对。配对之后,设备之间的连接是持续的、点对点的,并且不需要握手协议。
通过ESP-NOW可以实现一对一,一对多,多对一的单向通信及一对一的双向通信。
ESP-NOW库使用
获取MAC地址
利用ESP-NOW库进行通信首先需要知道接收端ESP32的MAC地址,利用串口通信扫描出MAC地址并记录下来。
#include "WiFi.h"
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_MODE_STA);
Serial.println(WiFi.macAddress()); //串口输出扫描到的MAC地址
}
void loop(){
}
数据发送
在获得接收端的MAC地址后,修改代码中broadcastAddress的MAC地址,以及结构体中所传输的数据类型。然后在主函数中esp_now_send函数之前添加myData各个结构体数据的值。
主要函数解释:
/*设置WIFI模式为STA模式,即无线终端*/
WiFi.mode(WIFI_STA);
/*发送数据函数*/
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
/*broadcastAddress为MAC地址,myData为发送的数据,sizeof(myData)为占用空间大小,
返回数据状态,ESP_OK表示发送成功,否则失败*/
完整发送代码
#include <esp_now.h>
#include <WiFi.h>
// 接收端的MAC地址(需要修改为你的eps32接收端mac地址)
uint8_t broadcastAddress[] = {0xC0, 0x49, 0xEF, 0xE6, 0x06, 0x6C};
// 发送结构体类型(可以根据你所需要的数据类型修改)
typedef struct struct_message {
int anglex;
char angley;
float anglez;
} struct_message;
// 创建一个结构体变量
struct_message myData;
// 回调函数,函数将在发送消息时执行。此函数告诉我们信息是否成功发送;
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);
// 设置WIFI模式为STA模式,即无线终端
WiFi.mode(WIFI_STA);
// 初始化ESP-NOW
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;//是否加密为False
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
/************************主函数****************************/
void loop() {
//需发送数据类型的值
myData.anglex=90;
myData.angley="y";
myData.anglez=0.01;
//发送信息到指定ESP32上
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(10);
}
接收数据
将接收到的信息存储在myData的结构体变量中,每次接收到数据就会在串口中打印出来。
主要函数解释:
// 设置wifi模式
WiFi.mode(WIFI_STA);
/*注册接收信息的回调函数*/
esp_now_register_recv_cb(OnDataRecv);
/*每次收到消息都会调用OnDataRecv函数*/
/*可以定义每次收到消息执行的动作*/
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len);
完整接收代码:
#include <esp_now.h>
#include <WiFi.h>
int angleX;
char angleY;
float angleZ;
// 创建一个结构体接收数据
typedef struct struct_message {
int anglex;
char angley;
float anglez;
} struct_message;
// 创建一个结构体变量
struct_message myData;
// 回调函数,当收到消息时会调佣该函数
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
//将incomData赋值到myData数据结构中
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("anglex: ");
Serial.println(myData.anglex);
Serial.print("angley: ");
Serial.println(myData.angley);
Serial.print("anglez: ");
Serial.println(myData.anglez);
Serial.println();
}
void setup() {
// 初始化串口波特率
Serial.begin(115200);
// 设置wifi模式
WiFi.mode(WIFI_STA);
// 初始化esp-now
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
//注册接收信息的回调函数
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
//读取结构体变量的值
angleX=myData.anglex;
strcmp(angleY,myData.angley);
angleZ=myData.anglez;
}
一对多单向通信只需要在发送端添加多个MAC地址执行esp_now_send函数,一对一双向通信将发送端及接受端代码结合在一起。