ESP32-NOW-类 -发送端和接收端的程序

news2024/10/6 20:01:29

ESP32-NOW-类 -发送端-持续发送-不考虑接收端是否收到-避免程序因接收端没有返回信息而意外停止发送。

import network
import espnow
import time

class esp_now_rs(object):  # 定义一个ESP-NOW通信类
    def __init__(self):  # 初始化方法
        self.sta = network.WLAN(network.STA_IF)  # 创建STA接口的WLAN对象
        self.sta.active(True)  # 激活STA接口
        self.sta.disconnect()  # 断开STA接口的WiFi连接,避免干扰ESP-NOW
        self.e = espnow.ESPNow()  # 创建ESP-NOW对象
        self.e.active(True)  # 激活ESP-NOW
        self.host_mac = self.sta.config('mac')  # 获取本机的MAC地址

    def send_msg(self, data, peer):  # 修改发送消息方法,不依赖接收确认
        try:
            self.e.send(peer, data)  # 使用ESP-NOW发送数据到目标设备
        except OSError as err:
            if err.errno == 116:  # ETIMEDOUT
                print("Send timeout, continuing...")
            else:
                raise

    def add_peer(self, addr):  # 添加对端设备方法
        self.e.add_peer(addr)  # 向ESP-NOW添加对端设备

# 主程序入口
if __name__ == '__main__':
    esp_sender = esp_now_rs()  # 创建ESP-NOW通信对象
    peer_addr = b'\xcc{\\$\xaf,'  # 接收端ESP32的MAC地址
    esp_sender.add_peer(peer_addr)  # 注册接收端ESP32的MAC地址

    counter = 0  # 初始化计数器
    while True:  # 主循环
        # 构建要发送的消息
        message = str(counter).encode('utf-8')
        
        # 使用esp_now_rs类的send_msg方法发送消息,忽略发送失败
        esp_sender.send_msg(message, peer_addr)
        
        # 输出发送的信息(可选)
        print("Sent:", message.decode('utf-8'))
        
        # 计数器递增,然后模10以循环发送0至9
        counter = (counter + 1) % 10
        
        # 等待1秒
        time.sleep(1)

ESP32-NOW-类 -接收端 - 没有信号时也持续接收-不会因为异常而停止程序的运行

import network
import espnow
import time
import json
import binascii
from machine import Pin
import ssd1306
from machine import SoftI2C

# OLED屏幕初始化
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)




