18、ESP32 ESP-NOW 点对点通信

        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()
{
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#修改默认参数settings文件

右击项目在设置中进行修改&#xff1a; 千万不要在这里改。 如果要在自己的项目里添加这个文件&#xff0c;首先新建个文件夹&#xff0c;然后添加.setting文件&#xff0c;然后再像上面说的那样添加属性。

通过 Java 操作 redis -- String 基本命令

关于 redis String 类型的相关命令推荐看 Redis - String 字符串 要想通过 Java 操作 redis&#xff0c;首先要连接上 redis 服务器&#xff0c;推荐看通过 Java 操作 redis -- 连接 redis 本博客只介绍了一小部分常用的命令&#xff0c;其他的命令根据上面推荐的博客也能很简单…

Penpad再获 Presto Labs 投资,Scroll 生态持续扩张

​Penpad 是 Scroll 生态的 LaunchPad 平台&#xff0c;其整计划像收益聚合器以及 RWA 等功能于一体的综合性 Web3 平台拓展&#xff0c;该平台在近期频获资本市场关注&#xff0c;并获得了多个知名投资者/投资机构的支持。 截止到本文发布前&#xff0c;Penpad 已经获得了包括…

【免费】虚拟同步发电机(VSG)惯量阻尼自适应控制仿真模型【simulink】

目录 主要内容 仿真模型要点 2.1 整体仿真模型 2.2 电压电流双闭环模块 2.3 SVPWM调制策略 2.4 无功电压模块 2.5 自适应控制策略及算法 部分结果 下载链接 主要内容 该模型为simulink仿真模型&#xff0c;主要实现的内容如下&#xff1a; 随着风力发电、光…

4.请求体

什么是请求体(Request Body) 请求体是客户端发送到API的数据。 响应体是API发送给客户端的数据 API几乎总是必须发送一个响应体&#xff0c;但是客户端并不需要一直发送请求体 定义请求体&#xff0c;需要使用 Pydantic 模型 不能通过GET请求发送请求体发送请求体数据&…

ISIS的工作原理

1.邻居关系建立 &#xff08;1&#xff09;IS-IS领接关系建立原则 1、通过将以太网接口模拟成点到点接口&#xff0c;可以建立点到点链路邻接关系。 2、当链路两端IS-IS接口的地址不在同一网段时&#xff0c;如果配置接口对接收的Hello报文不作IP地址检查&#xff0c;也可以建…

基于Springboot的教学辅助系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的教学辅助系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

FreeBSD安装Miniconda,python启动core dumped的问题

综述&#xff1a; 学会在FreeBSD安装Miniconda后&#xff0c;在一台服务器上安装却碰到问题&#xff0c;安装好后&#xff0c;执行python报错&#xff1a;Segmentation fault (core dumped) 。 以前成功的是在FreeBSD13版本&#xff0c;报错的这个是FreeBSD14版本&#xff0c…

基于FPGA的多路彩灯控制器VHDL代码Quartus仿真

名称&#xff1a;基于FPGA的多路彩灯控制器VHDL代码Quartus仿真&#xff08;文末获取&#xff09; 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; 多路彩灯控制器 综合训练内容要求 设计一台基于FPGA的多路彩灯控制器的设计。要求如下 1.彩灯从左…

SpringBoot中HandlerInterceptor拦截器的构建详细教程

作用范围&#xff1a;拦截器主要作用于Spring MVC的DispatcherServlet处理流程中&#xff0c;针对进入Controller层的请求进行拦截处理。它基于Java的反射机制&#xff0c;通过AOP&#xff08;面向切面编程&#xff09;的思想实现&#xff0c;因此它能够访问Spring容器中的Bean…

C语言栈的含义与栈数据操作代码详解!

引言&#xff1a;在本篇博客中&#xff0c;我们将学到数据结构——栈&#xff0c;讲到栈的含义与关于栈的数据操作代码。栈可以在顺序表、双向链表以及单链表的基础上实现&#xff0c;而于本篇博客中&#xff0c;我们选择在顺序表的基础上实现栈。 更多有关C语言和数据结构知识…

2024 AI中转计费平台系统源码

简介&#xff1a; 2024 AI中转计费平台系统源码 文件下载https://www.skpan.cn/CNZjzyC4txX 图片&#xff1a;

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…

什么是多模态大模型,有了大模型,为什么还要多模态大模型?

随着人工智能技术的愈演愈烈&#xff0c;其技术可以说是日新月异&#xff0c;每隔一段时间就会有新的技术和理念被创造出来&#xff1b;而多模态大模型也是其中之一。 什么是多模态 想弄明白什么是多模态大模型&#xff0c;那么首先就要弄明白什么是多模态。 简单来说&#x…

2024DCIC海上风电出力预测Top方案 + 光伏发电出力高分方案学习记录

海上风电出力预测 赛题数据 海上风电出力预测的用电数据分为训练组和测试组两大类&#xff0c;主要包括风电场基本信息、气象变量数据和实际功率数据三个部分。风电场基本信息主要是各风电场的装机容量等信息&#xff1b;气象变量数据是从2022年1月到2024年1月份&#xff0c;…

层级实例化静态网格体组件:开启大量模型处理之门

前言 在数字孪生的世界里&#xff0c;我们常常需要构建大量的模型来呈现真实而丰富的场景。然而&#xff0c;当使用静态网格体 &#xff08;StaticMesh &#xff09;构建大量模型时&#xff0c;可能会遇到卡顿的问题&#xff0c;这给我们带来了不小的困扰&#x1f623;。那么&…

Llama3-Tutorial之Llama3 Agent能力体验+微调(Lagent版)

Llama3-Tutorial之Llama3 Agent能力体验微调&#xff08;Lagent版&#xff09; 参考&#xff1a; https://github.com/SmartFlowAI/Llama3-Tutorial 1. 微调过程 使用XTuner在Agent-FLAN数据集上微调Llama3-8B-Instruct&#xff0c;以让 Llama3-8B-Instruct 模型获得智能体能力…

SpringCloud——consul

SpringCloud——consul 一、consul安装与运行二、consul 实现服务注册与发现1.引入2.服务注册3.服务发现 三、consul 分布式配置1.基础配置2.动态刷新3.配置持久化 四、参考 Eureka已经停止更新了&#xff0c;consul是独立且和微服务功能解耦的注册中心&#xff0c;而不是单独作…

Git命令Gitee注册idea操作git超详细

文章目录 概述相关概念下载和安装常见命令远程仓库介绍与码云注册创建介绍码云注册远程仓库操作关联拉取推送克隆 在idea中使用git集成add和commit差异化比较&查看提交记录版本回退及撤销与远程仓库关联 push从远程仓库上拉取&#xff0c;克隆项目到本地创建分支切换分支将…

[redis] 说一说 redis 的底层数据结构

Redis有动态字符串(sds)、链表(list)、字典(ht)、跳跃表(skiplist)、整数集合(intset)、压缩列表(ziplist) 等底层数据结构。 Redis并没有使用这些数据结构来直接实现键值对数据库&#xff0c;而是基于这些数据结构创建了一个对象系统&#xff0c;来表示所有的key-value。 文章…