Arduino for ESP32-----ESP-NOW介绍及使用

2023-05-16

ESP-NOW

  • ESP-NOW介绍
    • ESP-NOW支持以下特性
    • ESP-NOW技术也存在以下局限性
    • 获取ESP32的MAC地址
    • ESP-NOW单向通信(One-way communication)
    • ESP32单板间的双向通信
    • 一对多通信(一发多收)
    • 一对多通信(多发一收)

部分图片来自网络

ESP-NOW介绍

ESP-NOW是一种由Espressif开发的协议,可以让多个设备在不使用Wi-Fi的情况下相互通信。该协议类似于低功耗的2.4GHz无线连接。设备之间的配对需要在通信之前完成。配对完成后,连接是安全的、点对点的,不需要握手。这意味着在设备彼此配对后,连接是持久的。换句话说,如果你的某块单板突然失去电源或复位,当它重启时,它将自动连接到它的频道继续通信

ESP-NOW支持以下特性

  1. 混合加密和未加密的对端设备
  2. 加密和不加密的单播通信
  3. 最多可携带250字节的有效载荷(小数据传输);
  4. 发送回调函数,可以设置为通知应用层传输成功或失败;

ESP-NOW技术也存在以下局限性

  1. 有限的加密。Station模式最多支持10个加密对等体;“软拨号”或“软拨号+工作站”模式最多为6个
  2. 支持多个未加密的对等体,包括加密的对等体,总数不能超过20个
  3. 3.最大消息长度限制在250字节

获取ESP32的MAC地址

在使用ESP-NOW协议前需要知道ESP32 的MAC地址

#include "WiFi.h"
 
void setup(){
  Serial.begin(115200);
  WiFi.mode(WIFI_MODE_STA);
  Serial.println(WiFi.macAddress());
}
 
void loop(){

}

上串口打开串口监视器,可以得到板子的MAC地址,例如
在这里插入图片描述
最好拿个小纸条记下来

ESP-NOW单向通信(One-way communication)

一个ESP32作为发送方,另一个ESP32作为接收方

在这里插入图片描述
发送端的程序

#include <esp_now.h>
#include <WiFi.h>

// 接收端的MAC地址
uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};

// 发送结构体类型
typedef struct struct_message {
  char a[32];
  int b;
  float c;
  bool d;
} 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() {
  //设置要发送的值
  strcpy(myData.a, "THIS IS A CHAR");
  myData.b = random(1,20);
  myData.c = 1.2;
  myData.d = false;
  
  //发送信息到指定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(2000);
}

接收端的程序

#include <esp_now.h>
#include <WiFi.h>

// 创建一个结构体接收数据
typedef struct struct_message {
    char a[32];
    int b;
    float c;
    bool d;
} struct_message;

// 创建一个结构体变量
struct_message myData;

// 回调函数,当收到消息时会调佣该函数
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("Char: ");
  Serial.println(myData.a);
  Serial.print("Int: ");
  Serial.println(myData.b);
  Serial.print("Float: ");
  Serial.println(myData.c);
  Serial.print("Bool: ");
  Serial.println(myData.d);
  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() {

}

分别长传到两块ESP32上,打开串口监视器
发送端:
在这里插入图片描述接收端:在这里插入图片描述

ESP32单板间的双向通信

两块ESP32之间互相发送接收
在这里插入图片描述这里我们用BME280温湿度传感器做实验,并在OLED上显示
相关库连接(前两个是关于OLED的,后两个是BME280的驱动库):
1.Adafruit_GFX library
2.Adafruit_SSD1306 library
3.Adafruit_BME280_Library
4.Adafruit_Sensor

上传下面的代码到两块开发板上,注意MAC地址是两块板子的地址
,关于如何获取板子的MAC地址,前面已经有介绍

#include <esp_now.h>
#include <WiFi.h>

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Adafruit_BME280 bme;

// 这里换为对方板子的MAC地址
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// 定义几个浮点型变量存储BME280传感器的数值,用于发送
float temperature;
float humidity;
float pressure;

// 这里定义的变量用于接收 注意类型也是浮点型
float incomingTemp;
float incomingHum;
float incomingPres;

