BLE_uart example does not create discoverable service when devices are not connected

ahue32
Posts: 16
Joined: Mon Nov 06, 2017 10:09 am

BLE_uart example does not create discoverable service when devices are not connected

Postby ahue32 » Mon Jan 08, 2018 10:27 am

I am trying to connect two Adafruit HUZZAH32 ESP32 boards via bluetooth. Therefore I use the BLE_uart and the BLE_client example. The problem is, that the BLE_client does not find the service of the BLE_uart board. Just to be clear, the address is visible, but not the service UUID. I also tried it with the nRF Connect app, but I can't find a service UUID either.

Code: Select all

/*
    Video: https://www.youtube.com/watch?v=oCMOYS71NIU
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
    Ported to Arduino ESP32 by Evandro Copercini

   Create a BLE server that, once we receive a connection, will send periodic notifications.
   The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
   Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" 
   Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with  "NOTIFY"

   The design of creating the BLE server is:
   1. Create a BLE Server
   2. Create a BLE Service
   3. Create a BLE Characteristic on the Service
   4. Create a BLE Descriptor on the characteristic
   5. Start the service.
   6. Start advertising.

   In this example rxValue is the data received (only accessible inside that function).
   And txValue is the data to be sent, in this example just a byte incremented every second. 
*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
uint8_t txValue = 0;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"


class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++)
          Serial.print(rxValue[i]);

        Serial.println();
        Serial.println("*********");
      }
    }
};


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

  // Create the BLE Device
  BLEDevice::init("UART Service");

  // Create the BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

/*  if(pServer->createService(SERVICE_UUID)){ // I tried this to see if a service would be created. It returned true, but then the it crashed because of double call of createService I guess
    Serial.println("Service created");
  }
  else{
    Serial.println("No service created");
  } */
  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);
  
  
  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_TX,
                      BLECharacteristic::PROPERTY_NOTIFY
                    );
                      
  pCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID_RX,
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service
  pService->start();

  // Start advertising
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void loop() {

  if (deviceConnected) {
    Serial.printf("*** Sent Value: %d ***\n", txValue);
    pCharacteristic->setValue(&txValue, 1);
    pCharacteristic->notify();
    txValue++;
  }
  delay(1000);
}
Output of BLE_uart:

Code: Select all

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11392
entry 0x40078a9c
Waiting a client connection to notify...
Output of BLE_client:

Code: Select all

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371 
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11392
entry 0x40078a9c
Starting Arduino BLE Client application...
BLE Advertised Device found: Name: UART Service, Address: 30:ae:a4:26:37:82, txPower: -21
Does anyone know why I can't find a service and what I should do to make it work?

Edit: I do find the service UUID when I connect the device with my phone via nRF Connect app though, but I would like it to be visible to non connected devices, so I can chose to connect based on the service.
Last edited by ahue32 on Tue Jan 09, 2018 10:31 am, edited 1 time in total.

chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE_uart example does not create discoverable service

Postby chegewara » Mon Jan 08, 2018 5:36 pm

Hi. Could you change logging level to verbose:
Tools->Core debug level->Verbose

ahue32
Posts: 16
Joined: Mon Nov 06, 2017 10:09 am

Re: BLE_uart example does not create discoverable service

Postby ahue32 » Tue Jan 09, 2018 8:23 am

chegewara wrote:Hi. Could you change logging level to verbose:
Tools->Core debug level->Verbose
Verbose output from BLE_uart:

