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.手机蓝牙改名信息克隆代码测试案例说明 开发板扫描蓝牙设备,获取并打印蓝牙设备mac地址。mac地址每个设备不同,且不能更改。本案例仅适用于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指令来提交代码,简单记录一下日常使用的指令: 提交代码通常顺序: 1.git status 查看本地修改项 2.git add . 提交全部文件 (这个 .是全部文件)到暂存区 3.git commit -m ‘本次提交的说明’…...
ES6对象展开运算符浅拷贝or深拷贝
ES6中提出的对象展开运算符“…”就是用来展开元素的。有了它就不用代码循环遍历了,偷懒专用。 1. 合并数组 展开原有数组中的所有元素,可以合并成一个新的数组。 var a[1,2,3]; var b[4,5,6]; var c[...a,...b]; console.log(c) // 输出:…...

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

CAN总线详细介绍
1.1 CAN是什么? CAN 最终成为国际标准 ( ISO11898(高速应用)和 ISO11519(低速应用)),是国际上应用最广泛的现场总线之一。 1.2 CAN总线特点 多主方式: 可以多主方式工作,网络上任意一个节点…...
python如何完成对 Excel文件的解密后读取?
通常为了防止重要的Excel文件数据内容的泄露,需要对文件整体进行加密与解密的操作。 对于文件的加解密过程,python也有很多非标准库来帮助我们完成操作,这里主要说明如何完成对Excel文件的解密与读取操作。 这里我们使用到的是msoffcrypto-…...

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

autoCAD2022 - 设置新的原点
文章目录autoCAD2022 - 设置新的原点概述笔记UCS原点设置功能的菜单位置ENDautoCAD2022 - 设置新的原点 概述 上次整板子的dxf时, 原来的原点不合适, 想调整一下. 当时整完了, 没记录. 这次用的时候, 又找半天… 设置新原点的功能, 不在顶部菜单中, 而是在视图右上角的UCS图标…...
spring boot 配置 mybatis-plus多数据源
简介Mybatis-puls 多数据源的使用,采用的是官方提供的dynamic-datasource-spring-boot-starter包的 DS 注解,具体可以参考官网:https://gitee.com/baomidou/dynamic-datasource-spring-boot-starterpom.xml文件引入如下依赖主要引入dynamic-d…...

独立产品灵感周刊 DecoHack #047 - 安卓手机上最有用的APP
本周刊记录有趣好玩的独立产品设计开发相关内容,每周发布,往期内容同样精彩,感兴趣的伙伴可以点击订阅我的周刊。为保证每期都能收到,建议邮件订阅。欢迎通过 Twitter 私信推荐或投稿。💻 产品推荐 1. Bouncer Tempor…...

【面试题】JavaScript中递归的理解
大厂面试题分享 面试题库后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库递归 RecursionTo iterate is human, to recurse, divine. 理解迭代,神理解递归。本文会以 JavaScript为主、有部分 Rust 举例说明。…...

PyTorch学习笔记
PyTorch学习笔记(一):PyTorch环境安装 往期学习资料推荐: 1.Pytorch实战笔记_GoAI的博客-CSDN博客 2.Pytorch入门教程_GoAI的博客-CSDN博客 安装参考: 1.视频教程: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前景如何?
作为国际版的“支付宝”,全球第三方支付巨头PayPal的业务横跨欧美市场,覆盖了全球200多个国家和地区。同时,PayPal也是首家进军中国支付市场的外资机构,实力强劲。然而,近两年,PayPal的市值一路从3000亿跌至…...

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

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

网络安全-PHPstudy环境搭建
网络安全-PHPstudy环境搭建 网络搭建我是专家,安全我懂的不多,所以可能很基础。。因为我自己都不懂,都是跟着课程学的 PHPstudy 这个东东是一个在windwos下可以快速部署的web开发环境,安装了就能用,也支持iis和ngin…...
operator的两种用法(重载和隐式类型转换)
文章目录重载隐式类型转换构造函数的隐式类型转换补充operator算子的隐式类型转换重载 略 隐式类型转换 构造函数的隐式类型转换 利用operator进行的隐式类型转换成为operator算子的隐式类型转换,讲这个之前先了解构造函数的隐式类型转换,请看以下代…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...