// 数据发送成功标志
String success;

//定义结构体
typedef struct struct_message {
    float temp;
    float hum;
    float pres;
} struct_message;

// 创建一个结构体变量 用于发送
struct_message BME280Readings;

// 创建一个结构体变量 用于接收
struct_message incomingReadings;

// 发送数据回调函数
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");
  if (status ==0){
    success = "Delivery Success :)";
  }
  else{
    success = "Delivery Fail :(";
  }
}

// 收到消息的回调函数
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
  Serial.print("Bytes received: ");
  Serial.println(len);
  incomingTemp = incomingReadings.temp;
  incomingHum = incomingReadings.hum;
  incomingPres = incomingReadings.pres;
}
 
void setup() {
  // 初始化波特率
  Serial.begin(115200);

  // 初始化BME280
  bool status = bme.begin(0x76);  
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // 初始化OLED
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
 
  // 设置ESP32为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;
         
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
  //注册接收回调函数
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {
  getReadings();
 
  // 准备发送的变量
  BME280Readings.temp = temperature;
  BME280Readings.hum = humidity;
  BME280Readings.pres = pressure;

  //发送数据
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings));
   
  if (result == ESP_OK) {
    Serial.println("Sent with success");
  }
  else {
    Serial.println("Error sending the data");
  }
  updateDisplay();
  delay(10000);
}
//获取传感器数值
void getReadings(){
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = (bme.readPressure() / 100.0F);
}

void updateDisplay(){
  // 收掉信息在OLED上显示
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("INCOMING READINGS");
  display.setCursor(0, 15);
  display.print("Temperature: ");
  display.print(incomingTemp);
  display.cp437(true);
  display.write(248);
  display.print("C");
  display.setCursor(0, 25);
  display.print("Humidity: ");
  display.print(incomingHum);
  display.print("%");
  display.setCursor(0, 35);
  display.print("Pressure: ");
  display.print(incomingPres);
  display.print("hPa");
  display.setCursor(0, 56);
  display.print(success);
  display.display();
  
  // 串口打印信息
  Serial.println("INCOMING READINGS");
  Serial.print("Temperature: ");
  Serial.print(incomingReadings.temp);
  Serial.println(" ºC");
  Serial.print("Humidity: ");
  Serial.print(incomingReadings.hum);
  Serial.println(" %");
  Serial.print("Pressure: ");
  Serial.print(incomingReadings.pres);
  Serial.println(" hPa");
  Serial.println();
}

实验效果图
在这里插入图片描述

一对多通信(一发多收)

在这里插入图片描述

  1. 一块ESP32发送
  2. 多个ESP32作为接收
    同样需要先获取接收板子的Mac地址
    发送端的程序:
#include <esp_now.h>
#include <WiFi.h>

/*接收端板子的Mac地址,这里为三块板子*/
uint8_t broadcastAddress1[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t broadcastAddress2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t broadcastAddress3[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
//用于测试的数据
typedef struct test_struct {
  int x;
  int y;
} test_struct;

test_struct test;

// 发送时的回调函数
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.print(macStr);
  Serial.print(" send status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
 
void setup() {
  Serial.begin(115200);
 
  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;
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;
  
  //配置第一块接收接收的Mac地址
  memcpy(peerInfo.peer_addr, broadcastAddress1, 6);
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
  // 配置第二块接收接收的Mac地址
  memcpy(peerInfo.peer_addr, broadcastAddress2, 6);
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
  /// 配置第三块接收接收的Mac地址
  memcpy(peerInfo.peer_addr, broadcastAddress3, 6);
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
}
 
void loop() {
	//这里使用随机数作为发送的数据
  test.x = random(0,20); 
  test.y = random(0,20);
 
 //esp_now_send()中的第一个参数为0表示向所有接收的板子发送,也是传入指定的板子地址
  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");
  }
  delay(2000);
}

接收端

#include <esp_now.h>
#include <WiFi.h>

//发送的端是数据是结构体,所以这里也创建一个结构体
typedef struct test_struct {
  int x;
  int y;
} test_struct;

test_struct myData;

//收到消息时的回调函数
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("x: ");
  Serial.println(myData.x);
  Serial.print("y: ");
  Serial.println(myData.y);
  Serial.println();
}
 
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_recv_cb(OnDataRecv);
}
 
