为什么 2091 个 BLE 描述符之一在我的 ESP32 应用程序上没有发挥其价值?

问题描述 投票:0回答:1

我正在使用

ESP32-WROOM-32
开发 BLE 应用程序。

一切都很好,但有一个我无法解决的奇怪行为:我有 5 个特征,其中 4 个是只读的,一个是只写的。每个特征都有一个描述符,其值表示该特征的内容。

如果我为每个特征分配一个描述符,则只写特征无法获得其值

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID_1 "7285ab1e-217e-4595-97a1-85975fe801b3"
#define CHARACTERISTIC_UUID_2 "248386d7-cda1-4ffd-a45b-502a7e709ce9"
#define CHARACTERISTIC_UUID_3 "88ac4be2-45e9-4578-9459-124066251e22"
#define CHARACTERISTIC_UUID_4 "596639c8-d4de-4562-9365-7ee0d5409812"
#define CHARACTERISTIC_UUID_5 "945353c0-b3a4-4946-bab7-85da9c8346e3"

BLECharacteristic *pCharacteristic1, *pCharacteristic2, *pCharacteristic3, *pCharacteristic4, *pCharacteristic5;

class ServerCallbacks : public BLEServerCallbacks
{
  void onConnect(BLEServer *pServer)
  {
    Serial.println(F("Connected"));
  };
  void onDisconnect(BLEServer *pServer)
  {
    Serial.println(F("Disconnected"));
    BLEDevice::startAdvertising();
  }
};

class WriteCharacteristicCallback : public BLECharacteristicCallbacks
{
  void onWrite(BLECharacteristic *pCharacteristic, esp_ble_gatts_cb_param_t *param)
  {
    Serial.print(F("Received data: value is "));
    Serial.println((pCharacteristic->getValue()).c_str());
  }
};

void setup()
{
  Serial.begin(115200);

  Serial.println("\n");
  Serial.println(F("Setup started"));

  BLEDevice::init("TEST Descriptors");

  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new ServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);

  pCharacteristic1 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_1,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic2 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_2,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic3 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_3,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic4 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_4,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic5 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_5,
      BLECharacteristic::PROPERTY_WRITE);

  BLEDescriptor *pCharacteristicDescriptor1 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor2 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor3 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor4 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor5 = new BLEDescriptor("2901");

  pCharacteristicDescriptor1->setValue("CHARACTERISTIC 1");
  pCharacteristic1->addDescriptor(pCharacteristicDescriptor1);

  pCharacteristicDescriptor2->setValue("CHARACTERISTIC 2");
  pCharacteristic2->addDescriptor(pCharacteristicDescriptor2);

  pCharacteristicDescriptor3->setValue("CHARACTERISTIC 3");
  pCharacteristic3->addDescriptor(pCharacteristicDescriptor3);

  pCharacteristicDescriptor4->setValue("CHARACTERISTIC 4");
  pCharacteristic4->addDescriptor(pCharacteristicDescriptor4);

  pCharacteristicDescriptor5->setValue("CHARACTERISTIC 5");
  pCharacteristic5->addDescriptor(pCharacteristicDescriptor5);
  pCharacteristic5->setCallbacks(new WriteCharacteristicCallback());

  pService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  BLEDevice::startAdvertising();

  Serial.println(F("Setup done"));
}

void loop()
{
  delay(5000);
}

如果我删除其中一个描述符,那么一切都会正常工作

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID_1 "7285ab1e-217e-4595-97a1-85975fe801b3"
#define CHARACTERISTIC_UUID_2 "248386d7-cda1-4ffd-a45b-502a7e709ce9"
#define CHARACTERISTIC_UUID_3 "88ac4be2-45e9-4578-9459-124066251e22"
#define CHARACTERISTIC_UUID_4 "596639c8-d4de-4562-9365-7ee0d5409812"
#define CHARACTERISTIC_UUID_5 "945353c0-b3a4-4946-bab7-85da9c8346e3"

BLECharacteristic *pCharacteristic1, *pCharacteristic2, *pCharacteristic3, *pCharacteristic4, *pCharacteristic5;

class ServerCallbacks : public BLEServerCallbacks
{
  void onConnect(BLEServer *pServer)
  {
    Serial.println(F("Connected"));
  };
  void onDisconnect(BLEServer *pServer)
  {
    Serial.println(F("Disconnected"));
    BLEDevice::startAdvertising();
  }
};

class WriteCharacteristicCallback : public BLECharacteristicCallbacks
{
  void onWrite(BLECharacteristic *pCharacteristic, esp_ble_gatts_cb_param_t *param)
  {
    Serial.print(F("Received data: value is "));
    Serial.println((pCharacteristic->getValue()).c_str());
  }
};