class esp_now_rs(object):  # 定义一个ESP-NOW通信类
    def __init__(self):  # 初始化方法
        self.sta = network.WLAN(network.STA_IF)  # 创建STA接口的WLAN对象
        self.sta.active(True)  # 激活STA接口
        self.sta.disconnect()  # 断开STA接口的WiFi连接,避免干扰ESP-NOW
        self.e = espnow.ESPNow()  # 创建ESP-NOW对象
        self.e.active(True)  # 激活ESP-NOW
        self.host_mac = self.sta.config('mac')  # 获取本机的MAC地址

    def send_msg(self, data):  # 发送消息方法,仅发送给最近注册的设备
        self.e.send(self.peer, data)  # 使用ESP-NOW发送数据到目标设备

    def send_dict_msg(self, key, value):  # 发送字典格式的消息
        data = self.bytes_dictjson_bytes(key, value)  # 将键值对转换为字节化的字典数据
        self.e.send(self.peer, data)  # 发送数据
        return data  # 返回发送的数据

    def recv_dict_msg(self):  # 接收并解析字典格式的消息
        if self.e.any() > 0:  # 检查是否有待接收的消息
            host_adr, recv_msg = self.e.recv()  # 接收消息
            try:
                host_adr, recv_msg = self.bytes_dictjson_dict(recv_msg)  # 解析消息
            except:
                pass
            try:
                for peer, info in self.e.peers_table.items():  # 遍历对端设备表,获取RSSI等信息
                    mac_address = ':'.join('{:02x}'.format(b) for b in peer)  # 格式化MAC地址
                    rssi = info[0]  # 获取RSSI值
                    time_ms = info[1]  # 获取时间戳
                    #print(f"MAC: {mac_address}, RSSI: {rssi} dBm, Time: {time_ms} ms")  # 打印设备信息
                    #print(rssi)
                return host_adr, recv_msg, rssi  # 返回发送者地址、消息和RSSI值
            except:  # 兼容8266设备,8266没有RSSI功能
                return host_adr, recv_msg, 0  # 返回发送者地址、消息和默认RSSI值0

    def add_peer(self, addr):  # 添加对端设备方法
        self.peer = addr  # 记录对端设备的MAC地址
        self.e.add_peer(addr)  # 向ESP-NOW添加对端设备

    # 以下是一些辅助方法,用于数据的转换和处理

    def hex_to_bytes(self, b_data):  # 将字节串转换为十六进制字符串
        hex_key = binascii.hexlify(b_data).decode('ascii')  # 转换并解码
        return hex_key

    def bytes_to_hex(self, b_data):  # 将十六进制字符串转换为字节串
        b_hex = binascii.unhexlify(b_data)  # 转换
        return b_hex

    def bytes_dictjson_bytes(self, key, value):  # 将字典键值对转换为字节化的JSON数据
        key = self.hex_to_bytes(key)  # 将键转换为十六进制字符串
        value = self.hex_to_bytes(value)  # 将值转换为十六进制字符串
        b_data = json.dumps({key: value}).encode('utf-8')  # 序列化为JSON并编码为字节串
        return b_data

    def bytes_dictjson_dict(self, b_data):  # 将字节化的JSON数据转换为字典键值对
        b_dict = json.loads(b_data.decode('utf-8'))  # 反序列化为字典
        key = binascii.unhexlify(list(b_dict.keys())[0])  # 将键从十六进制字符串还原为字节串
        value = binascii.unhexlify(b_dict[list(b_dict.keys())[0]])  # 将值从十六进制字符串还原为字节串
        return key, value  # 返回键值对

    def recv_msg(self):  # 接收消息方法
        if self.e.any() > 0:  # 检查是否有待接收的消息
            host_adr, recv_msg = self.e.recv()  # 接收消息
            try:
                for peer, info in self.e.peers_table.items():  # 遍历对端设备表,获取RSSI等信息
                    mac_address = ':'.join('{:02x}'.format(b) for b in peer)  # 格式化MAC地址
                    rssi = info[0]  # 获取RSSI值
                    time_ms = info[1]  # 获取时间戳
                    #print(f"MAC: {mac_address}, RSSI: {rssi} dBm, Time: {time_ms} ms")  # 打印设备信息
                    #print(rssi)
                return host_adr, recv_msg, rssi  # 返回发送者地址、消息和RSSI值
            except:  # 兼容8266设备,8266没有RSSI功能
                return host_adr, recv_msg, 0  # 返回发送者地址、消息和默认RSSI值0

    def recv_msg(self):  # 修改接收消息方法,增强异常处理
        try:
            if self.e.any() > 0:  # 检查是否有待接收的消息
                host_adr, recv_msg = self.e.recv()  # 接收消息
                try:
                    for peer, info in self.e.peers_table.items():  # 遍历对端设备表,获取RSSI等信息
                        mac_address = ':'.join('{:02x}'.format(b) for b in peer)  # 格式化MAC地址
                        rssi = info[0]  # 获取RSSI值
                        time_ms = info[1]  # 获取时间戳
                        #print(f"MAC: {mac_address}, RSSI: {rssi} dBm, Time: {time_ms} ms")  # 打印设备信息
                        #print(rssi)
                    return host_adr, recv_msg, rssi  # 返回发送者地址、消息和RSSI值
                except Exception as e:
                    print("Error processing received message:", e)
                    return None, None, None  # 返回None以指示处理失败
        except OSError as e:
            if e.errno == 116:  # ETIMEDOUT
                print("Receive timeout, continuing...")
            else:
                print("Other receive error:", e)
        return None, None, None  # 返回None以指示接收失败



