ESP32/ESP8266开发板单向一对多ESP-NOW无线通信

目录

    • 简介
    • 读取ESP32/ESP8266接收方Receiver的MAC地址
    • ESP32发送方Sender程序
    • ESP32/ESP8266接收方Receiver程序
    • ESP-NOW通信验证
    • 总结

简介

本实验通过ESP-NOW无线通信协议实现ESP32开发板向多个ESP32/ESP 8266开发板发送数据。
在这里插入图片描述
在这里插入图片描述

读取ESP32/ESP8266接收方Receiver的MAC地址

读取ESP32开发板的代码

#include <WiFi.h>
#include <esp_wifi.h>void readMacAddress(){uint8_t baseMac[6];esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);if (ret == ESP_OK) {Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x\n",baseMac[0], baseMac[1], baseMac[2],baseMac[3], baseMac[4], baseMac[5]);} else {Serial.println("Failed to read MAC address");}
}void setup(){Serial.begin(115200);WiFi.mode(WIFI_STA);WiFi.STA.begin();Serial.print("[DEFAULT] ESP32 Board MAC Address: ");readMacAddress();
}void loop(){}

通过串口读取到接收方ESP32开发板1的MAC地址为:
在这里插入图片描述
同样的方式读取到接收方ESP32开发板2的MAC地址为:
在这里插入图片描述
读取ESP8266开发板的代码

#include <ESP8266WiFi.h>void setup(){Serial.begin(115200);Serial.println();Serial.print("ESP Board MAC Address:  ");Serial.println(WiFi.macAddress());
}void loop(){}

读取到接收方ESP8266开发板的MAC地址为:
在这里插入图片描述

ESP32发送方Sender程序

把ESP32开发板1,ESP开发板2,ESP8266开发板的MAC地址分别填入到下列代码的broadcastAddress1[ ],broadcastAddress2[ ],broadcastAddress3[ ]数组中

#include <esp_now.h>
#include <WiFi.h>// REPLACE WITH YOUR ESP RECEIVER'S MAC ADDRESS
uint8_t broadcastAddress1[] = {0x54, 0x43, 0xb2, 0x7f, 0x00, 0x60};
uint8_t broadcastAddress2[] = {0x34, 0x5f, 0x45, 0xac, 0x16, 0xc0};
uint8_t broadcastAddress3[] = {0xdc, 0x4f, 0x22, 0x23, 0xca, 0x10};typedef struct test_struct {int x;int y;
} test_struct;esp_now_peer_info_t peerInfo;void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {char macStr[18];Serial.print("Packet to: ");// Copies the sender mac address to a stringsnprintf(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);// register peerpeerInfo.channel = 0;  peerInfo.encrypt = false;memcpy(peerInfo.peer_addr, broadcastAddress1, 6);if (esp_now_add_peer(&peerInfo) != ESP_OK){Serial.println("Failed to add peer");return;}memcpy(peerInfo.peer_addr, broadcastAddress2, 6);if (esp_now_add_peer(&peerInfo) != ESP_OK){Serial.println("Failed to add peer");return;}memcpy(peerInfo.peer_addr, broadcastAddress3, 6);if (esp_now_add_peer(&peerInfo) != ESP_OK){Serial.println("Failed to add peer");return;}
}void loop() {test_struct test;test_struct test2;test_struct test3;test.x = random(0,20);test.y = random(0,20);test2.x = random(0,20);test2.y = random(0,20);test3.x = random(0,20);test3.y = random(0,20);esp_err_t result1 = esp_now_send(broadcastAddress1, (uint8_t *) &test,sizeof(test_struct));if (result1 == ESP_OK) {Serial.println("Sent with success");}else {Serial.println("Error sending the data");}delay(500);esp_err_t result2 = esp_now_send(broadcastAddress2, (uint8_t *) &test2,sizeof(test_struct));if (result2 == ESP_OK) {Serial.println("Sent with success");}else {Serial.println("Error sending the data");}delay(500);  esp_err_t result3 = esp_now_send(broadcastAddress3, (uint8_t *) &test3,sizeof(test_struct));if (result3 == ESP_OK) {Serial.println("Sent with success");}else {Serial.println("Error sending the data");}delay(2000);
}

ESP32/ESP8266接收方Receiver程序

上传代码到ESP32开发板1和ESP3开发板2