Code: Select all

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11392
entry 0x40078a9c
[D][BLEDevice.cpp:58] createServer(): >> createServer
[D][BLEServer.cpp:297] registerApp(): >> registerApp - 0
[D][BLEDevice.cpp:80] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 3] ... ESP_GATTS_REG_EVT
[D][BLEUtils.cpp:1611] dumpGattServerEvent(): GATT ServerEvent: ESP_GATTS_REG_EVT
[D][BLEUtils.cpp:1755] dumpGattServerEvent(): [status: ESP_GATT_OK, app_id: 0]
[D][BLEServer.cpp:175] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_REG_EVT
[D][BLEServer.cpp:301] registerApp(): << registerApp
[D][BLEDevice.cpp:61] createServer(): << createServer
[D][BLEServer.cpp:287] handleGATTServerEvent(): << handleGATTServerEvent
[D][BLEServer.cpp:76] createService(): >> createService - 6e400001-b5a3-f393-e0a9-e50e24dcca9e
[D][BLEDevice.cpp:80] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 3] ... ESP_GATTS_CREATE_EVT
[D][BLEUtils.cpp:1611] dumpGattServerEvent(): GATT ServerEvent: ESP_GATTS_CREATE_EVT
[D][BLEUtils.cpp:1680] dumpGattServerEvent(): [status: ESP_GATT_OK, service_handle: 40 0x28, service_id: [uuid: 6e400001-b5a3-f393-e0a9-e50e24dcca9e, inst_id: 0]]
[D][BLEServer.cpp:175] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_CREATE_EVT
[D][BLEService.cpp:160] setHandle(): >> setHandle - Handle=0x28, service UUID=6e400001-b5a3-f393-e0a9-e50e24dcca9e)
[D][BLEService.cpp:166] setHandle(): << setHandle
[D][BLEService.cpp:89] executeCreate(): << executeCreate
[D][BLEServer.cpp:93] createService(): << createService
[D][BLEService.cpp:188] addCharacteristic(): >> addCharacteristic()
[D][BLEService.cpp:191] addCharacteristic(): Adding characteristic: uuid=6e400003-b5a3-f393-e0a9-e50e24dcca9e to service: UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e, handle: 0x28
[D][BLEServer.cpp:287] handleGATTServerEvent(): << handleGATTServerEvent
[D][BLEService.cpp:203] addCharacteristic(): << addCharacteristic()
[D][BLECharacteristic.cpp:71] addDescriptor(): >> addDescriptor(): Adding UUID: 00002902-0000-1000-8000-00805f9b34fb, handle: 0xffff to UUID: 6e400003-b5a3-f393-e0a9-e50e24dcca9e, handle: 0xffff Notify 
[D][BLECharacteristic.cpp:73] addDescriptor(): << addDescriptor()
[D][BLEService.cpp:188] addCharacteristic(): >> addCharacteristic()
[D][BLEService.cpp:191] addCharacteristic(): Adding characteristic: uuid=6e400002-b5a3-f393-e0a9-e50e24dcca9e to service: UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e, handle: 0x28
[D][BLEService.cpp:203] addCharacteristic(): << addCharacteristic()
[D][BLECharacteristic.cpp:557] setCallbacks(): >> setCallbacks: 0x3ffdb0bc
[D][BLECharacteristic.cpp:559] setCallbacks(): << setCallbacks
[D][BLEService.cpp:125] start(): >> start(): Starting service (esp_ble_gatts_start_service): UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e, handle: 0x28
[D][BLECharacteristic.cpp:82] executeCreate(): >> executeCreate()
[D][BLECharacteristic.cpp:93] executeCreate(): Registering characteristic (esp_ble_gatts_add_char): uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e, service: UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e, handle: 0x28
[D][BLEDevice.cpp:80] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 3] ... ESP_GATTS_ADD_CHAR_EVT
[D][BLEUtils.cpp:1611] dumpGattServerEvent(): GATT ServerEvent: ESP_GATTS_ADD_CHAR_EVT
[D][BLEUtils.cpp:1633] dumpGattServerEvent(): [status: ESP_GATT_OK, attr_handle: 42 0x2a, service_handle: 40 0x28, char_uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e]
[D][BLEServer.cpp:175] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_ADD_CHAR_EVT
[D][BLECharacteristic.cpp:574] setHandle(): >> setHandle: handle=0x2a, characteristic uuid=6e400003-b5a3-f393-e0a9-e50e24dcca9e
[D][BLECharacteristic.cpp:576] setHandle(): << setHandle
[D][BLEDescriptor.cpp:63] executeCreate(): >> executeCreate(): UUID: 00002902-0000-1000-8000-00805f9b34fb, handle: 0xffff
[D][BLEServer.cpp:287] handleGATTServerEvent(): << handleGATTServerEvent
[D][BLEDevice.cpp:80] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 3] ... ESP_GATTS_ADD_CHAR_DESCR_EVT
[D][BLEUtils.cpp:1611] dumpGattServerEvent(): GATT ServerEvent: ESP_GATTS_ADD_CHAR_DESCR_EVT
[D][BLEUtils.cpp:1621] dumpGattServerEvent(): [status: ESP_GATT_OK, attr_handle: 43 0x2b, service_handle: 40 0x28, char_uuid: 00002902-0000-1000-8000-00805f9b34fb]
[D][BLEServer.cpp:175] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_ADD_CHAR_DESCR_EVT
[D][BLEDescriptor.cpp:275] setHandle(): >> setHandle(0x2b): Setting descriptor handle to be 0x2b
[D][BLEDescriptor.cpp:277] setHandle(): << setHandle()
[D][BLEDescriptor.cpp:87] executeCreate(): << executeCreate
[D][BLECharacteristic.cpp:134] executeCreate(): << executeCreate
[D][BLEServer.cpp:287] handleGATTServerEvent(): << handleGATTServerEvent
[D][BLECharacteristic.cpp:82] executeCreate(): >> executeCreate()
[D][BLECharacteristic.cpp:93] executeCreate(): Registering characteristic (esp_ble_gatts_add_char): uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e, service: UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e, handle: 0x28
[D][BLEDevice.cpp:80] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 3] ... ESP_GATTS_ADD_CHAR_EVT
[D][BLEUtils.cpp:1611] dumpGattServerEvent(): GATT ServerEvent: ESP_GATTS_ADD_CHAR_EVT
[D][BLEUtils.cpp:1633] dumpGattServerEvent(): [status: ESP_GATT_OK, attr_handle: 45 0x2d, service_handle: 40 0x28, char_uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e]
[D][BLEServer.cpp:175] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_ADD_CHAR_EVT
[D][BLECharacteristic.cpp:574] setHandle(): >> setHandle: handle=0x2d, characteristic uuid=6e400002-b5a3-f393-e0a9-e50e24dcca9e
[D][BLECharacteristic.cpp:576] setHandle(): << setHandle
[D][BLECharacteristic.cpp:134] executeCreate(): << executeCreate
[D][BLEServer.cpp:287] handleGATTServerEvent(): << handleGATTServerEvent
[D][BLEDevice.cpp:80] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 3] ... ESP_GATTS_START_EVT
[D][BLEUtils.cpp:1611] dumpGattServerEvent(): GATT ServerEvent: ESP_GATTS_START_EVT
[D][BLEUtils.cpp:1769] dumpGattServerEvent(): [status: ESP_GATT_OK, service_handle: 0x28]
[D][BLEServer.cpp:175] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_START_EVT
[D][BLEService.cpp:151] start(): << start()
[D][BLEAdvertising.cpp:86] start(): >> start
[D][BLEAdvertising.cpp:105] start(): - no services advertised
[D][BLEServer.cpp:287] handleGATTServerEvent(): << handleGATTServerEvent
[D][BLEAdvertising.cpp:137] start(): << start
[D][BLEUtils.cpp:1067] dumpGapEvent(): Received a GAP event: ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
Waiting a client connection to notify...[D][BLEUtils.cpp:1075] dumpGapEvent(): [status: 0]

