ESP32的下的蓝牙应用笔记(1)——Beacon蓝牙信标
Beacon蓝牙信标简介
Beacon蓝牙信标是一种基于蓝牙低功耗(BLE)技术的设备,主要用于提供位置信息和数据传输服务。它通过周期性地广播信号,能够在一定范围内与其他蓝牙设备进行通信,从而提供精准的位置信息和相关服务。
工作原理:Beacon蓝牙信标作为蓝牙低功耗协议中的外围设备,持续向周围广播包含设备标识的特定数据包,但不能和中心设备建立连接。这些数据包通常包含UUID、广播名称、MAC地址、major、minor、电量信息等。简而言之,不需要建立蓝牙连接便可广播数据,如果设备想要接受数据,就必须对特特定的地址进行监听。
Beacon蓝牙信标广播标准下又分为了若干种广播格式,此次学习便以其中的一种Eddystone格式为例子(ESP32例程中有相关的,便于学习)。
Eddystone广播格式简介
Eddystone广播有四种帧格式,
可以根据配置,广播四种不同类型的数据,非常强大。
Eddystone广播包是装载于BLE通用广播包,PDU中的Playload。
引用一张网图如下(这个一整大块就是PDU中的一个Playload)。
第一个AD structure是有关于物理连接功能的配置。
第二个AD structure是有关UUID的配置。
第三个AD structure是有关服务数据的配置,这里的数据包含了UUID和Eddystone的数据。既len-1(类型占用的一个字节)=UUID+Eddystone Data;
代码实现
这部分网上有一些其他作者已经实现,就不再赘述,着重讲一下效果部分。以及我个人的一些理解分析和疑问。
主函数部分:
void app_main(void)
{//初始化ESP_ERROR_CHECK(nvs_flash_init());//释放经典蓝牙ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));//初始化并开启低功耗蓝牙控制器esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();esp_bt_controller_init(&bt_cfg);//开启低功耗BLE控制器esp_bt_controller_enable(ESP_BT_MODE_BLE);//开启eddystone初始化esp_eddystone_init();/*<! set scan parameters *///设置扫描参数//esp_ble_gap_set_scan_params(&ble_scan_params);//服务数据封包esp_eddystone_frame_t uid = {0};int len = Eddystone_set_uid(&uid,0,(uint8_t *)"helloworld",(uint8_t *)"123456");if(len==-1){printf("erro\r\n");return;}adv_data.manufacturer_len = len;adv_data.p_manufacturer_data = (uint8_t *)&uid;//设置广播数据参数esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data);if (ret){ESP_LOGE(DEMO_TAG, "config adv data failed, error code = %x", ret);}//开始广播}
数据封装:
int Eddystone_set_uid(esp_eddystone_frame_t *uid,uint8_t power,uint8_t *name_space,uint8_t *instance)
{if(uid==NULL||name_space==NULL||instance==NULL){return -1;}memset(uid,0,sizeof(esp_eddystone_frame_t));uid->len = sizeof(esp_eddystone_frame_t);uid->uuid = EDDYSTONE_SERVICE_UUID;uid->frame_type = EDDYSTONE_FRAME_TYPE_UID;uid->type = 0x16;uid->u.uid.ranging_data = power;memcpy(uid->u.uid.namespace_id,name_space,10);memcpy(uid->u.uid.instance_id,instance,6);return uid->len;
}
回调函数:
void app_main(void)
{//初始化ESP_ERROR_CHECK(nvs_flash_init());//释放经典蓝牙ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));//初始化并开启低功耗蓝牙控制器esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();esp_bt_controller_init(&bt_cfg);//开启低功耗BLE控制器esp_bt_controller_enable(ESP_BT_MODE_BLE);//开启eddystone初始化esp_eddystone_init();/*<! set scan parameters *///设置扫描参数//esp_ble_gap_set_scan_params(&ble_scan_params);//服务数据封包esp_eddystone_frame_t uid = {0};int len = Eddystone_set_uid(&uid,0,(uint8_t *)"helloworld",(uint8_t *)"123456");if(len==-1){printf("erro\r\n");return;}adv_data.manufacturer_len = len;adv_data.p_manufacturer_data = (uint8_t *)&uid;//设置广播数据参数esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data);if (ret){ESP_LOGE(DEMO_TAG, "config adv data failed, error code = %x", ret);}//开始广播}
参数配置:
static uint8_t adv_service_uuid[]={0xfb,0x34,0x9b,0x5f,0x80,0x00,0x00,0x80,0x00,0x10,0x00,0x00,0xaa,0xfe,0x00,0x00
};
//广播数据
static esp_ble_adv_data_t adv_data={.set_scan_rsp = false,.include_name = false,.include_txpower =false,.min_interval = 0x0006,.max_interval = 0x000c,.appearance = 0x00,.manufacturer_len = 0,.p_manufacturer_data = NULL,.service_data_len = 0,.p_service_data = NULL,.service_uuid_len = 16,.p_service_uuid = adv_service_uuid,.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
};
//广播参数
static esp_ble_adv_params_t adv_params = {.adv_int_min = 0x20,.adv_int_max = 0x40,.adv_type = ADV_TYPE_IND,.own_addr_type = BLE_ADDR_TYPE_PUBLIC,//.peer_addr =//.peer_addr_type =.channel_map = ADV_CHNL_ALL,.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
效果展示
分析
以上图手机抓包的数据为例,第一包数据就是我们配置的物理连接功能基础参数。
对应的参数支持如下
着重讲一下这包数据,可以发现在抓包的数据中,并没有体现这一部分的数据。一开始我也很奇怪,后来经过细致的了解后才明白,这里的配置决定了设备在广告或后续连接过程中能够声明和提供的服务。注意,是能够声明和提供,并不是已经声明和提供,这部分的配置意味着,将BLE蓝牙配置为有哪些功能,至于是否把功能开放广播出来,又是另外一回事。所以如果没开放广播,在抓包的时候自然看不见这部分信息。
最后是
这一包数据,可能有人会好奇为什么是封包在这个manufacturer而不是service这里,我一开始也有疑问,细细了解以后发表一下我的理解。首先eddystone并非是官方的蓝牙协议,只是厂商制定的一种蓝牙广播协议标准,所以它包含的应该是厂家的特定信息,而这里的manufacture data的意为,制造商数据允许设备在广告中包含自定义信息,而这些信息对特定制造商有意义。就如eddystone,是谷歌制造的协议,属于厂家自定义的信息,而并不属于通用的。所以应该放在此处。而从我们蓝牙抓包的第二条数据也可以看到。类型是0xff。
也意为制造商特定数据。
因此eddystone的协议包放在类型为0xff的AD structure中也便好理解了。至于包中的内容,与eddystone的广播格式对应即可。
疑问
最后,查阅eddystone的协议规范发现,标准的eddystone协议包应该包含一位完整的16位的uuid既,len = 0x03 type = 0x03 UUID = 0xFEAA这样一包数据,但可以看到esp32发出的数据包并不包含,确不影响到设备的扫描,但同时在nRF Connect中也并没有把他识别为一个标准的eddystone设备,而是一个普通蓝牙设备,不过不影响数据的收发。协议中对于这一包数据的解析翻译如下:该列表必须包含Eddystone服务UUID(0xFEAA),以便iOS设备进行后台扫描。个人推测即便不加也不影响基础的广播功能。同时如果各位有啥办法能够加上,也不妨可以说一声完善一下(我是试了好多方法都没加上去)。
相关文章:

ESP32的下的蓝牙应用笔记(1)——Beacon蓝牙信标
Beacon蓝牙信标简介 Beacon蓝牙信标是一种基于蓝牙低功耗(BLE)技术的设备,主要用于提供位置信息和数据传输服务。它通过周期性地广播信号,能够在一定范围内与其他蓝牙设备进行通信,从而提供精准的位置信息和相关服…...

控制台安全内部:创新如何塑造未来的硬件保护
在 Help Net Security 的采访中,安全研究人员 Specter 和 ChendoChap 讨论了游戏机独特的安全模型,并强调了它与其他消费设备的不同之处。 他们还分享了对游戏机安全性的进步将如何影响未来消费者和企业硬件设计的看法。 斯佩克特 (Specter) 是本周在阿…...

如何选择适合自己的 Python IDE
集成开发环境(IDE)是指提供广泛软件开发能力的软件应用程序。IDE 通常包括源代码编辑器、构建自动化工具和调试器。大多数现代 IDE 都配备了智能代码补全功能。在本文中,你将发现目前市场上最好的 Python IDE。 什么是 IDE? IDE…...

Matlab车牌识别课程设计报告模板(附源代码)
目 录 一.课程设计目的……………………………………………3 二.设计原理…………………………………………………3 三.详细设计步骤……………………………………………3 四. 设计结果及分析…………………………………………18 五. …...

kubesphere jenkins自动重定向 http://ks-apiserver:30880/oauth/authorize
问题:登陆kubesphere的jenkins Nodeport IP :Port 46.XXX.XXX.16:30180 自动跳转失败 http://ks-apiserver:30880/oauth/authorize?client_idjenkins&redirect_urihttp://46.XXX.XXX.16:30180/securityRealm/finishLogin&response_typecode&scopeopen…...

Vue3访问页面时自动获取数据
1. 使用生命周期钩子函数 # 后端代码--使用pywebview class Api:def greet(self):greet_text pywebview and vue3response {}response[text] greet_textreturn responseif __name__ __main__:# 前后端通信测试api Api()window webview.create_window(Vue app in pywebvie…...

go语言回调函数的使用
前言 在 Go 语言中,回调函数是一种将一个函数作为参数传递给另一个函数,在特定的事件发生时被调用的编程模式。 一、回调函数的定义 type OnTaskHandler func(r []byte)type remoteTaskClient struct {sync.RWMutexonTask OnTaskHandler } 以上定义了…...

区块链学习笔记(一)
区块链技术实现了去中心化的货币系统,与中心化记账方式不同,它消除了中间第三方,允许用户进行点对点交易,并确保了货币的真正所有权。此外,区块链的代码完全公开且不可篡改,保障了系统的透明度和安全性。 …...

解决QT打包发布App Store时(90238)错误
Invalid signature. The main app bundle, xxxx at the “xxxx.app” path, has the following signing error(s): [a sealed resource is missing or invalid. In subcomponent: xxxx.app/Contents/Frameworks/QtWebEngineCore.framework]. For details about signing Mac cod…...

使用Vite构建现代化前端应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用Vite构建现代化前端应用 引言 Vite 简介 安装 Vite 创建项目 启动开发服务器 项目结构 配置 Vite 开发模式 生产构建 使用插…...

PyQt入门指南三十八 QWizard向导组件
在PyQt中,QWizard 是一个用于创建向导式应用程序的组件。向导是一种用户界面模式,它通过一系列逐步的页面引导用户完成某个任务。每个页面通常包含一些输入字段和选项,用户需要在每个页面上完成相应的操作,然后才能进入下一个页面…...

【数学二】线性代数-矩阵-矩阵的概念及运算
考试要求 1、理解矩阵的概念,了解单位矩阵、数量矩阵、对角矩阵、三角矩阵、对称矩阵、反对称矩阵和正交矩阵以及它们的性质. 2、掌握矩阵的线性运算、乘法、转置以及它们的运算规律,了解方阵的幂与方阵乘积的行列式的性质. 3、理解逆矩阵的概念&#x…...

近期学习前端的心得
1.如果你这一行的编辑权利在于你这一行的某个字段的值,你可以使用这样:disabled"scope.row.某字段 ! 某字段的值" 2.如果你不想使用弹出框的形式来修改数据库,可以采用 对“某字段”列使用了 el-input,并绑定了 v-model 到 sco…...

qt QMenu详解
1、概述 QMenu是Qt框架中的一个类,用于创建和管理菜单。它提供了丰富的接口来添加菜单项(通常是QAction对象)、子菜单以及分隔符。QMenu可以嵌入到菜单栏(QMenuBar)中,也可以作为弹出菜单(通过…...

HTMLCSS:旋转的动态卡片
效果演示 这段代码创建了一个具有动态背景和渐变效果的卡片。卡片背景有一个无限循环的旋转动画,增加了视觉吸引力。这种效果可以用于展示个人信息、项目介绍或其他需要吸引用户注意的内容。 HTML <div class"card"><h3>前端Hardy</h3&…...

通过自然语言表达你的想法。GitHub Spark让任何人都能使用人工智能,为自己创建软件...
我们能否让任何人都能使用人工智能,为自己创建软件?尽管开发者喜欢定制自己的开发环境以提高效率和趣味性,但创建个性化应用程序的复杂性常常阻止他们这样做。 如何使个性化软件的创建变得像定制开发环境一样简单?并让更多人能够轻松实现这种…...

c++的list类
本篇将讲述list类中的各种重要和常用函数(begin()、end()、rbegin()、rend()、empty()、size()、front(&#…...

uniapp数据缓存
利用uniapp做开发时,缓存数据是及其重要的,下面是同步缓存和异步缓存的使用 同步缓存 在执行同步缓存时会阻塞其他代码的执行 ① uni.setStorageSync(key, data) 设置缓存,如: uni.setStorageSync(name, 张三) ② uni.getSt…...

HarmonyOS-权限管理
一. 权限分类 1. system_grant system_grant 为系统授权,无需询问用户,常用的权限包括网络请求、获取网络信息、获取wifi信息、获取传感器数据等。 /* system_grant(系统授权)*/static readonly INTERNET ohos.permission.INTE…...

Github 2024-11-02 Rust开源项目日报 Top10
根据Github Trendings的统计,今日(2024-11-02统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Python项目2Dart项目1RustDesk: 用Rust编写的开源远程桌面软件 创建周期:1218 天开发语言:Rust, Dart协议类型:GNU Affero Genera…...

修改HarmonyOS鸿蒙图标和名字,打包后安装到真机,应用图标丢失变成透明,修改名字也不生效,还是默认的labeL解决方案教程
HarmonyOS鸿蒙打包hap 安装应用到桌面没有图标,用hdc安装到真机,打包后应用图标丢失变成透明,名字也还是默认的label的bug,以下是解决方案 以下是修改方案: 1、修改应用名字: 2、修改应用图标:…...

unreal engine5动画重定向
UE5系列文章目录 文章目录 UE5系列文章目录前言一、下载动画资源二、创建IK Rig(IK绑定) 前言 在Unreal Engine 5.4中,动画重定向(Animation Retargeting)和动作匹配(Motion Matching)是两种不…...

蓝桥杯练习笔记(二十-日期问题)
日期题常见于填空题,关键点涉及闰年的判断和星期几的判断 1.根据间隔天数计算日期 题目来源:CSDN算法技能树 在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。 每个炸弹都可以设定多少天之后爆炸。 比如:…...

jenkins 构建报错 mvn: command not found
首先安装过 maven,并且配置过环境变量 win r ,输入 cmd 键入 mvn -v 出现上图输出,则证明安装成功。 原因 jenkins 没有 maven 配置全局属性, 导致无法找到 mvn 命令。 解决方案 找到全局属性,点击新增,配置 MAVEN_HOME 路…...

Vue computed watch
computed watch watch current prev...

【java】java的基本程序设计结构06-运算符
运算符 一、分类 算术运算符关系运算符位运算符逻辑运算符赋值运算符其他运算符 1.1 算术运算符 操作符描述例子加法 - 相加运算符两侧的值A B 等于 30-减法 - 左操作数减去右操作数A – B 等于 -10*乘法 - 相乘操作符两侧的值A * B等于200/除法 - 左操作数除以右操作数B /…...

数据建模圣经|数据模型资源手册卷3,数据建模最佳实践
简介 本书采用了类设计模式的方式对数据模型进行高度抽象总结,展现了常见的数据模型构建模型等模型的作用、层次、分类、地位、沟通方式,和业务规则。使用一个强大的数据模型模式的数据建模,评估特定与广义模型的优缺点,有助于你改…...

Kafka相关知识点(上)
为什么要使用消息队列? 使用消息队列的主要目的主要记住这几个关键词:解耦、异步、削峰填谷。 解耦: 在一个复杂的系统中,不同的模块或服务之间可能需要相互依赖,如果直接使用函数调用或者 API 调用的方式,会造成模块之间的耦合…...

network HCIE认证
#1 ip地址设置 ip add 192.168.1.1 255.255.255.0 ip add 192.168.1.2 255.255.255.0 #2 DHCP 交换机上配置 system-view //进入系统配置 dhcp enable int g0/0/1 //接入接口管理 dhcp select interface //配置dncp选择接口 #3 DNS域名系统 int g0/0/1 dhcp server dn…...

造纸粉体分散机、改性包覆机、改性打散机
包覆改性机在造纸填料中的应用是近年来造纸行业技术创新的一个重要方向。通过包覆改性,可以改善填料的表面性质,提升其在纸张中的留着率和分布均匀性,进而增强纸张的性能,降低生产成本。以下是包覆改性机在造纸填料中的具体应用及…...