void loop() {

}

经过本人测试,并不是每次发送所有的板子都能成功的接收到信息
在这里插入图片描述

一对多通信(多发一收)

在这里插入图片描述

  • 一块ESP32板作为接收;多个ESP32板充当发送,本次示例程序采用3块板子作为发送
  • ESP32接收板接收来自所有发送方的消息,并识别发送消息的板子
  • 还是一样,需要先获取接收板子的MAC地址

发送端的程序

#include <esp_now.h>
#include <WiFi.h>

// 这里改为接收板子的MAC地址
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// 还是创建一个结构体类型
typedef struct struct_message {
    int id; //注意这里的id非常重要,作为区分不同发送端板子的标
    int x;
    int y;
} 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.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;
      
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
}
 
void loop() {
  // 设置发送的数据
  myData.id = 1; //注意这里的id,每块发送的板子不能重复
  myData.x = random(0,50);
  myData.y = random(0,50);

  // 向指定MAC地址发送数据
  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);
}

接收端:

#include <esp_now.h>
#include <WiFi.h>

// 和发送端一样,这里也声明一个结构体
typedef struct struct_message {
  int id;
  int x;
  int y;
}struct_message;

struct_message myData;

//创建三个结构体变量来保存每个板上的读数
struct_message board1;
struct_message board2;
struct_message board3;

// 创建一个结构体数组
struct_message boardsStruct[3] = {board1, board2, board3};