void setup()
{
  Serial.begin(115200);

  Serial.println("\n");
  Serial.println(F("Setup started"));

  BLEDevice::init("TEST Descriptors");

  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new ServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);

  pCharacteristic1 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_1,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic2 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_2,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic3 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_3,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic4 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_4,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic5 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_5,
      BLECharacteristic::PROPERTY_WRITE);

  BLEDescriptor *pCharacteristicDescriptor1 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor2 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor3 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor4 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor5 = new BLEDescriptor("2901");

  pCharacteristicDescriptor1->setValue("CHARACTERISTIC 1");
  pCharacteristic1->addDescriptor(pCharacteristicDescriptor1);

  pCharacteristicDescriptor2->setValue("CHARACTERISTIC 2");
  pCharacteristic2->addDescriptor(pCharacteristicDescriptor2);

  pCharacteristicDescriptor3->setValue("CHARACTERISTIC 3");
  pCharacteristic3->addDescriptor(pCharacteristicDescriptor3);

  pCharacteristicDescriptor4->setValue("CHARACTERISTIC 4");
  // pCharacteristic4->addDescriptor(pCharacteristicDescriptor4);

  pCharacteristicDescriptor5->setValue("CHARACTERISTIC 5");
  pCharacteristic5->addDescriptor(pCharacteristicDescriptor5);
  pCharacteristic5->setCallbacks(new WriteCharacteristicCallback());

  pService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  BLEDevice::startAdvertising();

  Serial.println(F("Setup done"));
}

void loop()
{
  delay(5000);
}

如果我将只写特性放在单独的服务上,它就可以工作

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define WRITE_SERVICE_UUID "1f425e27-0174-4591-b081-45732e0d93ad"
#define CHARACTERISTIC_UUID_1 "7285ab1e-217e-4595-97a1-85975fe801b3"
#define CHARACTERISTIC_UUID_2 "248386d7-cda1-4ffd-a45b-502a7e709ce9"
#define CHARACTERISTIC_UUID_3 "88ac4be2-45e9-4578-9459-124066251e22"
#define CHARACTERISTIC_UUID_4 "596639c8-d4de-4562-9365-7ee0d5409812"
#define CHARACTERISTIC_UUID_5 "945353c0-b3a4-4946-bab7-85da9c8346e3"

BLECharacteristic *pCharacteristic1, *pCharacteristic2, *pCharacteristic3, *pCharacteristic4, *pCharacteristic5;

class ServerCallbacks : public BLEServerCallbacks
{
  void onConnect(BLEServer *pServer)
  {
    Serial.println(F("Connected"));
  };
  void onDisconnect(BLEServer *pServer)
  {
    Serial.println(F("Disconnected"));
    BLEDevice::startAdvertising();
  }
};

class WriteCharacteristicCallback : public BLECharacteristicCallbacks
{
  void onWrite(BLECharacteristic *pCharacteristic, esp_ble_gatts_cb_param_t *param)
  {
    Serial.print(F("Received data: value is "));
    Serial.println((pCharacteristic->getValue()).c_str());
  }
};

void setup()
{
  Serial.begin(115200);

  Serial.println("\n");
  Serial.println(F("Setup started"));

  BLEDevice::init("TEST Descriptors");

  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new ServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLEService *pWriteService = pServer->createService(WRITE_SERVICE_UUID);

  pCharacteristic1 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_1,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic2 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_2,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic3 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_3,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic4 = pService->createCharacteristic(
      CHARACTERISTIC_UUID_4,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic5 = pWriteService->createCharacteristic(
      CHARACTERISTIC_UUID_5,
      BLECharacteristic::PROPERTY_WRITE);

  BLEDescriptor *pCharacteristicDescriptor1 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor2 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor3 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor4 = new BLEDescriptor("2901");
  BLEDescriptor *pCharacteristicDescriptor5 = new BLEDescriptor("2901");

  pCharacteristicDescriptor1->setValue("CHARACTERISTIC 1");
  pCharacteristic1->addDescriptor(pCharacteristicDescriptor1);

  pCharacteristicDescriptor2->setValue("CHARACTERISTIC 2");
  pCharacteristic2->addDescriptor(pCharacteristicDescriptor2);

  pCharacteristicDescriptor3->setValue("CHARACTERISTIC 3");
  pCharacteristic3->addDescriptor(pCharacteristicDescriptor3);

  pCharacteristicDescriptor4->setValue("CHARACTERISTIC 4");
  pCharacteristic4->addDescriptor(pCharacteristicDescriptor4);

  pCharacteristicDescriptor5->setValue("CHARACTERISTIC 5");
  pCharacteristic5->addDescriptor(pCharacteristicDescriptor5);
  pCharacteristic5->setCallbacks(new WriteCharacteristicCallback());

  pService->start();
  pWriteService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->addServiceUUID(WRITE_SERVICE_UUID);
  BLEDevice::startAdvertising();

  Serial.println(F("Setup done"));
}

void loop()
{
  delay(5000);
}

这是否意味着每个服务最多可以有 4 个带有值描述符的特征?我听起来真的很奇怪!

esp32 arduino-c++ gatt gatt-descriptors ble-descriptors
1个回答
0
投票

我不知道怎么做,但我找到了问题和解决方案,而且也非常简单明了。

ESP32 根据设计,在 BLEService 默认情况下最多处理 15 个处理程序。但是,可以通过在调用构造函数时指定它来更改处理程序的数量(因为它重载了 2 个构造函数)。

所以而不是做

BLEService *pService = pServer->createService(SERVICE_UUID);

我们只是做

BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID), 20);

还有田田!一切正常! 来自官方文档

一个特征使用 2 个处理程序,而一个描述符使用 1 个

这意味着对于带有描述符的每个特征,我们至少需要 3 个处理程序。如果描述符和/或特征包含数据(例如值),处理程序的数量就会增加,一旦 ESP32 饱和其默认功能,它就会停止添加内容。

我不确定这是否是 C/C++ 限制,但引发的运行时错误肯定有助于识别问题。

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.