BLE自适应跳频算法详解
前言
(1)自适应跳频算法是相当的简单,小学生都能够看懂,而且网上已经有相当多的关于自适应跳频算法的介绍。既然如此,为什么我还要写这样一篇博客呢?
(2)原因很简单,我发现各位大佬可能是觉得自适应跳频算法太简单,以至于又加上了一堆其他深奥的内容,用以拔高整篇博客质量。当然,深度提高了,但是对于我这种小菜鸡来说,就容易搞的脑壳痛。
(3)因此,这里小菜鸡斗胆再写一篇博客介绍一下自适应跳频算法,并举例进行分析。
为什么需要自适应跳频算法
(1)首先我们需要知道
BLE的40个信道分布如下。

(2)在
40个信道中,数据信道0 ~ 8,11 ~ 20,24 ~ 31这些信道都将会与WI-FI信道进行冲突。除了常见的WI-FI以外,因为2.4GHZ频段属于免费频段因此还会有例如Zigbee等协议采用该频段,造成拥挤。

(3)为了保证
BLE通讯过程中,降低与其他无线电协议产生碰撞几率,就需要使用一个跳频算法来进行保证。
(4)因此,我们即可知道,自适应跳频算法就是一种频率跳变的无线电技术,它能够屏蔽差的信道并将其重新映射到好的信道。
自适应跳频算法介绍
自适应跳频算法公式
(1)跳频算法公式如下:
<1> f n f_{n} fn : 当前BLE连接事件使用的信道。
<2> f n + 1 f_{n+1} fn+1 : 下一次BLE连接事件使用的理论信道。
<3> h o p hop hop : 每次跳频的间隔,值为5~16。
<3> % \% % : 取余,因为数据信道只有37个。
f n + 1 = ( f n + h o p ) % 37 f_{n+1}=(f_{n} + hop) \% 37 fn+1=(fn+hop)%37
(2)在跳频算法中,我们计算出来的 f n + 1 f_{n+1} fn+1 可能并不是可用信道,因此就需要
ChannelMap、Used、numUsed这三个参数了。
<1>ChannelMap:5byte数据,实际使用37bit,用来表示设备间传输的信道图。其中0表示信道不可用,1表示信道可用。高位表示信道数高,低位为信道数低。
<2>Used: 一个数组,用来记录当前ChannelMap中的可用信道。
<3>numUsed: 可用信道数量。
(3)当我们在上述的跳频算法中,获得的 f n + 1 f_{n+1} fn+1并不是可用信道时,就需要再使用如下算法得重映射后的信道。
<1> C h a n n e l Channel Channel : 重映射后的信道。
<2> U s e d [ ] Used[] Used[] : 可用信道数组
<3> f n + 1 f_{n+1} fn+1 : 下一次BLE连接事件使用的理论信道。
<4> % \% % : 取余,因为可用数据信道只有numUsed个。
<5> n u m U s e d numUsed numUsed : 可用信道数量。
C h a n n e l = U s e d [ f n + 1 % n u m U s e d ] Channel = Used[f_{n+1} \% numUsed] Channel=Used[fn+1%numUsed]
自适应跳频算法举例说明
所有信道均正常
(1)首先,我们假设
0~37个信道都是可供BLE进行使用的。那么此时的
<1>ChannelMap = 0001 1111 1111 1111 1111 1111 1111 1111 1111 1111
<2>Used = [0,1,2,3,4,5,...,35,36]
<3>numUsed = 37
(2)我们预设hop值为5,初始信道 f n f_{n} fn为0,那么信道分布如下:
<0>我们第一个信道设置为0,为好信道,因此无需进行重映射。因此实际信道也为0。
<1>因为上一个信道 f n f_{n} fn为0,hop为5,所以 f n f_{n} fn+hop = 5,5 % 37 = 5。而信道5为可用信道,因此此时采用信道5。
<…>
<8>因为上一个信道 f n f_{n} fn为35,所以 f n f_{n} fn+hop = 40,40 % 37 = 3。而信道3为可用信道,因此此时采用信道3。
| 连接事件计数器 | 未映射时信道 | 是否进行映射 | 实际信道 |
|---|---|---|---|
| 0 | 0 | 否 | 0 |
| 1 | 5 | 否 | 5 |
| 2 | 10 | 否 | 10 |
| 3 | 15 | 否 | 15 |
| 4 | 20 | 否 | 20 |
| 5 | 25 | 否 | 25 |
| 6 | 30 | 否 | 30 |
| 7 | 35 | 否 | 35 |
| 8 | 3 | 否 | 3 |
部分信道正常
(1)上述情况为理想状态,那么我们现在假设
3个主要的WI-FI信道都正在使用,此时的
<1>ChannelMap = 0001 1110 0000 0000 1110 1111 1111 0110 0000 0000。注意,从左到右表示36到0信道。
<2>Used = [9,10,21,22,23,33,34,35,36]
<3>numUsed = 9
(2)我们预设hop值为7,初始信道 f n f_{n} fn为7,那么信道分布如下:
<0>首先,因为我们的初始信道 f n f_{n} fn为7,而信道7不是可用信道,因此它会被重映射。因为numUsed = 9,所以 f n + 1 m o d n u m U s e d = 7 m o d 9 = 7 f_{n+1} \ mod \ \ numUsed = 7 \ mod \ 9 = 7 fn+1 mod numUsed=7 mod 9=7。又因为Used[7] = 35,因此最终重映射后的实际信道为35。
<…>后面计算方法同理。
| 连接事件计数器 | 未映射时信道 | 是否进行映射 | 实际信道 |
|---|---|---|---|
| 0 | 7 | 是 | 35 |
| 1 | 14 | 是 | 33 |
| 2 | 21 | 否 | 21 |
| 3 | 28 | 是 | 10 |
| 4 | 35 | 否 | 35 |
| 5 | 5 | 是 | 33 |
| 6 | 12 | 是 | 22 |
| 7 | 19 | 是 | 10 |
| 8 | 26 | 是 | 36 |
| 9 | 33 | 否 | 33 |
| 10 | 3 | 是 | 22 |
| 11 | 10 | 否 | 10 |
自适应跳频算法学习存在问题
为什么hop为5~16?
(1)根据上面的例子,想必各位已经能够成功掌握自适应跳频算法了。那么,我们此时是否应该思考一个问题,为什么跳频算法的跳数值
hop是在5~16范围内呢?
(2)因为大多数干扰一般都会占据几兆带宽,使用过小的hop值,并不能快速的脱离干扰源,这样将会造成持续的干扰。
(3)同理,如果使用过大的hop值,也无法快速脱离干扰源。根据前面所说的跳频算法,如果我们的 f n = 20 f_{n} = 20 fn=20, h o p = 17 hop = 17 hop=17,那么第一次信道为20,第二次就是0,第三次就是17。 这样我们会发现第一次和第三次的信道差距仅仅3个信道。
存在一个好信道,为什么不一直使用到不能使用为止?
(1)通过上面的了解,我们又会发现一个问题。如果某个信道是可用的,那为什么还需要跳到下一个信道中呢?按照常识来说,既然我们找到了一个可用信道,不应该一直使用该信道,直到该信道不可用为止吗?
(2)这个时候我们就需要考虑到一个问题,我们发现当前信道不可用了,那么做出改变,还来得及吗?因为数据信道大多和WI-FI的信道存在冲突,而WI-FI这种互联网流量存在突发性。当我们突然发现该信道不可用了,那么我们想通知对端设备更改信道,此时会发现,信息将无法有效的被对端设备接收。
(3)一旦信道失效,BLE设备就需要断开连接,重新进行连接同步,这将会耗费许多能量。
(4)而且处于同一区域的网络,会自发的选择干净的频率。如果使用单信道模型,将会出现,短时间相同信道网络数量激增情况。(这个从现实角度举例,就好比大家发现某个专业很好,就都一股脑往里面冲,最终导致内卷严重)
(5)如果使用跳频算法,将能够对网络流量在时域和频域做出合理的分配,这样就能够允许大量的网络在同一区域同时工作。(注意,这个“同时”是较大的单位,例如分钟。如果从us级单位来看,并不是同时工作)
(6)最终,BLE设备采用是的,一个连接事件之内保持相同信道进行数据的交互,在下一个连接事件到来之时,将会换至另外一个信道中进行通讯。
参考
(1)低功耗蓝牙开发权威指南 — 7.4 信道
(2)低功耗蓝牙开发权威指南 — 7.7.5 信道图
(3)低功耗蓝牙开发权威指南 — 7.11.1 自适应跳频
(3)低功耗蓝牙开发权威指南 — 7.12.5 单信道连接事件
相关文章:
BLE自适应跳频算法详解
前言 (1)自适应跳频算法是相当的简单,小学生都能够看懂,而且网上已经有相当多的关于自适应跳频算法的介绍。既然如此,为什么我还要写这样一篇博客呢? (2)原因很简单,我发…...
[Meachines] [Easy] Beep Elastix-CMS-LFI
信息收集 IP AddressOpening Ports10.10.10.7TCP:22, 25, 80, 110, 111, 143, 443, 993, 995, 3306 $ nmap -p- 10.10.10.7 --min-rate 1000 -sC -sV Nmap scan report for 10.10.10.7 (10.10.10.7) Host is up (0.53s latency). Not shown: 65486 filtered tcp ports (no-…...
甘肃麻花:酥脆香甜的陇原美味
在甘肃的美食画卷中,甘肃麻花以其独特的魅力占据着重要的一席之地。甘肃食家巷麻花,那金黄酥脆的外形,宛如一件件精美的艺术品。每一根麻花的纹理都清晰可见,缠绕交织,散发着诱人的光泽。 制作甘肃麻花是一门传统的手艺…...
C语言刷题小记2
前言 本篇博客还是为大家分享一些C语言的OJ题目,如果你感兴趣,希望大佬一键三连。多多支持。下面进入正文部分。 题目1竞选社长 分析:本题要求我们输入一串字符,并且统计个数的多少,那么我们可以通过getchar函数来获…...
JavaScript图片轮播
代码在文章最后面(含图片URL) 实现功能 按向左按钮图片显示上一张按向右按钮图片显示下一张每隔2000毫秒显示下一张图底部三个圆点显示当前的图片的编号 实现流程 初始化图片数组 创建一个包含图片URL的数组,轮播时会通过这个数组来切换图…...
MSSQL注入前置知识
简述 Microsoft SQL server也叫SQL server / MSSQL,由微软推出的关系型数据库,默认端口1433 常见搭配C# / .net IISmssql mssql的数据库文件 数据文件(.mdf):主要的数据文件,包含数据表中的数据和对象信息…...
idea一键为实体类赋值
file -> settings -> plugins -> marketplace 把这个插件装上 找个实体,选中,altenter进入edit界面 我是选择只保留右边这种生成方法,然后选择ok 返回到那个实体,选择,altenter generate生成...
秋招突击——7/24——知识补充——JVM类加载机制
文章目录 引言类加载机制知识点复习类的生命周期1、加载2、连接——验证3、连接——准备4、连接——解析5、初始化 类加载器和类加载机制类加载器类加载机制——双亲委派模型 面试题整理1、类加载是什么2、类加载的过程是什么3、有哪些类加载器?4、双亲委派模型是什…...
如何在 Microsoft SQL Server 中增加字段-完整指南
在使用 Microsoft SQL Server (MSSQL) 进行数据库管理时,添加新字段(列)是一项常见的任务。无论你是需要存储额外的信息,还是调整数据模型以适应新的业务需求,本指南都将帮助你轻松完成这项操作。 目录 1. 使用 T-SQL 添加字段2. 使用 SQL Server Management Studio (SSMS) 添加…...
快手电商Android一面凉经(2024)
快手电商Android一面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《快手电商Android一面凉经(2024)》。 面试职位: Android工程师 技术一面 面试形式…...
随机点名器
练习1 package lx;import java.io.*; import java.util.ArrayList; import java.util.Collections; import java.util.Random;/*需求:需求:有一个文件里面存储了班级同学的信息,每一个信息占一行。格式为:张三-男-23要求通过程序…...
添加动态云层
<template> <div class"topbox"> xx卫星管理 </div> <div class"selectbox"> <div class"title"> 卫星列表 </div> <el-table :data"tableData" style"width: 100%;height:230px;" …...
Spring Boot组成的分布式系统中实现日志跟踪
Spring Boot组成的分布式系统中实现日志跟踪 首发2024-07-25 08:54潘多编程 在分布式系统中,日志跟踪是一项非常重要的功能,它帮助开发者了解请求在整个系统中的流转过程,这对于调试、监控和故障排查至关重要。Spring Boot应用通常作为微服…...
GPT-4o Mini 模型的性能与成本优势全解析
GPT-4o Mini 模型的性能与成本优势全解析 📈 🌟 GPT-4o Mini 模型的性能与成本优势全解析 📈摘要引言正文内容GPT-4o Mini 模型简介 🚀性能测试与对比 📊应用场景 🌐自然语言处理对话系统内容生成 ✍️ &am…...
web前端 - HTML 基础知识大揭秘
HTML 大揭秘 什么是 HTML HTML(Hyper Text Markup Language),中文译为超文本标记语言。其中,我们需要注意两个关键词。一个是 超文本,一个是 标记。所谓超文本,就是将不同空间的文字信息通过超链接的方式…...
HTML meta
<meta>标签用于提供html文档的元信息(metadata)。这些信息不会显示在页面上,但会被浏览器或搜索引擎用来识别页面的编码方式、关键字、描述、作者信息、刷新时间等。 基本语法 <meta name"属性名" content"属性值&q…...
【学习笔记】子集DP
背景 有一类问题和子集有关。 给你一个集合 S S S,令 T T T 为 S S S 的超集,也就是 S S S 所有子集的集合,求 T T T 中所有元素的和。 暴力1 先预处理子集的元素和 A i A_i Ai,再枚举子集。 for(int s0; s<(1<…...
苦学Opencv的第十四天:人脸检测和人脸识别
Python OpenCV入门到精通学习日记:人脸检测和人脸识别 前言 经过了十三天的不懈努力,我们终于也是来到了人脸检测和人脸识别啦!相信大家也很激动吧。接下来我们开始吧! 人脸识别是基于人的脸部特征信息进行身份识别的一种生物识…...
PyTorch学习(1)
PyTorch学习(1) CIFAR-10数据集-图像分类 数据集来源是官方提供的: torchvision.datasets.CIFAR10()共有十类物品,需要用CNN实现图像分类问题。 代码如下:(CIFAR_10_Classifier_Self_1.py) import torch import t…...
三思而后行:计算机行业的决策智慧
在计算机行业,"三思而后行"这一原则显得尤为重要。在这个快速发展、技术不断更新换代的领域,每一个决策都可能对项目的成功与否产生深远的影响。以下是一篇关于在计算机行业中三思重要性的文章。 三思而后行:计算机行业的决策智慧 …...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