// 接收回调函数
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);
  // 更新数据
  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() {
  Serial.begin(115200);
  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() {

  /*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);  
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Arduino for ESP32-----ESP-NOW介绍及使用 的相关文章

随机推荐

  • 联合体在串口通讯中的妙用

    背景 本文主要涉及到的是一种串口通讯的数据处理方法 xff0c 主要是为了解决浮点数在串口通讯中的传输问题 xff1b 通常而言 xff0c 整形的数据类型 xff0c 只需进行移位运算按位取出每个字节即可 xff0c 那么遇到浮点型的数据
  • Linux 平均负载

    本文首发自公众号 LinuxOK xff0c ID 为 xff1a Linux ok 关注公众号第一时间获取更新 xff0c 分享不仅技术文章 xff0c 还有关于职场生活的碎碎念 在 Linux 系统中 xff0c 所谓平均负载 xff0
  • Linux 进程状态

    Linux 进程状态是平时排查问题 程序稳定性测试的基础知识 xff0c 查看进程状态的常用工具有 top 和 ps 以 top 的输出为例 xff1a S 列 xff08 Status xff09 表示进程的状态 xff0c 图中可见 D
  • Docker 是什么

    本文首发自公众号 LinuxOK xff0c ID为 xff1a Linux ok xff0c 关注公众号第一时间获取更新 xff0c 分享记录职场开发过程中所见所感 Docker 是一个用 GO 语言实现的开源项目 xff0c 它可以将应
  • 哈希表示例

    哈希表的意义在于高效查找 对于查找来说 xff0c 如果数据量特别大 xff0c 二分查找和哈希表算法十分有用了 二分查找前面已经讲过 xff0c 现来讲讲哈希表算法 就像输入数据数组下标返回数组元素一样 xff0c 这样的查找方式是最高效
  • RS-485通讯协议

    1 硬件层协议 通讯协议主要是实现两个设备之间的数据交换功能 xff0c 通讯协议分硬件层协议和软件层协议 硬件层协议决定数据如何传输问题 xff0c 比如要在设备1向设备2发送0x63 xff0c 0x63的二进制数为0110 0011
  • udp通讯中的connect()和bind()函数

    本文收录于微信公众号 LinuxOK xff0c ID为 xff1a Linux ok xff0c 关注公众号第一时间获取更多技术学习文章 udp是一个基于无连接的通讯协议 xff0c 通讯基本模型如下 可以看出 xff0c 不论是在客户端
  • c语言和c++的相互调用

    本文收录于微信公众号 LinuxOK xff0c ID为 xff1a Linux ok xff0c 关注公众号第一时间获取更多技术学习文章 在实际项目开发中 xff0c c和c 43 43 代码的相互调用是常见的 xff0c c 43 43
  • MSVC 版本号对应

    MSVC 43 43 14 0 MSC VER 61 61 1900 Visual Studio 2015 MSVC 43 43 12 0 MSC VER 61 61 1800 Visual Studio 2013 MSVC 43 43 1
  • SPI通讯协议介绍

    来到SPI通讯协议了 废话两句 xff0c SPI很重要 xff0c 这是我在学校时候听那些单片机开发工程师说的 出来实习 xff0c 到后来工作 xff0c 确实如此 xff0c SPI的使用很常见 xff0c 那么自然重要咯 SPI S
  • Qt多线程中的信号与槽

    1 Qt对象的依附性和事务循环 QThread继承自QObject xff0c 自然拥有发射信号 定义槽函数的能力 QThread默认声明了以下几个关键信号 信号只能声明不能定义 xff1a 1 线程开始运行时发射的信号 span clas
  • TCP/IP协议四层模型

    本文收录于微信公众号 LinuxOK xff0c ID为 xff1a Linux ok xff0c 关注公众号第一时间获取更多技术学习文章 接下来的学习重心会放在Linux网络编程这一块 xff0c 我的博客也会随之更新 参照的书籍有 Li
  • 常见的DoS攻击

    本文收录于微信公众号 LinuxOK xff0c ID为 xff1a Linux ok xff0c 关注公众号第一时间获取更多技术学习文章 拒绝服务攻击DoS Denial of Service xff1a 使系统过于忙碌而不能执行有用的业
  • stm32的can总线理解及应用——程序对应stm32f103系列

    CAN 是Controller Area Network 的缩写 xff08 以下称为CAN xff09 xff0c 是ISO国际标准化的串行通信协议 它的通信速度较快 xff0c 通信距离远 xff0c 最高1Mbps xff08 距离小
  • 多视图几何三维重建实战系列之MVSNet

    点击上方 计算机视觉工坊 xff0c 选择 星标 干货第一时间送达 1 概述 MVS是一种从具有一定重叠度的多视图视角中恢复场景的稠密结构的技术 xff0c 传统方法利用几何 光学一致性构造匹配代价 xff0c 进行匹配代价累积 xff0c
  • LiLi-OM: 走向高性能固态激光雷达惯性里程计和建图系统

    点击上方 计算机视觉工坊 xff0c 选择 星标 干货第一时间送达 编辑丨当SLAM遇见小王同学 声明 本文只是个人学习记录 xff0c 侵权可删 论文版权与著作权等全归原作者所有 xff0c 小王自觉遵守 中华人民共和国著作权法 与 伯尔
  • LITv2来袭 | 使用HiLo Attention实现高精度、快速度的变形金刚,下游任务均实时

    点击上方 计算机视觉工坊 xff0c 选择 星标 干货第一时间送达 作者丨ChaucerG 来源丨集智书童 近两年来 xff0c ViT 在计算机视觉领域的取得了很多重大的突破 它们的高效设计主要受计算复杂度的间接度量 xff08 即 FL
  • 问答|多重曝光相关论文有哪些?

  • ECCV 2022 | 清华&腾讯AI Lab提出REALY: 重新思考3D人脸重建的评估方法

    作者丨人脸人体重建 来源丨人脸人体重建 编辑丨极市平台 极市导读 本文围绕3D人脸重建的评估方式进行了重新的思考和探索 作者团队通过构建新数据集RELAY xff0c 囊括了更丰富以及更高质量的脸部区域信息 xff0c 并借助新的流程对先前
  • Arduino for ESP32-----ESP-NOW介绍及使用

    ESP NOW ESP NOW介绍ESP NOW支持以下特性ESP NOW技术也存在以下局限性获取ESP32的MAC地址ESP NOW单向通信 One way communication ESP32单板间的双向通信一对多通信 xff08 一