#include <esp_now.h>
#include <WiFi.h>//Structure example to receive data
//Must match the sender structure
typedef struct test_struct {int x;int y;
} test_struct;//Create a struct_message called myData
test_struct myData;//callback function that will be executed when data is received
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() {//Initialize Serial MonitorSerial.begin(115200);//Set device as a Wi-Fi StationWiFi.mode(WIFI_STA);//Init ESP-NOWif (esp_now_init() != ESP_OK) {Serial.println("Error initializing ESP-NOW");return;}// Once ESPNow is successfully Init, we will register for recv CB to// get recv packer infoesp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}void loop() {}

ESP8266开发板接收代码

#include <ESP8266WiFi.h>
#include <espnow.h>//Structure example to receive data
//Must match the sender structure
typedef struct test_struct {int x;int y;
} test_struct;//Create a struct_message called myData
test_struct myData;//callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t 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() {//Initialize Serial MonitorSerial.begin(115200);//Set device as a Wi-Fi StationWiFi.mode(WIFI_STA);//Init ESP-NOWif (esp_now_init() != 0) {Serial.println("Error initializing ESP-NOW");return;}// Once ESPNow is successfully Init, we will register for recv CB to// get recv packer infoesp_now_set_self_role(ESP_NOW_ROLE_SLAVE);esp_now_register_recv_cb(OnDataRecv);
}void loop() {}

ESP-NOW通信验证

同时给发送方ESP32开发板,接收方ESP32开发板1,接收方ESP32开发板2,接收方ESP8266开发板供电,并打开四个串口助手观察四个开发板的数据收发情况
若接收方都收到数据,发送方ESP32开发板会收到应答信息,串口打印各个MAC地址的接收方数据分发成功:
在这里插入图片描述
若有接收方没有收到数据,发送方ESP32开发板会收到应答信息,串口打印对应的MAC地址的接收方数据分发失败:
在这里插入图片描述
接收方ESP32开发板1串口打印接收到发送方发过来的随机数据
在这里插入图片描述
接收方ESP32开发板2串口打印接收到发送方发过来的随机数据
在这里插入图片描述
接收方ESP8266开发板串口打印接收到发送方发过来的随机数据
在这里插入图片描述

总结

通过以上例程验证了ESP32/ESP开发板之间单向一对多的ESP-NOW无线通信,接下来的篇章将继续验证多个的ESP32开发板之间实现多对一的ESP-NOW无线通信。

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

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

相关文章

Nginx反向代理出现502 Bad Gateway问题的解决方案

&#x1f389; 前言 前一阵子写了一篇“关于解决调用百度翻译API问题”的博客&#xff0c;近日在调用其他API时又遇到一些棘手的问题&#xff0c;于是写下这篇博客作为记录。 &#x1f389; 问题描述 在代理的遇到过很多错误码&#xff0c;其中出现频率最高的就是502&#x…

LabVIEW提高开发效率技巧----代码规范与文档记录

良好的代码规范与文档记录在LabVIEW开发中至关重要。它不仅能够大幅提升开发效率&#xff0c;还为后续的维护和项目交接提供便利。下面将从命名规则、注释标准、功能说明等多个角度&#xff0c;介绍如何通过规范化开发提高项目的可维护性与协作性。 1. 保持一致的命名规则 在L…

set的相关函数(3)

3.删除 //删除 /* int main() {set<int> s;s.insert({ 2,4,5,2,6,8,10,15 });for (auto e : s){cout << e << " ";}cout << endl;//删除最小的元素就删除排序后的首元素s.erase(s.begin());for (auto e : s){cout << e << "…

Flutter局域网广播(UDP通信)与TCP通信

前言 现在有一个需求&#xff0c;手机和ESP32通过WIFI进行通信。流程如下&#xff1a; 手机创建TCP服务器手机向192.168.0.255的1002端口广播自己的ip地址以及TCP服务器的端口号ESP32监听到1002的广播内容后&#xff0c;连接手机的TCP服务器。最后就是ESP32硬件和TCP服务器进…

双击热备 Electron网页客户端

安装流程&#xff1a; 1.下载node.js安装包进行安装 2.点击Next; 3.勾选&#xff0c;点击Next; 4.选择安装目录 5.选择Online 模式 6.下一步执行安装 。 7.运行cmd,执行命令 path 和 node --version&#xff0c;查看配置路径和版本 8.Goland安装插件node.js 9.配置运行…

深入理解Go语言中的并发封闭与for-select循环模式

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在现代编程中,并发已经成为提高程序性能和响应能力的关键手段。然而,在并发环境下,如何安全地访问和操作共享数据却是一大挑战。本文将深入探讨Go语言中的**封闭(confinement)**技术,以及常见的for-select循…

操作系统:进程间通信方式详解(下:消息队列、信号量、共享内存、套接字)

每日一问&#xff1a;操作系统&#xff1a;进程间通信方式详解&#xff08;下&#xff1a;消息队列、信号量、共享内存、套接字&#xff09; 进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是操作系统中实现不同进程之间数据交换和协作的关键机…

【有啥问啥】深度剖析:大模型AI时代下的推理路径创新应用方法论

深度剖析&#xff1a;大模型AI时代下的推理路径创新应用方法论 随着大规模预训练模型&#xff08;Large Pretrained Models, LPMs&#xff09;和生成式人工智能的迅速发展&#xff0c;AI 在多领域的推理能力大幅提升&#xff0c;尤其是在自然语言处理、计算机视觉和自动决策领…