[D][BLEServer.cpp:134] handleGAPEvent(): BLEServer ... handling GAP event!
[D][BLEUtils.cpp:1067] dumpGapEvent(): Received a GAP event: ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT
[D][BLEUtils.cpp:1261] dumpGapEvent(): [status: 0]
[D][BLEServer.cpp:134] handleGAPEvent(): BLEServer ... handling GAP event!
[D][BLEUtils.cpp:1067] dumpGapEvent(): Received a GAP event: ESP_GAP_BLE_ADV_START_COMPLETE_EVT
[D][BLEUtils.cpp:1099] dumpGapEvent(): [status: 0]
[D][BLEServer.cpp:134] handleGAPEvent(): BLEServer ... handling GAP event!
Do you need the BLE_client as well? I would need to upload it later because there are so many Bluetooth devices around and the log is too long.

chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE_uart example does not create discoverable service when devices are not connected

Postby chegewara » Tue Jan 09, 2018 11:02 am

Im assuming you are trying to use BLE_uart example without any changes and with BLE_client example trying to find and connect to uart server by filtering it with this statement:

Code: Select all

 if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID)) {
also, im assuming you have changed serviceUUID in client code to match serviceUUID from server code:

Code: Select all

static BLEUUID serviceUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
Here we can see that uart server is not advertising any services UUID:
[D][BLEAdvertising.cpp:105] start(): - no services advertised
but here client code is checking if server is advertising services and if its then if advertised service UUID is the one we need:

Code: Select all

if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID)) 
In this case you have one more thing to do. You need to add service UUID to advertising with:

