BLE server for Battery Service application

Aswinth
Posts: 3
Joined: Thu Oct 11, 2018 7:51 am

BLE server for Battery Service application

Postby Aswinth » Thu Oct 11, 2018 8:26 am

Hi,
I am using Arduino to program ESP32.

I am very new to BLE but have been working with Arduino for a long time. My knowledge on BLE is limited to https://www.youtube.com/watch?v=2mePPqiocUE this video.

My idea here is to program the ESP32 as a server which uses GAT services to display the battery level on my phone (client) when the bluetooth connection is paired. I am partially successful with the below code

Code: Select all

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

byte percentage = byte(62);
byte level[1] = {percentage};

bool _BLEClientConnected = false;

#define BatteryService BLEUUID((uint16_t)0x180F)
BLECharacteristic BatteryLevelCharacteristic(BLEUUID((uint16_t)0x2A19), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor BatteryLevelDescriptor(BLEUUID((uint16_t)0x2901));

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

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


void InitBLE() {
  BLEDevice::init("BLE Battery");
  // Create the BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pBattery = pServer->createService(BatteryService);

  pBattery->addCharacteristic(&BatteryLevelCharacteristic);
  BatteryLevelDescriptor.setValue("Percentage 0 - 100");
  BatteryLevelCharacteristic.addDescriptor(&BatteryLevelDescriptor);
  BatteryLevelCharacteristic.addDescriptor(new BLE2902());

  pServer->getAdvertising()->addServiceUUID(BatteryService);

  pBattery->start();
  // Start advertising
  pServer->getAdvertising()->start();
}

void setup() {
  Serial.begin(115200);
  Serial.println("Battery Level Indicator - BLE");
  InitBLE();
}

void loop() {

  BatteryLevelCharacteristic.setValue(level, 1);
  BatteryLevelCharacteristic.notify();
  delay(2000);
  
  percentage++;
  level[1] = (byte)percentage;
  Serial.println(level[1]);

}
In the above code I have hard coded the battery percentage to be 62% and then increment the value for every 2 seconds. I expected the program to display the battery level on the status bar of my phone just like my bluetooth headphones but it did not happen.

I am using nRF mobile application to monitor the BLE server and there I am able to receive the data that was initialized, I am not getting it to update for every 2 sec, it stays at 62% as shown below.

Image

I am also a bit confused on the characteristic function Read and Notify. What does it mean why is notify optional? Also since we are writing the battery level from server to client should it not be write instead of Read?

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

Re: BLE server for Battery Service application

Postby chegewara » Thu Oct 11, 2018 12:31 pm

For battery service i prefer to add those descriptors:
https://github.com/nkolban/esp32-snippe ... pp#L38-L45

It allows me to send value from 0-100 and client like nRF connect take cares how to parse it.

I dont know exactly what you want to achieve, but basically battery level service and characteristic are to inform client device (in most case its client, in your case smartphone) what battery level i on peripheral peer device (again, in most case usage its GATT server, in your case esp32). In such case you will use notifications to send value depend how you program esp32, every constant time period or when battery level is changed, many options. In addition you have read permission on characteristic. This means you can read value on demand, but you have to implement characteristic callback with onRead function.

Aswinth
Posts: 3
Joined: Thu Oct 11, 2018 7:51 am

Re: BLE server for Battery Service application

Postby Aswinth » Thu Oct 11, 2018 12:49 pm

Hi,
Thanks for your reply.

I am trying to achieve something like this Image.

Why do we need to add HID service for this?

Code: Select all

void loop() {

  BatteryLevelCharacteristic.setValue(level, 1);
  BatteryLevelCharacteristic.notify();
  delay(2000);
  
  percentage++;
  level[1] = (byte)percentage;
  Serial.println(level[1]);

}
As far as my understanding goes, the above code should update the battery value in my nRF application, can you please tell me why it is not happening?

Who is online

Users browsing this forum: No registered users and 74 guests