移动端开发进阶之蓝牙通讯(二)

移动端开发进阶之蓝牙通讯(二)

蓝牙广播是一种无线通讯技术,通过无线电波传输数据;
在蓝牙低功耗(BLE)协议中,广播通信是其重要组成部分,主要有两类使用场景:
单一方向的、无连接的数据通信,数据发送者在广播信道上广播数据,数据接收者扫描、接收数据;
连接的建立;
此外,每个设备在使用时,同一时刻,只会在一个信道进行工作,不会占用其他信道,这样可以有效地避免干扰,即使一个信道存在干扰,另外的信道也可以很好地工作;
在广播间隔上,设备每次广播时,会在3个广播信道发送相同的报文,这种设置能有效地避免干扰,因为即使一个信道存在干扰,另外的信道也可以很好地工作。
蓝牙通讯

一、广播参数

蓝牙广播的系统参数主要包括广播间隔和广播延时;
广播间隔是一个关键参数,其单位是毫秒,范围通常在20ms至10.24s之间,必须是0.625ms的整数倍;
根据不同的Advertising_Type,最小值可能会有所不同,例如,当Advertising_Type为0x02或0x03时,最小值为100ms。
另外,广播延时是在广播事件期间,链路层产生的一个0ms至10ms之间的伪随机时间量,这个延时被添加到两个广播事件之间,目的是为了防止多个设备间的干扰。

二、广播信道

任何带有信息的信号传递都要占用一定的带宽,不可能是一个单一的频率;
以BLE为例,BLE在2.4GHz频段安排了40个信道(channel),中心频率从2402MHz开始,以2MHz为间隔;
一个BLE设备在任一时刻只能选择40个信道之中一个进行发射或监听;
接收方需要在同一信道上监听才可能收到数据包,接收方还需要知道数据包长度才能进行CRC校验,包长度是包含在PDU段内;
BLE4.0和4.2时,信道37、38和39用于advertising;每次广播,会在3个广播信道上发送相同的报文;
广播信道的选择主要考虑了避免与WiFi等其他无线通信系统的干扰,通过将广播信道设置在非标准WiFi信道,可以降低广播通信受到的干扰,提高通信的可靠性和稳定性。

三、广播结构

蓝牙广播的最大长度是37个字节,其中设备地址占用了6个字节,只有31个字节是可用的,这意味着广播数据最大长度为31字节,包括广播内容类型和广播数据;
在有效广播数据长度方面,由于广播数据包的结构和组成较为复杂,实际上可用的有效广播数据长度可能会受到限制,具体有效长度取决于广播内容类型和广播数据的内容,不同的类型和内容对应不同的长度;
一般情况下蓝牙广播数据由以下部分组成:

  1. Preamble:这是一个长度为1字节的标识符,用于表示广播数据包的开始。
  2. Access Address:这是一个长度为4字节的地址,用于标识广播设备。
  3. PDU Header:这是一个长度为2字节的头部信息,包含广播数据包的长度和类型等信息。
  4. Payload Data:这是实际传输的数据,长度和内容根据具体应用而定。
  5. CRC:这是一个长度为3字节的校验码,用于检测数据传输的错误。

其中,PDU(Protocol Data Unit)是协议数据单元,用于传输数据;
PDU Header是PDU的头部信息,包含了PDU的一些基本信息,例如长度和类型等;
Payload Data是实际传输的数据内容,可以是设备名称、Mac地址、服务UUID等信息;
CRC是校验码,用于检测数据传输过程中是否出现了错误;
根据不同的需求配置,广播实际传输的数据也会有相应的不同。

