当前位置: 首页 > news >正文

3.28 haas506 2.0开发教程-example-蓝牙多设备扫描(仅支持M320,HD1)

haas506 2.0开发教程-example-蓝牙多设备扫描

  • 案例说明
  • 蓝牙信息克隆
      • 1.手机蓝牙改名
      • 信息克隆
  • 代码
  • 测试

案例说明

  • 开发板扫描蓝牙设备,获取并打印蓝牙设备mac地址。mac地址每个设备不同,且不能更改。
  • 本案例仅适用于M320开发板和HD1-RTU。
  • 案例使用手机与iBeacon作为从机。开发板根据设备名称进行连接,要同时扫描到2个设备,手机的蓝牙名称需要改成与iBeacon相同的名称。

蓝牙信息克隆

使用手机克隆iBeacon的名字信息。

1.手机蓝牙改名

手机下载nRF connect蓝牙调试工具。
在这里插入图片描述
iBeacon设备名称,将手机蓝牙改成一样的名字
在这里插入图片描述

选择ADVERTISER后点击图标改名
在这里插入图片描述

在这里插入图片描述

信息克隆

点开iBeacon设备后,点击CLONE
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就得到了2个同名的设备。

代码

  • 注意更改代码中的设备名称

main.py

# This example finds and connects to a BLE temperature sensor (e.g. the one in ble_temperature.py).# from ast import While
# from logging.config import valid_ident
# from multiprocessing.sharedctypes import Value
# from sys import platlibdir
# from this import d
# from traceback import print_list
import bluetooth
from bluetooth import BLE
from bluetooth import UUID
# import random
import ustruct#import time
import micropythonimport utime as time#from ble_advertising import decode_services, decode_namefrom micropython import const_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_IRQ_GATTS_READ_REQUEST = const(4)
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_PERIPHERAL_CONNECT = const(7)
_IRQ_PERIPHERAL_DISCONNECT = const(8)
_IRQ_GATTC_SERVICE_RESULT = const(9)
_IRQ_GATTC_SERVICE_DONE = const(10)
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11)
_IRQ_GATTC_CHARACTERISTIC_DONE = const(12)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
_IRQ_GATTC_READ_RESULT = const(15)
_IRQ_GATTC_READ_DONE = const(16)
_IRQ_GATTC_WRITE_DONE = const(17)
_IRQ_GATTC_NOTIFY = const(18)
_IRQ_GATTC_INDICATE = const(19)_ADV_IND = const(0x00)
_ADV_DIRECT_IND = const(0x01)  
_ADV_SCAN_IND = const(0x02)
_ADV_NONCONN_IND = const(0x03)# org.bluetooth.service.environmental_sensing
# _ENV_SENSE_UUID = bluetooth.UUID(0x30AF)
_ENV_SENSE_UUID = bluetooth.UUID("FDA50693-A4E2-4FB1-AFCF-C6EB07647825")
# org.bluetooth.characteristic.temperature
_TEMP_UUID = bluetooth.UUID(0x2A6E)
_TEMP_CHAR = (_TEMP_UUID,bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,
)
_ENV_SENSE_SERVICE = (_ENV_SENSE_UUID,(_TEMP_CHAR,),
)_UART_SERVICE_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA77")
_UART_RX_CHAR_UUID = bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA77")
_UART_TX_CHAR_UUID = bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA77")_MY_SERVICE_UUID = bluetooth.UUID(0x181A)# org.bluetooth.characteristic.gap.appearance.xml
_ADV_APPEARANCE_GENERIC_THERMOMETER = const(768)_ADV_TYPE_FLAGS = const(0x01)
_ADV_TYPE_NAME = const(0x09)
_ADV_TYPE_UUID16_COMPLETE = const(0x3)
_ADV_TYPE_UUID32_COMPLETE = const(0x5)
_ADV_TYPE_UUID128_COMPLETE = const(0x7)
_ADV_TYPE_UUID16_MORE = const(0x2)
_ADV_TYPE_UUID32_MORE = const(0x4)
_ADV_TYPE_UUID128_MORE = const(0x6)
_ADV_TYPE_APPEARANCE = const(0x19)def decode_field(payload, adv_type):i = 0result = []while i + 1 < len(payload):if payload[i + 1] == adv_type:result.append(payload[i + 2 : i + payload[i] + 1])i += 1 + payload[i]return resultdef decode_name(payload):n = decode_field(payload, _ADV_TYPE_NAME)# print("n:",n)return str(n[0], "utf-8") if n else ""def decode_mac(addr):if isinstance(addr, memoryview):addr = bytes(addr)assert isinstance(addr,bytes) and len(addr) == 6,ValueError("mac address value error")return ":".join(['%02X' % byte for byte in addr])def print_hex(bytes):l = [hex(int(i)) for i in bytes]return " ".join(l)def decode_services(payload):services = []for u in decode_field(payload, _ADV_TYPE_UUID16_COMPLETE):services.append(bluetooth.UUID(ustruct.unpack("<h", u)[0]))for u in decode_field(payload, _ADV_TYPE_UUID32_COMPLETE):services.append(bluetooth.UUID(ustruct.unpack("<d", u)[0]))for u in decode_field(payload, _ADV_TYPE_UUID128_COMPLETE):services.append(bluetooth.UUID(u))return servicesclass BLETemperatureCentral:def __init__(self, ble):self._ble = bleself._ble.gap_scan_name('X622080084')self._ble.gattc_set_uuids(0xFFF2, 0xFFF1)self._ble.active(True)time.sleep_ms(3000)self._ble.irq(self._irq)self._reset()def _reset(self):# Cached name and address from a successful scan.self._name = Noneself._addr_type = Noneself._addr = Noneself._mac = Noneself._adv_data = None# Cached value (if we have one)self._value = None# Callbacks for completion of various operations.# These reset back to None after being invoked.self._scan_callback = Noneself._conn_callback = Noneself._read_callback = None# Persistent callback for when new data is notified from the device.self._notify_callback = None# Connected device.self._conn_handle = Noneself._start_handle = Noneself._end_handle = Noneself._value_handle = Nonedef _irq(self, event, data):if event == _IRQ_SCAN_RESULT:# time.sleep_ms(1)addr_type, addr, adv_type, rssi, adv_data = data# print("ble data:{}".format(adv_data))# if adv_type in (_ADV_IND, _ADV_DIRECT_IND) and _ENV_SENSE_UUID in decode_services(adv_data):if adv_type in (_ADV_IND, _ADV_DIRECT_IND):# if adv_type in (_ADV_DIRECT_IND): #ibeacon的类型# Found a potential device, remember it and stop scanning.self._addr_type = addr_typeself._addr = bytes(addr)  # Note: addr buffer is owned by caller so need to copy it.self._name = decode_name(adv_data)self._mac = decode_mac(addr)# self._adv_data = bytes(#     adv_data# )  # Note: addr buffer is owned by caller so need to copy it.# self._name = decode_name(adv_data) or "?"# print("ble addr:",self._mac )# print("ble data:",data )elif event == _IRQ_SCAN_DONE:#time.sleep_ms(1000)self._ble.gap_scan(None)#print("##### scan done #####")val = 1if self._scan_callback:if self._addr:# Found a device during the scan (and the scan was explicitly stopped).self._scan_callback(self._addr_type, self._addr, self._name)self._scan_callback = Noneelse:# Scan timed out.self._scan_callback(None, None, None)elif event == _IRQ_PERIPHERAL_CONNECT:print('connect')elif event == _IRQ_PERIPHERAL_DISCONNECT:print('disconnect')elif event == _IRQ_GATTC_SERVICE_RESULT:# Connected device returned a service.conn_handle, start_handle, end_handle, uuid = dataif conn_handle == self._conn_handle and uuid == _ENV_SENSE_UUID:self._start_handle, self._end_handle = start_handle, end_handleelif event == _IRQ_GATTC_SERVICE_DONE:# Service query complete.if self._start_handle and self._end_handle:self._ble.gattc_discover_characteristics(self._conn_handle, self._start_handle, self._end_handle)else:print("Failed to find environmental sensing service.")elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:# Connected device returned a characteristic.conn_handle, def_handle, value_handle, properties, uuid = dataif conn_handle == self._conn_handle and uuid == _TEMP_UUID:self._value_handle = value_handleelif event == _IRQ_GATTC_CHARACTERISTIC_DONE:# Characteristic query complete.if self._value_handle:# We've finished connecting and discovering device, fire the connect callback.if self._conn_callback:self._conn_callback()else:print("Failed to find temperature characteristic.")elif event == _IRQ_GATTC_READ_RESULT:buffer = self._ble.gattc_read(0,0)print('recv data:',buffer)elif event == _IRQ_GATTC_READ_DONE:# Read completed (no-op).conn_handle, value_handle, status = dataelif event == _IRQ_GATTC_NOTIFY:# The ble_temperature.py demo periodically notifies its value.conn_handle, value_handle, notify_data = dataif conn_handle == self._conn_handle and value_handle == self._value_handle:self._update_value(notify_data)if self._notify_callback:self._notify_callback(self._value)elif event == _IRQ_GATTC_WRITE_DONE:conn_handle, value_handle, status = dataprint("TX complete")# Returns true if we've successfully connected and discovered characteristics.def is_connected(self):return self._conn_handle is not None and self._value_handle is not None# Find a device advertising the environmental sensor service.def scan(self, callback=None):self._addr_type = Noneself._addr = Noneself._scan_callback = callbackself._ble.gap_scan(4000, 6000, 6000)# Connect to the specified device (otherwise use cached address from a scan).def connect(self, addr_type=None, addr=None, callback=None):self._addr_type = addr_type or self._addr_typeself._addr = addr or self._addrself._conn_callback = callbackif self._addr_type is None or self._addr is None:return Falseself._ble.gap_connect(self._addr_type, self._addr)return True# Disconnect from current device.def disconnect(self):if not self._conn_handle:returnself._ble.gap_disconnect(self._conn_handle)self._reset()# Issues an (asynchronous) read, will invoke callback with data.def read(self, callback):if not self.is_connected():returnself._read_callback = callbackself._ble.gattc_read(self._conn_handle, self._value_handle)# Sets a callback to be invoked when the device notifies us.def on_notify(self, callback):self._notify_callback = callbackdef _update_value(self, data):# Data is sint16 in degrees Celsius with a resolution of 0.01 degrees Celsius.self._value = ustruct.unpack("<h", data)[0] / 100return self._valuedef value(self):return self._valuedef write(self, v, response=False):# if not self.is_connected():#     returnself._ble.gattc_write(0, 0, v, 1 if response else 0)print("data_send:", v)global v
def demo():time.sleep_ms(2000)ble = bluetooth.BLE()central = BLETemperatureCentral(ble)time.sleep_ms(2000)not_found = Falsedef on_scan(addr_type, addr, name):if addr_type is not None:print("Found sensor addr_type:", addr_type)print("Found sensor addr:", print_hex(addr))print("Found sensor name:", name)global vv = 1else:nonlocal not_foundnot_found = Trueprint("No sensor found.")while True :central.scan(callback=on_scan)time.sleep_ms(2000)# if v == 1:#     central.connect()# while True:#     ble.gattc_notify(1, 1)#     # central.write('123', False)#     time.sleep_ms(1000)if __name__ == "__main__":demo()

