vany5921 发表于 2020-7-2 18:13

ESP-NOW在Arduino中的使用

本帖最后由 vany5921 于 2020-7-3 14:22 编辑

    简单来说,ESP-NOW是乐鑫自主研发的一种基于WiFi的无线通讯技术,借助自身的STA/AP进行连接,特别适合建立快速连接,传输短数据。在ESP32的ESP-NOW协议中有主从机的定义,但在实际使用中除了建立连接外没有明确的主从机关系,双方是对等的,都可具备双向收发能力。在ESP-NOW中有几项是需要明确的,1、主机的mac地址 2、保证主从机在同一个信道 3、是否需要加密 4、从机的MAC地址或者广播。了解了以上4项,使用ESP-NOW是很简单的,基本上就是添加主机/从机,添加发送回调函数,发送成功回调函数,接收回调函数。以下将使用M5StackCore和M5StickC来进行通讯实验,M5StickC用于主机,M5StackCore用于从机,双方可以互发消息,也可以单独指定主发从收。
从机收发程序

#include <WiFi.h>
#include <M5Stack.h>

#define WIFI_CHANNEL 1 //设置通信信道

uint8_t masterDeviceMac[] = {0xD8, 0xA0, 0x1D, 0x55, 0x27, 0xA0}; //添加主机MAC地址
esp_now_peer_info_t master; //声明一个主机类型
const esp_now_peer_info_t *masterNode = &master;
const byte maxDataFrameSize = 250;//ESP-NOW最大支持250字节
uint8_t dataToSend; //消息数组
byte cnt=0;

void setup()
{
M5.begin(true, false, true);
Serial.print("\r\n\r\n");
WiFi.mode(WIFI_AP);//从机通常设置为AP模式
M5.Lcd.print(WiFi.softAPmacAddress()); //获取本机MAC地址
Serial.println( WiFi.softAPmacAddress() );
WiFi.disconnect();
if(esp_now_init() == ESP_OK) //初始化ESP-NOW服务
{
    Serial.println("ESPNow Init Success!");
}
else
{
    Serial.println("ESPNow Init Failed....");
}

//Add the master node to this slave node
memcpy( &master.peer_addr, &masterDeviceMac, 6 ); //添加主机到从机节点
master.channel = WIFI_CHANNEL;
master.encrypt = 0;
master.ifidx = ESP_IF_WIFI_AP;
//Add the remote master node to this slave node
if( esp_now_add_peer(masterNode) == ESP_OK)
{
    Serial.println("Added Master Node!");
}
else
{
    Serial.println("Master Node could not be added...");
}

esp_now_register_recv_cb(OnDataRecv);//接收回调函数
esp_now_register_send_cb(OnDataSent); //发送回调函数

}

void loop()
{
yield();
}

void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)//接收数据
{
M5.Lcd.fillRect(0, 40, 320, 240, TFT_BLACK);
memcpy( dataToSend, data, data_len );
esp_now_send(master.peer_addr, dataToSend, maxDataFrameSize);
Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data);
M5.Lcd.setCursor(0, 40, 2);
M5.Lcd.printf("\r\nReceived\t%d Bytes\t%d", data_len, data);
Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data);
}

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)//发送数据
{
Serial.print("\r\nLast Packet Send Status:\t");
Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}


主机收发程序
#include <esp_now.h>
#include <WiFi.h>
#include <M5StickC.h>

#define WIFI_CHANNEL 1
esp_now_peer_info_t slave;

//uint8_t remoteMac[] = {0xA4, 0xCF, 0x12, 0x6D, 0x6A, 0xD1};//从机MAC地址
uint8_t remoteMac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//广播MAC地址
const uint8_t maxDataFrameSize=250;
const esp_now_peer_info_t *peer = &slave;
uint8_t dataToSend;
byte cnt=0;
long timers;

void setup()
{
M5.begin();
M5.Lcd.setRotation(1);
Serial.print("\r\n\r\n");

WiFi.mode(WIFI_STA);
M5.Lcd.print(WiFi.softAPmacAddress());
Serial.println( WiFi.macAddress() );
WiFi.disconnect();
if(esp_now_init() == ESP_OK)
{
    Serial.println("ESP NOW INIT!");
}
else
{
    Serial.println("ESP NOW INIT FAILED....");
}

memcpy( &slave.peer_addr, &remoteMac, 6 ); //添加从机
slave.channel = WIFI_CHANNEL;
slave.encrypt = 0;
if( esp_now_add_peer(peer) == ESP_OK)
{
    Serial.println("Added Peer!");
}

esp_now_register_send_cb(OnDataSent);//发送回调函数
esp_now_register_recv_cb(OnDataRecv);//接收回调函数
}