#include <iostream>  
#include <bluetooth/bluetooth.h>  
#include <bluetooth/rfcomm.h>  
#include <bluetooth/sdp.h>  int main() {  // 初始化Bluez库  int status = bluetooth_init(&bt_context, NULL);  if (status != 0) {  std::cerr << "Failed to initialize Bluez library." << std::endl;  return 1;  }  // 打开默认的RFCOMM通道(1)  int channel = 1;  int fd = bt_open_channel(channel);  if (fd < 0) {  std::cerr << "Failed to open RFCOMM channel." << std::endl;  return 1;  }  // 开始扫描附近的蓝牙设备  const int type = BLUETOOTH_DISCOV_ANY; // 扫描所有类型的设备  const int filter = 0; // 不使用过滤器  int err = bt_discovery(type, filter, NULL, NULL);  if (err != 0) {  std::cerr << "Failed to start device discovery." << std::endl;  return 1;  }  // 等待设备广播事件  struct sockaddr_rc addr = {0};  socklen_t len = sizeof(addr);  int events = POLLIN; // 等待数据可读的事件  int e = poll(&bt_event, 1, -1, &events); // -1 表示无限等待  if (e == -1) {  std::cerr << "Failed to wait for device discovery event." << std::endl;  return 1;  }  // 处理发现的设备广播事件  if (bt_event.revents & POLLIN) { // 数据可读事件发生时处理广播数据包  char buffer[256]; // 用于存储接收到的广播数据包  int bytes_read = recvfrom(bt_event.fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, &len); // 接收广播数据包  if (bytes_read > 0) { // 处理接收到的数据包  std::cout << "Received device broadcast." << std::endl;  // 在这里处理广播数据包,例如解析服务UUID等。你可以根据需要添加代码来识别特定的设备和服务。  // ...  // 应答广播并尝试建立连接的代码也放在这里。具体的实现取决于你希望如何应答和建立连接。你可能需要发送特定的命令或数据来响应设备,然后等待设备的响应以建立连接。这部分代码需要根据具体的设备和协议进行实现。  } else { // 处理接收错误的情况  std::cerr << "Failed to receive device broadcast." << std::endl;  }  } else if (bt_event.revents & POLLHUP) { // 处理连接断开事件(如果适用)  std::cerr << "RFCOMM channel disconnected." << std::endl;  } else if (bt_event.revents & POLLERR) { // 处理其他错误事件(如果适用)  std::cerr << "Error on RFCOMM channel." << std::endl;  } else { // 处理其他未知事件(如果适用)  std::cerr << "Unknown event on RFCOMM channel." << std::endl;  }  // 清理并关闭资源  close(bt_event.fd); // 关闭RFCOMM通道的文件描述符  bluetooth_cleanup(&bt_context); // 清理Bluez库资源  return 0; // 表示成功执行完毕或出现错误导致程序退出,具体取决于前面的错误处理逻辑。你可以根据需要添加更多的错误处理和资源清理逻辑。  
}

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

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

相关文章

力扣2085-统计出现过一次的公共字符串

统计出现过一次的公共字符串 题目链接 解题思路&#xff1a; 显然我们需要统计每个字符串数组中每个字符串出现的字数 使用哈希表key表示字符产&#xff0c;val用来记录该字符串出现的次数 最后遍历map1&#xff0c;要找到每个字符串只出现一次&#xff0c;并且在两个字符串数…

用Python实现给图片去黑边

图片去黑边&#xff08;只考虑了去水平方向上的黑边&#xff09;的核心算法是要找到图片顶部或顶部的黑边位置&#xff0c;即两个纵坐标值&#xff0c; 主要用到了canny边缘计算、 houghlines直线检测、easyocr识别等算法。 给图片去黑边的实现逻辑为&#xff1a; 先进行canny边…

腾讯云服务器租用价格表_2024新版报价

腾讯云服务器租用价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器446元一年、646元15个月&#xff0c;云服务器CVM S5实例2核2G配置280.8元一年…

127.0.0.1和0.0.0.0的区别

在网络开发中&#xff0c;经常会涉及到两个特殊的IP地址&#xff1a;127.0.0.1和0.0.0.0。这两者之间有一些关键的区别&#xff0c;本文将深入介绍它们的作用和用途。 127.0.0.1 127.0.0.1 是本地回环地址&#xff0c;通常称为 “localhost”。作用是让网络应用程序能够与本地…

【android】rk3588-android-bt

文章目录 蓝牙框架HCI接口蓝牙VENDORLIBvendorlib是什么 代码层面解读vendorlib1、 vendorlib实现&#xff0c;协议栈调用2、协议栈实现&#xff0c;vendorlib调用&#xff08;回调函数&#xff09;2.1、 init函数2.2、BT_VND_OP_POWER_CTRL对应处理2.3、BT_VND_OP_USERIAL_OPE…

5.1 内容管理模块 - 课程预览、提交审核

内容管理模块 - 课程预览、提交审核 文章目录 内容管理模块 - 课程预览、提交审核一、课程预览1.1 需求分析1.2 freemarker 模板引擎1.2.1 Maven 坐标1.2.2 freemaker 相关配置信息1.2.3 添加模板 1.3 测试静态页面1.3.1 部署Nginx1.3.2 解决端口问题被占用问题1.3.3 配置host文…

紫光展锐T770安卓核心板_展锐T770 5G核心板规格参数

紫光展锐T770安卓核心板是一款高性能的5G安卓智能模块&#xff0c;拥有先进的6nm制程工艺和强大的性能。板载8GB Ram 256GBROM的内存单元&#xff0c;支持4K H.265/ H.264视频编解码&#xff0c;搭载Android 13以上操作系统&#xff0c;功能丰富。除了支持5G NSA和SA双模式向下…

数学建模 | 运筹学的 LINGO 软件(附 LINGO代码)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 运筹学的 LINGO 软件 1 简介2 LINGO 快速入门3 LINGO 中的集