# 主程序入口
if __name__ == '__main__':
    aa = esp_now_rs()  # 创建ESP-NOW通信对象
    aa.add_peer(b'\xcc{\\$\xa3\xfc')  # 注册要去连接通信的设备MAC

    adddd = 0  # 初始化计数器变量
    while True:  # 主循环
        host_adr, data, rssi = aa.recv_msg()  # 接收消息,使用增强的recv_msg方法
        if data is not None:  # 只有当数据不为空时才显示
            oled.fill(0)  # 清除屏幕
            oled.text('Received: {}'.format(data.decode()), 0, 0)  # 显示接收数据
            oled.show()  # 更新屏幕显示
        time.sleep(0.5)  # 等待0.5秒
        aa.send_msg(b'%d' % adddd)  # 发送计数器值作为消息
        adddd += 1  # 计数器自增

参考了:
micropython - espnow

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

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

相关文章

湘潭大学信息与网络安全复习笔记2(总览)

前面的实验和作业反正已经结束了,现在就是集中火力把剩下的内容复习一遍,这一篇博客的内容主要是参考教学大纲和教学日历 文章目录 教学日历教学大纲 教学日历 总共 12 次课,第一次课是概述,第二次和第三次课是密码学基础&#x…

使用Redis将单机登录改为分布式登录

使用Redis将单机登录改为分布式登录 1. 背景 ​ 现在大多数的应用程序登录的方式都是必须满足分布式登录的效果,比如我们在一个客户端登录之后可以在另一个客户端上面共享当前用户的信息,这样在另一个客户端登录的时候就不用用户再次输入自己的账号密码…

2024年哪4种编程语言最值得学习?看JetBrains报告

六个月前,编程工具界的大牛JetBrains发布了他们的全球开发者年度报告。 小吾从这份报告中挑出了关于全球程序员过去一年使用编程语言的情况和未来的采纳趋势,总结出2024年最值得学习的四种编程语言。一起来看看吧。 JetBrains在2023年中开始,就向全球的编程达人们发出了问卷…

R语言数据分析案例27-使用随机森林模型对家庭资产的回归预测分析

一、研究背景及其意义 家庭资产分析在现代经济学中的重要性不仅限于单个家庭的财务健康状况,它还与整个经济体的发展紧密相关。家庭资产的增长通常反映了国家经济的整体增长,而资产分布的不均则暴露了经济不平等的问题。因此,全球视角下的家…

工业园区的弱电智能化总体建设规划

在当今迅速发展的工业环境中,一个高效、智能的工业园区是企业成功的重要基石。随着技术的进步,弱电系统的智能化已不仅仅是便利的象征,更是安全生产和效率提升的必要条件。今天,我们将探讨如何通过弱电智能化系统的总体建设规划来…

小阿轩yx-Apache 网页优化

小阿轩yx-Apache 网页优化 网页压缩与缓存 对Apache服务器优化配置 能让 Apache 发挥出更好的性能 相反,配置糟糕 Apache可能无法正常服务 网页压缩 网站的访问速度是由多个因素所共同决定的 包括应用程序 响应速度网络带宽服务器性能与客户端之间的网络传…

通过语言大模型来学习LLM和LMM(四)

一、大模型学习 新的东西,学习的东西就是多,而且最简单最基础的都需要学习,仿佛一点基础知识都要细嚼慢咽,刨根问底,再加上一顿云里雾里的吹嘘,迷迷糊糊的感觉高大上。其实就是那么一回事。再过一段时日&a…

ASP.NET MVC企业级程序设计(增非空,日期转换,修改)

目录 题目: 实现过程 控制器代码 DAL BLL Index ADD 题目: 实现过程 控制器代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MvcApplication1.Models; namespace …

