ESP32 BLE特征值示例

news2024/12/23 17:19:07

键盘特征值初始化示例

void BleKeyboard::begin(void)
{
  BLEDevice::init(deviceName);
  BLEServer* pServer = BLEDevice::createServer();
  pServer->setCallbacks(this);

  hid = new BLEHIDDevice(pServer);
  inputKeyboard = hid->inputReport(KEYBOARD_ID);  // <-- input REPORTID from report map
  outputKeyboard = hid->outputReport(KEYBOARD_ID);
  inputMediaKeys = hid->inputReport(MEDIA_KEYS_ID);

  outputKeyboard->setCallbacks(this);

  hid->manufacturer()->setValue(deviceManufacturer);

  hid->pnp(0x02, vid, pid, version);
  hid->hidInfo(0x00, 0x01);


#if defined(USE_NIMBLE)

  BLEDevice::setSecurityAuth(true, true, true);

#else

  BLESecurity* pSecurity = new BLESecurity();
  pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND);

#endif // USE_NIMBLE

  hid->reportMap((uint8_t*)_hidReportDescriptor, sizeof(_hidReportDescriptor));
  hid->startServices();

  onStarted(pServer);

  advertising = pServer->getAdvertising();
  advertising->setAppearance(HID_KEYBOARD);
  advertising->addServiceUUID(hid->hidService()->getUUID());
  advertising->setScanResponse(false);
  advertising->start();
  hid->setBatteryLevel(batteryLevel);

  ESP_LOGD(LOG_TAG, "Advertising started!");
}

在这里插入图片描述
2901:用户描述,如上图:My Counter
2902:特征值配置(需要主动推送notify、indicate就需要增加)
在这里插入图片描述

在这里插入图片描述

Bluetooth Low Energy (BLE) 中的这两个服务具有基本而重要的功能,它们为 BLE 设备提供基础支持。下面是关于这两个服务的详细介绍:

  1. 0x1800 - Generic Access Service (通用访问服务):
    这个服务包含了许多跟 BLE 设备的连接和设备本身信息相关的属性。这些属性包括设备名称(Device Name,0x2A00)、外观(Appearance,0x2A01)、外设连接参数(Peripheral Preferred Connection Parameters,0x2A04)等。用户可以通过访问这些属性,获取和设置与 BLE 设备相关的信息,从而实现连接设置、设备信息展示等功能。

  2. 0x1801 - Generic Attribute Service (通用属性服务):
    这个服务是 BLE 中其他服务和特征数据交互的基础,它提供了一个框架以支持其他服务和特征值的查找、读取、写入等操作。这个服务通常包含了服务修改变更特征(Service Change, 0x2A05)。这个特征会在服务或特征发生变更时触发,通知其他相关的设备需要重新发现服务、特征等。

总之,这两个服务在 BLE 通信过程中起到了基础和桥接的作用,支持设备建立连接,获取属性信息,以及实现其他自定义服务的数据通信。

实际示例中,蓝牙鼠标、耳机等典型设备会设置这些值来描述设备的基本信息和配置:

  1. 蓝牙鼠标:
  • 通用访问服务(Generic Access Service,0x1800):

    • 设备名称(Device Name,0x2A00):例如 “WeTab Wireless Mouse”
    • 外观(Appearance,0x2A01):鼠标的类型和类别,例如设置为 “Mouse” 类型
    • 外设连接参数(Peripheral Preferred Connection Parameters,0x2A04):设置鼠标的连接参数,例如设置连接间隔为 15ms-30ms。
  • 通用属性服务(Generic Attribute Service,0x1801):

    • 服务修改变更特征(Service Change,0x2A05):当鼠标的其他服务或特征发生变更时,触发此特征来通知设备重新发现服务或特征。
  1. 蓝牙耳机:
  • 通用访问服务(Generic Access Service,0x1800):

    • 设备名称(Device Name,0x2A00):例如 “WeTab Bluetooth Headphones”
    • 外观(Appearance,0x2A01):耳机的类型和类别,例如设置为 “Headset” 类型
    • 外设连接参数(Peripheral Preferred Connection Parameters,0x2A04):设置耳机的连接参数,例如选择适合音频传输的低延迟连接间隔。
  • 通用属性服务(Generic Attribute Service,0x1801):

    • 服务修改变更特征(Service Change,0x2A05):当耳机的其他服务或特征发生变更时(如音频控制、电池状态等),触发此特征来通知设备重新发现服务或特征。

以上是两个典型蓝牙设备设置通用访问服务和通用属性服务的例子。设备制造商可以根据设备类型和使用场景自定义属性值,从而为用户提供正确、稳定的蓝牙连接和使用体验。