我的NPI项目之设备系统启动(三) -- CDT的一个实例

上面说了这么多&#xff0c;这里就添加一个CDT的使用实例和简单的代码解析。 首先生成cdt_configure.xml配置文件&#xff0c;然后执行如下命令&#xff1a; python cdt_generator.py cdt_configure.xml CDT.bin; 就可以生成对应的CDT.bin文件。同时也会生成, 我们会利用ha…

『 C++ 』AVL树详解 ( 万字 )

&#x1f988;STL容器类型 在STL的容器中,分为几种容器: 序列式容器&#xff08;Sequence Containers&#xff09;: 这些容器以线性顺序存储元素&#xff0c;保留了元素的插入顺序。 支持随机访问&#xff0c;因此可以使用索引或迭代器快速访问任何位置的元素。 主要的序列式…

03 SpringMVC响应数据之接收Cookie和请求头+原生API+共享域对象操作

下载postman,测试传json数据 1. 接收cookie 用CookieValue注解将cookie值绑定到控制器中的handler参数。 Controller类中的一个handler GetMapping("/CookieTest") public void handle(CookieValue("cookie的id(name)") String cookie) { //... }2. 接收…

leetcode-2085.统计出现过一次的公共字符串

题目链接&#xff1a;2085. 统计出现过一次的公共字符串 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 1、暴力破解 首先想到的是暴力破解&#xff0c;用两个循环遍历列表&#xff0c;然后将单词出现的情况都记录在一个字典里面。最后遍历字典找到满足条件…

DBA技术栈(三):MySQL 性能影响因素

文章目录 前言一、影响MySQL性能的因素1.1 商业上的需求1.2 应用架构规划1.3 查询语句使用方式1.4 Schema的设计1.5 硬件环境 总结 前言 大部分人都一致认为一个数据库应用系统&#xff08;这里的数据库应用系统概指所有使用数据库的系统&#xff09;的性能瓶颈最容易出现在数…

MOSS 混元 巅峰对话!2024大模型发展都在这里

引言 2023 年&#xff0c;各大厂商争先投入 LLM 研发&#xff0c;一年内&#xff0c;在国内累计就有 200 余个大模型正式发布。尽管很多大模型并不完善&#xff0c;但行业内的研究专家及产业领袖都在为大模型的突破甚至 AGI 的发展&#xff0c;做着不懈探索。 但同时&#xff0…

基于Java (spring-boot)的停车场管理系统

一、项目介绍 基于Java (spring-boot)的停车场管理系统、预订车位系统、停车缴费系统功能&#xff1a; 登录、注册、后台首页、用户信息管理、车辆信息管理、新增车辆、车位费用设置、停泊车辆查询、车辆进出管理、登录日志查询、个人中心、预定停车位、缴费信息。 适用人群&…

Windows系统缺失api-ms-win-crt-runtime-l1-1-0.dll的修复方法

“在Windows操作系统环境下&#xff0c;用户经常遇到丢失api-ms-win-crt-runtime-l1-1-0.dll文件的问题&#xff0c;这一现象引发了广泛的关注与困扰。该dll文件作为Microsoft Visual C Redistributable Package的重要组成部分&#xff0c;对于系统内许多应用程序的正常运行起着…

CMake入门教程【高级篇】编译选项target_compile_options

文章目录 1.概述2.命令作用3.使用说明4.完整代码示例5.实际使用中的技巧6.实际使用中注意事项1.概述 target_compile_options命令允许用户为特定目标(如可执行文件或库)指定编译器选项,这对于优化构建过程和确保代码兼容性至关重要。 #mermaid-svg-q5VxDlvxzfEgUXvs {font-…

MATLAB介绍

MATLAB是MATrix LABoratory即矩阵实验室的缩写&#xff0c;是由美国MathWorks公司开发的专业工程与科学计算软件&#xff0c;是一个集科学计算、数值分析、矩阵计算、数据可视化及交互式程序设计于一体的计算环境&#xff0c;形成一个易于使用的视窗环境。 MATLAB执行由MATLAB…

C++ λ表达式

λ表达式提供了函数对象的另一种编程机制。 在 C 11 和更高版本中&#xff0c;Lambda 表达式&#xff08;通常称为 Lambda&#xff09;是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象&#xff08;闭包&#xff09;的简便方法。 Lambda 通常用于封装传递给算法…

论文笔记(三十九)Learning Human-to-Robot Handovers from Point Clouds

Learning Human-to-Robot Handovers from Point Clouds 文章概括摘要1. 介绍2. 相关工作3. 背景3.1. 强化学习3.2. 移交模拟基准 4. 方法4.1. Handover Environment4.2. 感知4.3. 基于视觉的控制4.4. 师生两阶段培训 (Two-Stage Teacher-Student Training) 5. 实验5.1. 模拟评估…