测试

Haas506可以搜索到2个不同mac地址的设备,并将mac地址打印。
在这里插入图片描述

相关文章:

3.28 haas506 2.0开发教程-example-蓝牙多设备扫描(仅支持M320,HD1)

haas506 2.0开发教程-example-蓝牙多设备扫描案例说明蓝牙信息克隆1.手机蓝牙改名信息克隆代码测试案例说明 开发板扫描蓝牙设备&#xff0c;获取并打印蓝牙设备mac地址。mac地址每个设备不同&#xff0c;且不能更改。本案例仅适用于M320开发板和HD1-RTU。案例使用手机与iBeac…...

C语言经典编程题100例(41~60)

目录41、习题4-4 特殊a串数列求和42、习题4-6 水仙花数43、习题4-7 最大公约数和最小公倍数44、习题7-5 找鞍点45、练习5-1 求m到n之和46、练习5-2 找两个数中最大者47、练习5-3 数字金字塔48、习题5-1 符号函数49、习题5-2 使用函数求奇数和50、习题5-3 使用函数计算两点间的距…...

git日常使用命令

实习这段时间使用了很多git指令来提交代码&#xff0c;简单记录一下日常使用的指令&#xff1a; 提交代码通常顺序&#xff1a; 1.git status 查看本地修改项 2.git add . 提交全部文件 &#xff08;这个 .是全部文件&#xff09;到暂存区 3.git commit -m ‘本次提交的说明’…...