链接蓝牙耳机的数据
在这里插入图片描述
罗技蓝牙鼠标的特征值
![在这里插入图片描述](https://img-blog.csdnimg.cn/9722feb941bd41ccb289e9330ec27baf.png

按键按下与松开处理,按键值为k,经过处理通过sendReport修改inputKeyboard特征值。
this->inputKeyboard->setValue((uint8_t*)keys, sizeof(KeyReport));

//按下按键处理
size_t BleKeyboard::press(uint8_t k)
{
	uint8_t i;
	if (k >= 136) {			// it's a non-printing key (not a modifier)
		k = k - 136;
	} else if (k >= 128) {	// it's a modifier key
		_keyReport.modifiers |= (1<<(k-128));
		k = 0;
	} else {				// it's a printing key
		k = pgm_read_byte(_asciimap + k);
		if (!k) {
			setWriteError();
			return 0;
		}
		if (k & 0x80) {						// it's a capital letter or other character reached with shift
			_keyReport.modifiers |= 0x02;	// the left shift modifier
			k &= 0x7F;
		}
	}

	// Add k to the key report only if it's not already present
	// and if there is an empty slot.
	if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
		_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
		_keyReport.keys[4] != k && _keyReport.keys[5] != k) {

		for (i=0; i<6; i++) {
			if (_keyReport.keys[i] == 0x00) {
				_keyReport.keys[i] = k;
				break;
			}
		}
		if (i == 6) {
			setWriteError();
			return 0;
		}
	}
	sendReport(&_keyReport);
	return 1;
}
//松开按键处理
size_t BleKeyboard::release(uint8_t k)
{
	uint8_t i;
	if (k >= 136) {			// it's a non-printing key (not a modifier)
		k = k - 136;
	} else if (k >= 128) {	// it's a modifier key
		_keyReport.modifiers &= ~(1<<(k-128));
		k = 0;
	} else {				// it's a printing key
		k = pgm_read_byte(_asciimap + k);
		if (!k) {
			return 0;
		}
		if (k & 0x80) {							// it's a capital letter or other character reached with shift
			_keyReport.modifiers &= ~(0x02);	// the left shift modifier
			k &= 0x7F;
		}
	}

	// Test the key report to see if k is present.  Clear it if it exists.
	// Check all positions in case the key is present more than once (which it shouldn't be)
	for (i=0; i<6; i++) {
		if (0 != k && _keyReport.keys[i] == k) {
			_keyReport.keys[i] = 0x00;
		}
	}

	sendReport(&_keyReport);
	return 1;
}
//发送
void BleKeyboard::sendReport(KeyReport* keys)
{
  if (this->isConnected())
  {
    this->inputKeyboard->setValue((uint8_t*)keys, sizeof(KeyReport));
    this->inputKeyboard->notify();
#if defined(USE_NIMBLE)        
    // vTaskDelay(delayTicks);
    this->delay_ms(_delay_ms);
#endif // USE_NIMBLE
  }	
}

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

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

相关文章

媒体软文投放的流程与媒体平台的选择

海内外媒体软文&#xff1a;助力信息传播与品牌建设 在当今数字化时代&#xff0c;企业如何在庞大的信息海洋中脱颖而出&#xff0c;成为品牌建设的领军者&#xff1f;媒体软文投放无疑是一项强大的策略&#xff0c;通过选择合适的平台&#xff0c;精准投放&#xff0c;可以实…

软件推荐目录——按类划分

之前的文章中&#xff0c;博主介绍过诸多实用的软件&#xff0c;今天博主就继续来泛总结一下电脑常用的功能里&#xff0c;有哪些天花板级别存在的软件呢。 1. 浏览器 在之前的文章中&#xff0c;学长已经详细介绍过优秀的浏览器产品&#xff0c;还是同样的套路&#xff1a;外网…

蓝桥杯每日一题2023.11.13

题目描述 蓝桥杯大赛历届真题 - C 语言 B 组 - 蓝桥云课 (lanqiao.cn) 题目分析 由于每次吹灭的蜡烛与年龄相同故我们想到使用前缀和可以让我们求出各个区间的和&#xff0c;我们将每个区间都枚举一遍&#xff0c;如果符合要求就输出区间开始的位置&#xff08;答案&#xff…

专业开源人员的需求仍在增长

Linux 基金会执行总监根据 Dice.com 的一项调查结果表示&#xff1a;「开源正变得越来越专业化&#xff0c;各大公司都在寻求具备这方面技能的专业型人才。」网上有研究分析了两组「2017 年度开源工作调查与报告」&#xff0c;主要分析结果如下&#xff1a; 89% 的招聘人员表示…

机带RAM:16G(可用2G)

文章目录 机带RAM 16G&#xff08;可用2G&#xff09;一 、问题描述二、解决办法2.1 最大内存设置 2.2 系统激活重启 机带RAM 16G&#xff08;可用2G&#xff09; 一 、问题描述 戴尔商务计算机 Windows11系统 16GB内存 之前一直是正常使用的&#xff0c;突然有一天内存占用率…

【杂记】WinServer 2019解决net3.5无法安装问题

1. 问题描述 由于QA环境中的OSCE V16服务端是部署在虚拟机Windows Server 2019上&#xff0c;当进行数据库的迁移操作时&#xff0c;操作系统会提示缺少.NET Framework 3.5组件(SQL Server数据库系统的运行需要依靠.NET Framework 3.5&#xff0c;但是Windows Server2019默认情…

【rl-agents代码学习】01——总体框架

