ESP32 BLE特征值示例

键盘特征值初始化示例

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
  }	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值