程序员如何保持与提升核心竞争力

一、引言  随着AIGC&#xff08;人工智能生成内容&#xff09;的快速发展&#xff0c;如chatgpt、midjourney、claude等大语言模型的涌现&#xff0c;AI辅助编程工具正逐渐成为程序员日常工作的得力助手。这一变革不仅对程序员的工作方式产生了深刻影响&#xff0c;也引发了关…

Kafka 下载安装及使用总结

1. 下载安装 官网下载地址&#xff1a;Apache Kafka 下载对应的文件 上传到服务器上&#xff0c;解压 tar -xzf kafka_2.13-3.7.0.tgz目录结果如下 ├── bin │ └── windows ├── config │ └── kraft ├── libs ├── licenses └── site-docs官方文档…

动态数据源多种实现方式及对比详细介绍

文章目录 动态数据源实现方式1. 概述2. 动态数据源实现方式2.1 基于 AbstractRoutingDataSource 实现动态数据源2.2 基于 Spring AOP 实现动态数据源2.3 基于 TransactionManager 实现动态数据源2.4 通过数据库中间件实现动态数据源&#xff08;ShardingSphere、MyCAT&#xff…

探索 Go 语言 container 包:强大容器的魔法世界

《探索 Go 语言 container 包:强大容器的魔法世界》 在 Go 语言的世界里,container包就像是一个神奇的宝库,里面藏着各种强大的容器,为开发者提供了高效的数据存储和操作方式。让我们一起揭开这个宝库的神秘面纱,探索container包中的那些容器。 一、container包简介 co…

将成功请求的数据 放入apipost接口测试工具,发送给后端后,部分符号丢失

将成功请求的数据 放入apipost接口测试工具&#xff0c;发送给后端后&#xff0c;部分符号丢失 apipost、接口测试、符号、丢失、错乱、变成空格背景 做CA对接&#xff0c;保存CA系统的校验数据&#xff0c;需要模仿前端请求调起接口&#xff0c;以便测试功能完整性。 问题描…

MySQL:事务隔离级别

SQL 标准定义了四个隔离级别&#xff1a; READ-UNCOMMITTED(读取未提交) &#xff1a;最低的隔离级别&#xff0c;允许读取尚未提交的数据变更&#xff0c;可能会导致脏读、幻读或不可重复读。READ-COMMITTED(读取已提交) &#xff1a;允许读取并发事务已经提交的数据&#xf…

Flink Task 日志文件隔离

Flink Task 日志文件隔离 任务在启动时会先通过 MdcUtils 启动一个 slf4j 的 MDC 环境&#xff0c;然后将 jobId 添加到 slf4j 的 MDC 容器中&#xff0c;随后任务输出的日志都将附带 joid。 MDC 介绍如下&#xff1a; MDC ( Mapped Diagnostic Contexts )&#xff0c;它是一个…

深度学习:(六)激活函数的选择与介绍

激活函数 之前使用的 a σ ( z ) a\sigma(z) aσ(z) &#xff0c;其中 σ ( ) \sigma(~) σ( ) 便是激活函数。 在神经网络中&#xff0c;不同层的激活函数可以不同。 在学习中&#xff0c;一般以 g ( z ) g(z) g(z) 来表示激活函数。 为什么需要(线性)激活函数&#xff…

K8s容器运行时,移除Dockershim后存在哪些疑惑?

K8s容器运行时&#xff0c;移除Dockershim后存在哪些疑惑&#xff1f; 大家好&#xff0c;我是秋意零。 K8s版本截止目前&#xff08;24/09&#xff09;已经发布到了1.31.x版本。早在K8s版本从1.24.x起&#xff08;22/05&#xff09;&#xff0c;默认的容器运行时就不再是Doc…

暑假考研集训营游记

文章目录 摘要&#xff1a;1.对各大辅导机构考研封闭集训营的一些个人看法&#xff1a;2.对于考研原因一些感想&#xff1a;结语 摘要&#xff1a; Ashy在暑假的时候参加了所在辅导班的为期一个月的考研封闭集训营&#xff0c;有了一些全新的感悟&#xff0c;略作记录。 1.对…

【SpringBoot】97、SpringBoot中使用EasyExcel导出/导入数据

1、EasyExcel Java 解析、生成 Excel 比较有名的框架有 Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi 有一套 SAX 模式的 API 可以一定程度的解决一些内存溢出的问题,但 POI 还是有一些缺陷,比如 07 版 Excel 解压缩以及解压后存储都是在内存中完成的,…

linux-系统备份与恢复-系统恢复

Linux 系统备份与恢复&#xff1a;系统恢复 1. 概述 Linux 系统的恢复是系统管理的重要组成部分&#xff0c;它指的是在系统崩溃、硬件故障、误操作或安全问题后&#xff0c;恢复系统到可用状态的过程。良好的系统恢复计划可以有效避免数据丢失和业务中断&#xff0c;并确保系…