FLAN-T5模型的文本摘要任务

Text Summarization with FLAN-T5 — ROCm Blogs (amd.com) 在这篇博客中,我们展示了如何使用HuggingFace在AMD GPU ROCm系统上对语言模型FLAN-T5进行微调,以执行文本摘要任务。 介绍 FLAN-T5是谷歌发布的一个开源大型语言模型,相较于之前的…

企业化运维(3)_PHP、nginx结合php-fpm、memcache、openresty、goaccess日志可视化

###1.PHP源码编译### 解压PHP压缩包,切入PHP目录,进行configure-->make-->make installd三部曲 [rootserver1 ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel ##依赖性 [rootserver1 ~]# yum…

基于Nios-II实现流水灯

基于Nios-II实现流水灯的主要原理 涉及到FPGA(现场可编程门阵列)上的嵌入式软核处理器Nios II与LED控制逻辑的结合。以下是详细的实现原理,分点表示并归纳: Nios II软核处理器介绍: Nios II是Altera公司推出的一种应用…

Camtasia2024破解永久激活码注册码分享最新

随着数字时代的到来,视频制作已成为许多人日常生活和工作中不可或缺的一部分。而在众多视频编辑软件中,Camtasia凭借其强大的功能和易用性,赢得了广泛的用户喜爱。近期,Camtasia 2024的破解版本在网络上引起了广泛关注。本文旨在为…

外链建设如何进行?

理解dofollow和nofollow链接,所谓dofollow链接,就是可以传递权重到你的网站的链接,这种链接对你的网站排名非常有帮助,这种链接可以推动你的网站在搜索结果中的位置向上爬,但一个网站全是这种有用的链接,反…

scrapy爬取豆瓣书单存入MongoDB数据库

scrapy爬取豆瓣书单存入MongoDB数据库 一、安装scrapy库二、创建scrapy项目三、创建爬虫四、修改settings,设置UA,开启管道五、使用xpath解析数据六、完善items.py七、在douban.py中导入DoubanshudanItem类八、爬取所有页面数据九、管道中存入数据,保存至csv文件十、将数据写…

解决javadoc一直找不到路径的问题

解决javadoc一直找不到路径的问题 出现以上问题就是我们在下载jdk的时候一些运行程序安装在C:\Program Files\Common Files\Oracle\Java\javapath下: 一开始是没有javadoc.exe文件的,我们只需要从jdk的bin目录下找到复制到这个里面,就可以使用…

玄机平台应急响应—MySQL应急

前言 这个是比较简单的,其实和MySQL没啥太大的关系,没涉及太多MySQL的知识。看一下它的flag要求吧。 flag1 它说黑客写入的shell,那我们就去它的网站目录去看看,果然有一个叫sh.php的文件。 flag1{ccfda79e-7aa1-4275-bc26-a61…

excel中按多列进行匹配并对数量进行累加

公司的生产计划是按订单下发,但不同订单的不同产品中可能有用到相同的配件,按单1对1时,对计算机十分友好,但对于在配件库检料的工人来说就比较麻烦,上百条产品里可能会有多条都是相同的产品,首先考虑的办法…

Android采用Scroller实现底部二楼效果

需求 在移动应用开发中,有时我们希望实现一种特殊的布局效果,即“底部二楼”效果。这个效果类似于在列表底部拖动时出现额外的内容区域,用户可以继续向上拖动查看更多内容。这种效果可以用于展示广告、推荐内容或其他信息。 效果 实现后的…

回答网友的一个Delphi问题

网友想在grid 中 加一个水印,俺就给他写了个例子。先靠效果: 这个例子 包含下面几步: 1、创建背景 dg_bmp:Tbitmap.Create; w: Image1.Picture.Bitmap.width; h: Image1.Picture.Bitmap.height; dg_bmp.width: w*2; dg_bmp.height: …