ES6对象展开运算符浅拷贝or深拷贝

ES6中提出的对象展开运算符“…”就是用来展开元素的。有了它就不用代码循环遍历了&#xff0c;偷懒专用。 1. 合并数组 展开原有数组中的所有元素&#xff0c;可以合并成一个新的数组。 var a[1,2,3]; var b[4,5,6]; var c[...a,...b]; console.log(c) // 输出&#xff1a;…...

leaflet 上传包含shp的zip文件,在map上解析显示图形(059)

第059个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中本地上传包含shp的zip文件,利用shapefile读取shp数据,并在地图上显示图形。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示例效果加载shapefile.js方式安装引用jszip(…...

CAN总线详细介绍

1.1 CAN是什么&#xff1f; CAN 最终成为国际标准 &#xff08; ISO11898(高速应用)和 ISO11519&#xff08;低速应用&#xff09;&#xff09;&#xff0c;是国际上应用最广泛的现场总线之一。 1.2 CAN总线特点 多主方式: 可以多主方式工作&#xff0c;网络上任意一个节点…...

python如何完成对 Excel文件的解密后读取?

通常为了防止重要的Excel文件数据内容的泄露&#xff0c;需要对文件整体进行加密与解密的操作。 对于文件的加解密过程&#xff0c;python也有很多非标准库来帮助我们完成操作&#xff0c;这里主要说明如何完成对Excel文件的解密与读取操作。 这里我们使用到的是msoffcrypto-…...

微服务实战--高级篇:RabbitMQ高级

服务异步通信-高级篇 消息队列在使用过程中&#xff0c;面临着很多实际问题需要思考&#xff1a; 1.消息可靠性 消息从发送&#xff0c;到消费者接收&#xff0c;会经理多个过程&#xff1a; 其中的每一步都可能导致消息丢失&#xff0c;常见的丢失原因包括&#xff1a; 发送…...

autoCAD2022 - 设置新的原点

文章目录autoCAD2022 - 设置新的原点概述笔记UCS原点设置功能的菜单位置ENDautoCAD2022 - 设置新的原点 概述 上次整板子的dxf时, 原来的原点不合适, 想调整一下. 当时整完了, 没记录. 这次用的时候, 又找半天… 设置新原点的功能, 不在顶部菜单中, 而是在视图右上角的UCS图标…...

spring boot 配置 mybatis-plus多数据源

简介Mybatis-puls 多数据源的使用&#xff0c;采用的是官方提供的dynamic-datasource-spring-boot-starter包的 DS 注解&#xff0c;具体可以参考官网&#xff1a;https://gitee.com/baomidou/dynamic-datasource-spring-boot-starterpom.xml文件引入如下依赖主要引入dynamic-d…...

独立产品灵感周刊 DecoHack #047 - 安卓手机上最有用的APP

本周刊记录有趣好玩的独立产品设计开发相关内容&#xff0c;每周发布&#xff0c;往期内容同样精彩&#xff0c;感兴趣的伙伴可以点击订阅我的周刊。为保证每期都能收到&#xff0c;建议邮件订阅。欢迎通过 Twitter 私信推荐或投稿。&#x1f4bb; 产品推荐 1. Bouncer Tempor…...

【面试题】JavaScript中递归的理解

大厂面试题分享 面试题库后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库递归 RecursionTo iterate is human, to recurse, divine. 理解迭代&#xff0c;神理解递归。本文会以 JavaScript为主、有部分 Rust 举例说明。…...

PyTorch学习笔记

PyTorch学习笔记&#xff08;一&#xff09;&#xff1a;PyTorch环境安装 往期学习资料推荐&#xff1a; 1.Pytorch实战笔记_GoAI的博客-CSDN博客 2.Pytorch入门教程_GoAI的博客-CSDN博客 安装参考&#xff1a; 1.视频教程&#xff1a;3分钟深度学习【环境搭建】CUDA Anacon…...

SpringBoot2知识点记录

SpringBoot2知识点记录1.SpringBoot2基础入门1.1 环境要求1.1.1 maven设置1.2 第一个程序 HelloWorld1.2.1 创建maven工程1.2.2 引入依赖1.2.3 创建主程序1.2.4 编写业务1.2.5 测试1.2.6 简化配置1.2.7 简化部署1.3 自动装配1.3.1 SpringBoot特点1.3.1.1 依赖管理1.3.1.2 自动装…...

Mysql

1 Sql编写 count(*) //是对行数目进行计数 count(column_name) //是对列中不为空的行进行计数 SELECT COUNT( DISTINCT id ) FROM tablename; //计算表中id不同的记录有多少条 SELECT DISTINCT id, type FROM tablename; //返回表中id与type同时不同的结果 X.1 连表子查询 sel…...

Q4营收利润增长背后估值持续偏低,全球支付巨头PayPal前景如何?

作为国际版的“支付宝”&#xff0c;全球第三方支付巨头PayPal的业务横跨欧美市场&#xff0c;覆盖了全球200多个国家和地区。同时&#xff0c;PayPal也是首家进军中国支付市场的外资机构&#xff0c;实力强劲。然而&#xff0c;近两年&#xff0c;PayPal的市值一路从3000亿跌至…...

【自然语言处理】【大模型】BLOOM:一个176B参数且可开放获取的多语言模型

BLOOM&#xff1a;一个176B参数且可开放获取的多语言模型《BLOOM: A 176B-Parameter Open-Access Multilingual Language Model》论文地址&#xff1a;https://arxiv.org/pdf/2211.05100.pdf 相关博客 【自然语言处理】【大模型】用于大型Transformer的8-bit矩阵乘法介绍 【自然…...

小红书穿搭博主推广费用是多少?

小红书作为一个种草属性非常强的平台&#xff0c;商业价值是有目共睹的。很多爱美的女性都会在小红书上被种草某个商品&#xff0c;所以很多服装品牌都会在小红书上布局推广。 穿搭作为小红书的顶梁柱类目&#xff0c;刷小红书就能总是看到好看的穿搭博主分享美美的衣服&#…...

网络安全-PHPstudy环境搭建

网络安全-PHPstudy环境搭建 网络搭建我是专家&#xff0c;安全我懂的不多&#xff0c;所以可能很基础。。因为我自己都不懂&#xff0c;都是跟着课程学的 PHPstudy 这个东东是一个在windwos下可以快速部署的web开发环境&#xff0c;安装了就能用&#xff0c;也支持iis和ngin…...

operator的两种用法(重载和隐式类型转换)

文章目录重载隐式类型转换构造函数的隐式类型转换补充operator算子的隐式类型转换重载 略 隐式类型转换 构造函数的隐式类型转换 利用operator进行的隐式类型转换成为operator算子的隐式类型转换&#xff0c;讲这个之前先了解构造函数的隐式类型转换&#xff0c;请看以下代…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

【实施指南】Android客户端HTTPS双向认证实施指南

&#x1f510; 一、所需准备材料 证书文件&#xff08;6类核心文件&#xff09; 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...

break 语句和 continue 语句

break语句和continue语句都具有跳转作用&#xff0c;可以让代码不按既有的顺序执行 break break语句用于跳出代码块或循环 1 2 3 4 5 6 for (var i 0; i < 5; i) { if (i 3){ break; } console.log(i); } continue continue语句用于立即终…...

使用VMware克隆功能快速搭建集群

自己搭建的虚拟机&#xff0c;后续不管是学习java还是大数据&#xff0c;都需要集群&#xff0c;java需要分布式的微服务&#xff0c;大数据Hadoop的计算集群&#xff0c;如果从头开始搭建虚拟机会比较费时费力&#xff0c;这里分享一下如何使用克隆功能快速搭建一个集群 先把…...

mq安装新版-3.13.7的安装

一、下载包&#xff0c;上传到服务器 https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.7/rabbitmq-server-generic-unix-3.13.7.tar.xz 二、 erlang直接安装 rpm -ivh erlang-26.2.4-1.el8.x86_64.rpm不需要配置环境变量&#xff0c;直接就安装了。 erl…...