Code: Select all

pServer->getAdvertising()->addServiceUUID(serviceUUID);
before you call this:

Code: Select all

pServer->getAdvertising()->start();

ahue32
Posts: 16
Joined: Mon Nov 06, 2017 10:09 am

Re: BLE_uart example does not create discoverable service when devices are not connected

Postby ahue32 » Tue Jan 09, 2018 11:57 am

chegewara wrote:Im assuming you are trying to use BLE_uart example without any changes and with BLE_client example trying to find and connect to uart server by filtering it with this statement:

Code: Select all

 if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID)) {
also, im assuming you have changed serviceUUID in client code to match serviceUUID from server code:

Code: Select all

static BLEUUID serviceUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
Your assumptions are correct. However, I tried
chegewara wrote: In this case you have one more thing to do. You need to add service UUID to advertising with:

Code: Select all

pServer->getAdvertising()->addServiceUUID(serviceUUID);
before you call this:

Code: Select all

pServer->getAdvertising()->start();
and the log of BLE_uart said

Code: Select all

[D][BLEAdvertising.cpp:98] start(): - advertising service: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
but the `Serial.println(advertisedDevice.toString().c_str());` still returns

Code: Select all

BLE Advertised Device found: Name: UART Service, Address: 30:ae:a4:26:37:82, txPower: -21
I managed to connect both devices though, by hard coding the address of the uart server to the client but that is not what I want.

chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE_uart example does not create discoverable service when devices are not connected

Postby chegewara » Tue Jan 09, 2018 5:15 pm

Can you paste client code please?

chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE_uart example does not create discoverable service when devices are not connected

Postby chegewara » Tue Jan 09, 2018 6:27 pm

I think i know where is the problem. I forgot about one important thing and im sorry for that. UART service is 128 bit UUID and to successfuly advertising 128 bit UUID you need to do some tweaks. Because you have not so much choice with BLE library you need to use short device name during:

Code: Select all

BLEDevice::init("UART")
it cant be longer than 5 characters.

There is workaround if you nee/want to use longer name for your device. You can advertise with server and search with client for 32 bit UUID:

Code: Select all

pServer->getAdvertising()->addServiceUUID(BLEUUID((uint32_t)0x6E400001));

Pros and cons:
- 5 characters can be too few for name, but in most cases its enough
- with 32 bit UUID you still can create own client which can find and connect to it
- with 128 bit UUID advertised some other applications like nRF connect can recognize your esp32 as UART server

ahue32
Posts: 16
Joined: Mon Nov 06, 2017 10:09 am

Re: BLE_uart example does not create discoverable service when devices are not connected

Postby ahue32 » Wed Jan 10, 2018 8:00 am

chegewara wrote:I think i know where is the problem. I forgot about one important thing and im sorry for that. UART service is 128 bit UUID and to successfuly advertising 128 bit UUID you need to do some tweaks. Because you have not so much choice with BLE library you need to use short device name during:

Code: Select all

BLEDevice::init("UART")
it cant be longer than 5 characters.
This works. Thank you so much!! That definitely is something I would never have thought about and I probably would just have given up.

Lambosprit
Posts: 1
Joined: Fri Feb 23, 2018 11:17 pm

Re: BLE_uart example does not create discoverable service when devices are not connected

Postby Lambosprit » Fri Feb 23, 2018 11:25 pm

First post here but this helped me so much with getting the BLE_Client and BLE_Server ino files supplied with N Kolbans ESP32_BLE_Arduino examples working that I thought I'd ask if they could be updated in the git repository to help other people not run into the issue. The BLE_Server uses the name MyESP32 which is too long and it misses the line pServer->getAdvertising()->addServiceUUID(serviceUUID); before the pAdvertising->start();. Once I added those lines and matched up the UUID's in both files the examples worked perfectly together.

Who is online

Users browsing this forum: icyTwist and 40 guests