void loop()
{
for(cnt=0; cnt<maxDataFrameSize; cnt++)
{
    dataToSend++;
}
if( esp_now_send(slave.peer_addr, dataToSend, maxDataFrameSize) == ESP_OK)
{
    timers = micros();
    Serial.printf("\r\nSuccess Sent Value->\t%d", dataToSend);
    M5.Lcd.setCursor(0, 20, 2);
    M5.Lcd.printf("\r\nSuccess Sent Value->\t%d", dataToSend);
    M5.Lcd.println();
}
else
{
    Serial.printf(".");
}
delay(1000);
M5.Lcd.fillRect(0, 20, 160, 80, TFT_BLACK);
}

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
Serial.print("\r\nLast Packet Send Status:\t");
Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)
{
if(data == dataToSend)
{
    timers = micros();
    timers = timers-timers;
    Serial.printf("\r\nReceived\t%d Bytes val\t%d\tin %d micros", data_len, data, timers);
}
else
{
    Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data);
}
}---------------------------------------------------------------
从机只接收
#include <M5Stack.h>
#include <esp_now.h>
#include <WiFi.h>

#define WIFI_CHANNEL 1
//uint8_t localCustomMac[] = {0xD8, 0xA0, 0x1D, 0x55, 0x27, 0xA0};
const byte maxDataFrameSize = 200;
byte cnt=0;

void setup()
{
M5.begin(true, false, true);
//Serial.begin(115200);
Serial.print("\r\n\r\n");
WiFi.mode(WIFI_AP);
Serial.println( WiFi.softAPmacAddress() );
M5.Lcd.setCursor(0, 0, 2);
M5.Lcd.print("MAC: ");
M5.Lcd.print(WiFi.softAPmacAddress());
M5.Lcd.printf("   CHANNEL:%d",WIFI_CHANNEL);
WiFi.disconnect();
if(esp_now_init() == ESP_OK)
{
    Serial.println("ESPNow Init Success!");
}
else
{
    Serial.println("ESPNow Init Failed....");
}
esp_now_register_recv_cb(OnDataRecv);

}

void loop()
{
yield();
}

void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)
{
Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data);
M5.Lcd.fillRect(0, 20, 320, 220, TFT_BLACK);
M5.Lcd.setCursor(0, 20, 2);
M5.Lcd.printf("\r\nReceived\t%d Bytes\t%d", data_len, data);
}

主机只发送
#include <M5StickC.h>
#include <esp_now.h>
#include <WiFi.h>

#define WIFI_CHANNEL 1
esp_now_peer_info_t slave;
//uint8_t remoteMac[] = {0xA4, 0xCF, 0x12, 0x6D, 0x6A, 0xD1};//从机地址
uint8_t remoteMac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//广播地址
const uint8_t maxDataFrameSize=200;
const esp_now_peer_info_t *peer = &slave;
uint8_t dataToSend;
byte cnt=0;

void setup()
{
M5.begin();
M5.Lcd.setRotation(1);
Serial.begin(115200);
Serial.print("\r\n\r\n");

WiFi.mode(WIFI_STA);
M5.Lcd.print("MAC:");
M5.Lcd.println(WiFi.softAPmacAddress());
M5.Lcd.printf("CHANNEL:%d", WIFI_CHANNEL);
M5.Lcd.println();
Serial.println(WiFi.softAPmacAddress());
WiFi.disconnect();
if(esp_now_init() == ESP_OK)
{
    Serial.println("ESP NOW INIT!");
}
else
{
    Serial.println("ESP NOW INIT FAILED....");
}


memcpy( &slave.peer_addr, &remoteMac, 6 );
slave.channel = WIFI_CHANNEL;
slave.encrypt = 0;
if( esp_now_add_peer(peer) == ESP_OK)
{
    Serial.println("Added Peer!");
    M5.Lcd.println("Added Peer!");
}

esp_now_register_send_cb(OnDataSent);
}

void loop()
{
for(cnt=0; cnt<maxDataFrameSize; cnt++)
{
    dataToSend++;
}
if( esp_now_send(slave.peer_addr, dataToSend, maxDataFrameSize) == ESP_OK)
{
    Serial.printf("\r\nSuccess Sent Value->\t%d", dataToSend);
    M5.Lcd.fillRect(0, 30, 160, 40, TFT_BLACK);
    M5.Lcd.setCursor(0, 30, 2);
    M5.Lcd.printf("\r\nSuccess Sent Value->\t%d", dataToSend);
}
else
{
    Serial.printf("\r\nDID NOT SEND....");
}
delay(250);
}

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
Serial.print("\r\nLast Packet Send Status:\t");
Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

myself1820 发表于 2021-10-9 12:26

楼主有没有 esp_now.h 的库,网上找了半天硬是没找到
页: [1]
查看完整版本: ESP-NOW在Arduino中的使用