文章目录 rl-agent Get startInstallationUsageMonitoring 具体代码 学习一下rl-agents的项目结构以及代码实现思路。 source: https://github.com/eleurent/rl-agents rl-agent Get start Installation pip install --user githttps://github.com/eleurent/rl-agentsUsage…

第一章:线性查找

系列文章目录 文章目录 系列文章目录前言一、线性查找二、实现查找算法三、循环不变量四、复杂度分析五、常见复杂度六、测试算法性能总结 前言 从线性查找入手算法。 一、线性查找 线性查找目的在线性数据结构中一个一个查找目标元素输入数组和目标元素输出目标元素所在的索…

LCA

定义 最近公共祖先简称 LCA&#xff08;Lowest Common Ancestor&#xff09;。两个节点的最近公共祖先&#xff0c;就是这两个点的公共祖先里面&#xff0c;离根最远的那个。 性质 如果 不为 的祖先并且 不为 的祖先&#xff0c;那么 分别处于 的两棵不同子树中&#…

Clickhouse学习笔记(13)—— Materialize MySQL引擎

该引擎用于监听 binlog 事件&#xff0c;类似于canal、Maxwell等组件 ClickHouse 20.8.2.3 版本新增加了 MaterializeMySQL 的 database 引擎&#xff0c;该 database 能映射到 MySQL中的某个database &#xff0c;并自动在ClickHouse中创建对应ReplacingMergeTree。 ClickHous…

【Python Opencv】图片与视频的操作

文章目录 前言一、opencv图片1.1 读取图像1.2 显示图像1.3 写入图像1.4 示例代码 二、Opencv视频2.1 从相机捕获视频获取摄像头一帧一帧读取显示图片VideoCapture 中的get和set函数示例代码 2.2 从文件播放视频示例代码 2.3 保存视频示例代码 总结 前言 在计算机视觉和图像处理…

As Const:一个被低估的 TypeScript 特性

目录 理解 as const TypeScript的期望与现实 解决方案&#xff1a;as const 与 object.freeze 的比较 一个配合 as const 的更清洁的 go to root 函数 使用 as const 提取对象值 基于Vue3.0的优秀低代码项目 你有没有感觉 TypeScript中可能有一些被低估但却非常有用的工…

解析JSON字符串:属性值为null的时候不被序列化

如果希望属性值为null及不序列化&#xff0c;只序列化不为null的值。 1、测试代码 配置代码&#xff1a; mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 或者通过注解JsonInclude(JsonInclude.Include.NON_NULL) //常见问题2&#xff1a;属性为null&a…

操作系统 | 虚拟机及linux的安装

​ &#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《操作系统实验室》&#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 目录结构 1.操作系统实验之虚拟机及linux的安装 1.1 实验目的 1.2 实验内容 1.3 实验步骤 …

修改django开发环境runserver命令默认的端口

runserver默认8000端口 虽然python manage.py runserver 8080 可以指定端口&#xff0c;但不想每次runserver都添加8080这个参数 可以通过修改manage.py进行修改&#xff0c;只需要加三行&#xff1a; from django.core.management.commands.runserver import Command as Ru…

蓝桥杯 选择排序

选择排序的思想 选择排序的思想和冒泡排序类似&#xff0c;是每次找出最大的然后直接放到右边对应位置&#xff0c;然后将最 右边这个确定下来&#xff08;而不是一个一个地交换过去&#xff09;。 再来确定第二大的&#xff0c;再确定第三大的… 对于数组a[]&#xff0c;具体…

虹科方案 | 汽车电子电气架构设计仿真解决方案

来源&#xff1a;虹科汽车电子 虹科方案 | 汽车电子电气架构设计仿真解决方案 导读 本文将介绍面向服务&#xff08;SOA&#xff09;的汽车TSN网络架构&#xff0c;并探讨RTaW-Pegase仿真与设计软件在TSN网络设计中的应用。通过RTaW将设计问题分解&#xff0c;我们可以更好地理…

低代码、零代码开源与不开源:区别解析

在如今日益发展的数字时代&#xff0c;程序开发变得越来越重要。为了实现日益提高的业务需求&#xff0c;开发人员必须能够以更高效、更灵活的方式构建和交货软件解决方案。低代码和零代码开源是近几年流行的两种开发方法。本文将探讨它们与传统非开源程序开发的差别&#xff0…

javaSE的发展历史以及openjdk和oracleJdk

1 JavaSE 的发展历史 1.1 Java 语言的介绍 SUN 公司在 1991 年成立了一个称为绿色计划&#xff08;Green Project&#xff09;的项目&#xff0c;由 James Gosling&#xff08;高斯林&#xff09;博士领导&#xff0c;绿色计划的目的是开发一种能够在各种消费性电子产品&…

PostGIS学习教程一:PostGIS介绍

一、什么是空间数据库 PostGIS是一个空间数据库&#xff0c;Oracle Spatial和SQL Server(2008和之后版本&#xff09;也是空间数据库。 但是这意味着什么&#xff1f;是什么使普通数据库变成空间数据库&#xff1f; 简短的答案是… 空间数据库像存储和操作数据库中其他任何…