Passing Uptime Value through BLE to Android

Good afternoon everyone,

Just been experimenting with the Uptime in serial, a nice little library that will save me some time using for-loops.

I'm trying to use the uptime library with BLE, and pass through to n rfConnect on Android the value of the uptime, updating every 1000ms via delay.

My code compiles, but the android value stays at (0x) 00-00-00-00, what am I missing here? I've put comments in the code below.

#include <uptime.h>
#include <uptime_formatter.h>

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

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

//global variable
int uptime = uptime::getSeconds();



class MyCallbacks: public BLECharacteristicCallbacks {
    void onRead(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
 }

};

void setup() {
  Serial.begin(115200);
  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue(uptime); ////EXPECTED BEHAVIOR: update every second on android device as a int, RESULT: value stayed at (0x) 00-00-00-00
    
    pService->start();

    BLEAdvertising *pAdvertising = pServer->getAdvertising();
    pAdvertising->start();


}

void loop() {
 //update the second every 1000ms
  uptime::getSeconds();
  delay(1000);
 }

TIA, Sam

This statement in loop() only gets and throws away the current uptime:

The variables: pServer, pService and pCharacteristic should be global variables. In loop() you must call pCharacteristic->setValue(std::to_string(uptime::getSeconds())); and that should be the end of that.

EDIT: convert long to string, if the string version of setValue() is to be used.

This is returning an unsigned long. You may want to define the characterisitic for that type, or possibly you can use this to send the 4 bytes.

pCharacteristic->setValue((uint8_t*)&uptime::getSeconds(),4);

That's probably not gonna work, but this may:

unsigned long uptime;

setup()
{
  pCharacteristic->setValue((uint8_t*)&uptime, sizeof(uptime));
}

loop()
{
  uptime = uptime::getSeconds();
}

I've tried giving the solution above an attempt, the code compiles but there is no output. Do BLE Characteristics have default declaration types as global variables? Updated code below:

#include <uptime.h>
#include <uptime_formatter.h>

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

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

//global variable
unsigned long uptime;




class MyCallbacks: public BLECharacteristicCallbacks {
    void onRead(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
 }

};

void setup() {
  Serial.begin(115200);
  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue((uint8_t*)&uptime, sizeof(uptime));
    
    pService->start();

    BLEAdvertising *pAdvertising = pServer->getAdvertising();
    pAdvertising->start();


}

void loop() {
 //update the second every 1000ms
   uptime = uptime::getSeconds();
  delay(1000);
 }

You are setting the value as a binary value and reading it out as a string. Set the value as a string (in loop) as described in #3 OR change this part of the code:

void onRead(BLECharacteristic *pCharacteristic) {
  //std::string value = pCharacteristic->getValue(); //Old
  pCharacteristic->setValue(std::to_string(uptime)); //New
 }

As said before, you need to write the new values in loop()

void loop() {
 //update the second every 1000ms
   uptime = uptime::getSeconds();
   pCharacteristic->setValue((uint8_t*)&uptime, sizeof(uptime));
  delay(1000);
 }

nrfConnect will show the four hex bytes being sent.