18、ESP32 ESP-NOW 点对点通信

news2024/11/23 19:40:45

        ESP-NOW 是乐鑫自主研发的无连接通信协议,具有短数据包传输功能。该协议使多个设备能够以简单的方式相互通信。

ESP-NOW 功能

ESP-NOW 支持以下功能:

  • 加密和未加密的单播通信;
  • 混合加密和未加密的对等设备;
  • 最多可携带 250 字节 的有效载荷;
  • 发送回调功能,可以设置用于通知应用层传输成功或失败。

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

  • 有限的加密对等体。Station 模式最多支持 10 个加密对等体,在 SoftAP 或 SoftAP + Station 模式下最多 6 个;
  • 支持多个未加密的对等体,但其总数应小于 20 个,包括加密的对等体;
  • 有效负载限制为 250 字节

        简单来说,ESP-NOW 是一种快速通信协议,可用于在 ESP32 开发板之间交换小消息(最大 250 字节)。


ESP-NOW 通信

1、 单向通信,这种配置非常容易实现,适合将数据从一块板发送到另一块板

 2、一对多通信,一个 ESP32 向不同的 ESP32 发送相同或不同的命令,适合构建类似遥控器的东西

3、多对一通信,将多个传感器节点的数据收集到一个 ESP32 中。可以配置为Web服务器,以显示来自所有其他板的数据

ESP32 获取 MAC 地址

        要通过 ESP-NOW 进行通信,需要知道 ESP32 的 MAC 地址,这样就可以知道要将数据发送到哪个设备。

        每个 ESP32 都有唯一的 MAC 地址,这就是我们识别每块开发板的方式,以便使用 ESP-NOW 向其发送数据。

// 次示例返回 MAC 地址

#include <Arduino.h>
#include <WiFi.h>

void setup()
{
    Serial.begin(115200);
    WiFi.mode(WIFI_MODE_STA);
    Serial.println(WiFi.macAddress());
}

void loop()
{
}

 ESP-NOW 双向通信

        使用 ESP-NOW,每块板可以同时是发送方和接收方。因此也可以构建一个类似网络的连接。

函数名称和说明
esp_now_init()初始化 ESP-NOW。在初始化 ESP-NOW 之前,必须先初始化 Wi-Fi
esp_now_add_peer()调用此函数以配对设备并将对等 MAC 地址作为参数传递
esp_now_send()使用 ESP-NOW 发送数据
esp_now_register_send_cb()注册发送回调函数。发送消息时调用此函数返回传递是否成功
esp_now_register_rcv_cb()注册接收回调函数。当通过 ESP-NOW 接收数据时触发

发送设备内容:

  1. 初始化 ESP-NOW;
  2. 注册发送回调函数 OnDataSent,函数将在发送消息时执行,告诉我们消息是否成功传递;
  3. 添加对等设备(接收 ESP32),需要知道接收方 MAC 地址;
  4. 向对等设备发送消息。

接收设备内容:

  1. 初始化 ESP-NOW;
  2. 注册接收回调函数 OnDataRecv,在收到消息时将执行;
  3. 在回调函数中,将消息保存到变量中,以使用该信息执行任何任务。
// 发送设备代码
// 发送四个类型的数据

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

// CC:7B:5C:25:7B:BC
// 08:D1:F9:EB:52:E8

uint8_t broadcastAddress[] = {0xCC, 0x7B, 0x5C, 0x25, 0x7B, 0xBC};

// 发送的数据结构
typedef struct struct_message
{
    char a[32];
    int b;
    float c;
    bool d;
} struct_message;

struct_message myData;

esp_now_peer_info_t peerInfo;


// 发送数据回调函数
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
    // 打印消息是否成功传递
    Serial.print("Last Packet Send Status:");
    Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}


void setup()
{
    Serial.begin(115200);

    WiFi.mode(WIFI_STA);    // Wi-Fi Station

    if (esp_now_init() != ESP_OK)
    {
        Serial.println("Error initializing ESP-NOW");
        return;
    }

    esp_now_register_send_cb(OnDataSent);   // 注册发送数据的回调函数

    memcpy(peerInfo.peer_addr, broadcastAddress, 6);    // 复制 MAC 地址
    peerInfo.channel = 0;       // 使用当前打开的通道
    peerInfo.encrypt = 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;

    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(5000);
}
// 接收设备代码

#include <Arduino.h>
#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.mode(WIFI_STA); // Wi-Fi Station

    if (esp_now_init() != ESP_OK)
    {
        Serial.println("Error initializing ESP-NOW");
        return;
    }

    // 注册接收数据回调函数
    esp_now_register_recv_cb(OnDataRecv);
}

void loop()
{
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1648649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rust 解决循环引用

导航 循环引用一、现象二、解决 循环引用 循环引用出现的一个场景就是你指向我&#xff0c;我指向你&#xff0c;导致程序崩溃 解决方式可以通过弱指针&#xff0c;而Rust中的弱指针就是Weak 在Rc中&#xff0c;可以实现&#xff0c;对一个变量&#xff0c;持有多个不可变引…

QSPI的使用

Quad SPI接口(QSPI)是一种同步串行数据链路,在主模式下提供与外部设备的通信。它类似于SPI协议,只是它有额外的数据线。 普通SPI有四条通信线路:芯片选择、时钟、MOSI和MISO。对于QSPI,可提供额外的数据线。因此,命令/数据/地址是根据所选模式通过单、四或双IO发送的。由…

Typescript基础语法(四)

模块化 模块化是指将复杂的程序拆解为多个独⽴的⽂件单元&#xff0c;每个⽂件被称为⼀个模块。在 TypeScript 中&#xff0c;默认情况下&#xff0c;每个模块都拥有⾃⼰的作⽤域&#xff0c;这意味着在⼀个模块中声明的任何内容&#xff08;如变量、函数、类等&#xff09;在该…

Unity技术学习:渲染大量物体的解决方案,外加RenderMesh、RenderMeshInstanced、RenderMeshIndirect的简单使用

叠甲&#xff1a;本人比较菜&#xff0c;如果哪里不对或者有认知不到的地方&#xff0c;欢迎锐评&#xff08;不玻璃心&#xff09;&#xff01; 导师留了个任务&#xff0c;渲染大量的、移动的物体。 寻找解决方案&#xff1a; 当时找了几个解决方案&#xff1a; 静态批处…

C++常用库函数——strcmp、strchr

1、strcmp&#xff1a;比较两个字符串的值是否相等 例如 char a1[6] "AbDeG",*s1 a1;char a2[6] "AbdEg",* s2 a2;s1 2;s2 2;printf("%d \n", strcmp(s1, s2));return(0); s1指向a1&#xff0c;s2指向a2&#xff0c;strcmp表示比较s1和s…

vue3+vite+js 实现移动端,PC端响应式布局

目前使用的是vue3vite&#xff0c;没有使用ts 纯移动端|PC端 这种适用于只适用一个端的情况 方法&#xff1a;amfe-flexible postcss-pxtorem相结合 ① 执行以下两个命令 npm i -S amfe-flexible npm install postcss-pxtorem --save-dev② main.js文件引用 import amfe-f…

[一本Java+一本Java]5月7日简历指导直播

一、直播预告 每周二、四、六16:30简历指导直播&#xff0c;前美团项目负责人、校招VIP CEO-大拿老师在线讲简历优化 二、简历内容 三、简历核心问题 【简历1】一本- Java 1 虽然项目名称有一定的包装&#xff0c;两个项目的内容都是一眼能看出来的烂大街的项目&#xff0c…

游戏辅助 -- 实战找人物对象基址

本节课在线学习视频&#xff1a; https://pan.quark.cn/s/3e83f4568031 一、打开CE工具&#xff0c;加载游戏进程 二、搜索人物血量144&#xff0c;选择首次扫描 三、进入游戏&#xff0c;让人物血量发生变化&#xff0c;搜索减少的数值 四、发现绿色的数值&#xff0c;一般绿…

uniapp日期区间选择器

uniapp日期区间选择器 在 uniapp 中创建一个简单的自定义日期范围的日期区间选择器&#xff1a; - 限制有效日期范围开始日期为 2024-01-01&#xff0c;结束日期为当日&#xff1b; - 默认日期区间为当日向前计算的7日区间&#xff1b; - 选择开始时间后&#xff0c;判断不可大…

预定类小程序源码搭建包含各行业+源码开源可二开+详细图文搭建部署教程

在数字化浪潮席卷的今天&#xff0c;各行各业都急需找到与顾客连接的新方式。为了满足这一需求&#xff0c;很多店铺和企业都推出了预定类小程序&#xff0c;分享一款开源版预订类小程序源码&#xff0c;一站式解决方案&#xff0c;覆盖餐饮、旅游、美容、医疗、教育等多个行业…

vue-img-cutter 图片裁剪详解

前言&#xff1a;vue-img-cutter 文档&#xff0c;本文档主要讲解插件在 vue3 中使用。 一&#xff1a;安装依赖 npm install vue-img-cutter # or yarn add vue-img-cutter # or pnpm add vue-img-cutter 二&#xff1a;构建 components/ImgCutter.vue 组件 <script se…

罗德与施瓦茨 SMC100A信号发生器9kHz至3.2 GHz

罗德与施瓦茨 SMC100A信号发生器&#xff0c;9 kHz - 3.2 GHz 罗德与施瓦茨 SMC100A 以极具吸引力的价格提供出色的信号质量。它覆盖的频率范围为 9 kHz 至 1.1 GHz 或 3.2 GHz。输出功率为典型值。> 17 dBm。所有重要功能&#xff08;AM/FM/φM/脉冲调制&#xff09;均已集…

视频素材哪个app好?8个视频素材库免费使用

视频内容已成为现代传播中不可或缺的一部分&#xff0c;具备卓越的视频素材对于提升任何媒体作品的质量和吸引力尤为关键。这里列举的一系列精挑细选的全球视频素材网站&#xff0c;旨在为您的商业广告、社交媒体更新或任何其他类型的视觉项目提供最佳支持。 1. 蛙学府&#x…

力扣顺序表思路讲解

本篇文章&#xff0c;我给大家带来的是顺序表题目讲解&#xff0c;希望大家看完有所收获&#xff0c;废话不多说&#xff0c;我们现在开始 审题 大白话&#xff1a;给了一个数组和一个目标值。如果数组里的两个元素相加 目标值&#xff0c;则返回这两个元素的下标。那么大家需…

Xinstall:专业的APP全渠道统计服务商,助力广告数据分析

在移动互联网时代&#xff0c;APP已成为企业营销的重要阵地。然而&#xff0c;随着竞争加剧&#xff0c;广告主们面临着如何精准衡量广告投放效果、优化投放策略等挑战。这时&#xff0c;专业的APP全渠道统计服务商——Xinstall便成为了广告主们的得力助手。 Xinstall作为国内…

EtherCAT开发_4_分布时钟知识点摘抄笔记1

分布时钟 (DC&#xff0c;Distributed Cl ock) 可以使所有EtherCAT设备使用相同的系统时间&#xff0c;从而控制各设备任务的同步执行。从站设备可以根据同步的系统时间产生同步信号&#xff0c;用于中断控制或触发数字量输入输出。支持分布式时钟的从站称为 DC 从站。分布时钟…

消费金融平台公司如何做大做强自营产品

本文来自于2019年的某次内部分享沟通会&#xff0c;部分敏感内容已做删减。

Ubuntu进行换源

各种源大全 在此地 // 此源均只适用Ubuntu 18.04 版本&#xff0c;其他版本需要修改 bionic 为对应的Ubuntu版本#阿里云源地址 deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-security ma…

springboot3 集成spring-authorization-server (一 基础篇)

官方文档 Spring Authorization Server 环境介绍 java&#xff1a;17 SpringBoot&#xff1a;3.2.0 SpringCloud&#xff1a;2023.0.0 引入maven配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…

ComfyUI的图像调色处理

可知这个节点可以让一张图片根据另外一张图片进行调色&#xff0c;我上传其他图片再来看看效果&#xff0c;如下 【保姆级教程】ComfyUI中常见的十几种多图处理节点&#xff0c;包括图像填充、图像拼接、图像混合等等 工作流链接 更多好玩且实用AIGC工作流和节点 星球号&#…