Everything but the data

I have modified the following BLE code (originally by Rui Santos) to work for temperature, humidity, and pressure when communicating with an app. The serial monitor prints flawlessly every 30 seconds after I connect with my Light Blue app. The app shows the three attributes but there is no data and the app says: “Properties: Notify” for Temperature, pressure, and Humidity.

Also, when I use nRF Connect, I receive the message “Characteristic (UUID Code) has no Descriptors.” and I do not even see the attribute names. Can someone advise me on what I am missing? I get that I am probably neglecting a line (or three) of code but I have spun my wheels for quite some time with no solution in sight. Thank you in advance for any ideas.

/*********
  Rui Santos
  Complete instructions at https://RandomNerdTutorials.com/esp32-ble-server-client/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

//Default Temperature is in Celsius
//Comment the next line for Temperature in Fahrenheit
#define temperatureCelsius

//BLE server name
#define bleServerName "BME280 Meter"

Adafruit_BME280 bme; // I2C

float temp;
float pres;
float hum;

// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;

bool deviceConnected = false;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "49cad492-b950-4226-aa2b-4ede9fa42f59"

// Temperature Characteristic and Descriptor

  BLECharacteristic bmeTemperatureCharacteristics("49cad492-b950-4226-ab2b-4ede9fa42f59", BLECharacteristic::PROPERTY_NOTIFY);
  BLEDescriptor bmeTemperatureDescriptor(BLEUUID((uint16_t)0x2901));


//  Atmospheric Pressure Characteristic and Description
  BLECharacteristic bmeAtmosphericPressureCharacteristics("49cad492-b950-4226-ac2b-4ede9fa42f59", BLECharacteristic::PROPERTY_NOTIFY);
  BLEDescriptor bmeAtmosphericPressureDescriptor(BLEUUID((uint16_t)0x2901));


// Humidity Characteristic and Descriptor
BLECharacteristic bmeHumidityCharacteristics("49cad492-b950-4226-ad2b-4ede9fa42f59", BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor bmeHumidityDescriptor(BLEUUID((uint16_t)0x2901)); 

//Setup callbacks onConnect and onDisconnect
class MyServerCallbacks: public BLEServerCallbacks {
  void onConnect(BLEServer* pServer) {
    deviceConnected = true;
  };
  void onDisconnect(BLEServer* pServer) {
    deviceConnected = false;
  }
};

void initBME(){
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

void setup() {
  // Start serial communication 
  Serial.begin(115200);

  // Init BME Sensor
  initBME();

  // Create the BLE Device
  BLEDevice::init(bleServerName);

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

  // Create the BLE Service
  BLEService *bmeService = pServer->createService(SERVICE_UUID);

  // Create BLE Characteristics and Create a BLE Descriptor
  // Temperature
    bmeService->addCharacteristic(&bmeTemperatureCharacteristics);
    bmeTemperatureDescriptor.setValue("Temperature");
    bmeTemperatureCharacteristics.addDescriptor(&bmeTemperatureDescriptor);
 
  // Pressure
    bmeService->addCharacteristic(&bmeAtmosphericPressureCharacteristics);
    bmeAtmosphericPressureDescriptor.setValue("Pressure");
    bmeAtmosphericPressureCharacteristics.addDescriptor(&bmeAtmosphericPressureDescriptor);
 
  // Humidity
  bmeService->addCharacteristic(&bmeHumidityCharacteristics);
  bmeHumidityDescriptor.setValue("Humidity");
  bmeHumidityCharacteristics.addDescriptor(&bmeHumidityDescriptor);
  
  // Start the service
  bmeService->start();

  // Start advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void loop() {
  if (deviceConnected) {
    if ((millis() - lastTime) > timerDelay) {
      // Read temperature as Celsius (the default)
      temp = bme.readTemperature();
      pres = bme.readPressure();
      hum = bme.readHumidity();
  
      //Notify temperature reading from BME sensor
     
        static char temperatureCTemp[6];
        dtostrf(temp, 6, 2, temperatureCTemp);
        //Set temperature Characteristic value and notify connected client
        bmeTemperatureCharacteristics.setValue(temperatureCTemp);
        bmeTemperatureCharacteristics.notify();
        Serial.print("      Temperature Celsius: ");
        Serial.print(temp);
        Serial.print(" ºC");
      
        static char AtmosphericPressure[6];
        dtostrf(pres, 6, 2, AtmosphericPressure);
        //Set atmospheric pressure Characteristic value and notify connected client
        bmeAtmosphericPressureCharacteristics.setValue(AtmosphericPressure);
        bmeAtmosphericPressureCharacteristics.notify();
        Serial.print("        Atmospheric Pressure: ");
        Serial.print(pres);
        Serial.print(" KPa");
    
      
      //Notify humidity reading from BME
      static char humidityTemp[6];
      dtostrf(hum, 6, 2, humidityTemp);
      //Set humidity Characteristic value and notify connected client
      bmeHumidityCharacteristics.setValue(humidityTemp);
      bmeHumidityCharacteristics.notify();   
      Serial.print("      Humidity: ");
      Serial.print(hum);
      Serial.println(" %");
      
      lastTime = millis();
    }
  }
}

Hi there,
So NO DATA… Well pretty sure you can’t read those from the sensor like that?
Can you print the TEMp, HUM & Pressure to the screen?
Or put some known values in the setValue char and see if it’s passed it will, I think.
You need to put a 1000ms/ in between the reads of each Sensor. The BLE portion is fine, The descriptor is what units it represents, the value is of. ie. battery percentage % if that makes sense.

     temp = bme.readTemperature();
   delay(1000);
     pres = bme.readPressure();
    delay(1000); 
 hum = bme.readHumidity();
:-p

My .02
HTH
GL :slight_smile: PJ

I made some changes in several places. Try this.
Please use “esp32 by Espressif 2.0.11” for BSP. 3.0.0-alpha3 does not work.

/*********
  Rui Santos
  Complete instructions at https://RandomNerdTutorials.com/esp32-ble-server-client/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

//Default Temperature is in Celsius
//Comment the next line for Temperature in Fahrenheit
#define temperatureCelsius

//BLE server name
#define bleServerName "BME280 Meter"

Adafruit_BME280 bme; // I2C

float temp;
float pres;
float hum;

// Timer variables
unsigned long lastTime = 0;
//unsigned long timerDelay =30000;
unsigned long timerDelay =1000;

static bool deviceConnected = false;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "49cad492-b950-4226-aa2b-4ede9fa42f59"

// Temperature Characteristic and Descriptor
  BLECharacteristic bmeTemperatureCharacteristics("49cad492-0001-4226-ab2b-4ede9fa42f59", BLECharacteristic::PROPERTY_NOTIFY);
  BLEDescriptor bmeTemperatureDescriptor(BLEUUID((uint16_t)0x2901));


//  Atmospheric Pressure Characteristic and Description
  BLECharacteristic bmeAtmosphericPressureCharacteristics("49cad492-0002-4226-ac2b-4ede9fa42f59", BLECharacteristic::PROPERTY_NOTIFY);
  BLEDescriptor bmeAtmosphericPressureDescriptor(BLEUUID((uint16_t)0x2901));


// Humidity Characteristic and Descriptor
  BLECharacteristic bmeHumidityCharacteristics("49cad492-0003-4226-ad2b-4ede9fa42f59", BLECharacteristic::PROPERTY_NOTIFY);
  BLEDescriptor bmeHumidityDescriptor(BLEUUID((uint16_t)0x2901)); 

//Setup callbacks onConnect and onDisconnect
class MyServerCallbacks: public BLEServerCallbacks {
  void onConnect(BLEServer* pServer) {
    deviceConnected = true;
    Serial.print("Connected "); Serial.println(deviceConnected);
  };
  void onDisconnect(BLEServer* pServer) {
    deviceConnected = false;
    Serial.print("Disconnected "); Serial.println(deviceConnected);
  }
};

void initBME(){
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

void setup() {
  // Start serial communication 
  Serial.begin(115200);

  // Init BME Sensor
  initBME();

  // Create the BLE Device
  BLEDevice::init(bleServerName);

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

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);  

  // Create BLE Characteristics and Create a BLE Descriptor
  // Temperature
//    bmeService->addCharacteristic(&bmeTemperatureCharacteristics);
    pService->addCharacteristic(&bmeTemperatureCharacteristics);    
    bmeTemperatureDescriptor.setValue("Temperature");
    bmeTemperatureCharacteristics.addDescriptor(&bmeTemperatureDescriptor);
 
  // Pressure
//    bmeService->addCharacteristic(&bmeAtmosphericPressureCharacteristics);
    pService->addCharacteristic(&bmeAtmosphericPressureCharacteristics);    
    bmeAtmosphericPressureDescriptor.setValue("Pressure");
    bmeAtmosphericPressureCharacteristics.addDescriptor(&bmeAtmosphericPressureDescriptor);
 
  // Humidity
//    bmeService->addCharacteristic(&bmeHumidityCharacteristics);
    pService->addCharacteristic(&bmeHumidityCharacteristics);    
    bmeHumidityDescriptor.setValue("Humidity");
    bmeHumidityCharacteristics.addDescriptor(&bmeHumidityDescriptor);
  
  // Start the service
//  bmeService->start();
  pService->start();  

  // Start advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void loop() {
  if (deviceConnected) {    
    if ((millis() - lastTime) > timerDelay) {
      //Read temperature as Celsius (the default)
      temp = bme.readTemperature();
      pres = bme.readPressure();
      hum = bme.readHumidity();
  
      //Notify temperature reading from BME sensor     
        static char temperatureCTemp[6];
        dtostrf(temp, 6, 2, temperatureCTemp);
      //Set temperature Characteristic value and notify connected client
        bmeTemperatureCharacteristics.setValue(temperatureCTemp);
        bmeTemperatureCharacteristics.notify();
        Serial.print("      Temperature Celsius: ");
        Serial.print(temp);
        Serial.print(" ºC");
      
        static char AtmosphericPressure[6];
        dtostrf(pres, 6, 2, AtmosphericPressure);
        //Set atmospheric pressure Characteristic value and notify connected client
        bmeAtmosphericPressureCharacteristics.setValue(AtmosphericPressure);
        bmeAtmosphericPressureCharacteristics.notify();
        Serial.print("        Atmospheric Pressure: ");
        Serial.print(pres);
        Serial.print(" KPa");    
      
      //Notify humidity reading from BME
      static char humidityTemp[6];
      dtostrf(hum, 6, 2, humidityTemp);
      //Set humidity Characteristic value and notify connected client
      bmeHumidityCharacteristics.setValue(humidityTemp);
      bmeHumidityCharacteristics.notify();   
      Serial.print("      Humidity: ");
      Serial.print(hum);
      Serial.println(" %");
      
      lastTime = millis();      
    }
  }
}

OK, here is code that works perfectly with nRF Connect (see the markup below). All I have to do is translate the hex to integer and active the readout in nRF Connect. Can someone please (gently) explain how my sketch works perfectly using UUID shortcuts (like 0x181A for environmental sensing) but the example submitted by MS Fugino (Gawd, I hope I interpreted that handle correctly;) which has full-length UUIDs works in the serial monitor, and is discovered by nRF Connect, will not allow me to select the individual streams of data for viewing ) please see attached image of my nRF Connect screen for more detail).

My current goal is to display data in nRF Connect as the following sketch will do but do so with my own UUIDs. Thank you, again, to PJ and msfugino for all your help to date!

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-ble-server-environmental-sensing-service/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. 
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/

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

//BLE server name
#define bleServerName "Finally Working"

// Default UUID for Environmental Sensing Service
// https://www.bluetooth.com/specifications/assigned-numbers/
#define SERVICE_UUID (BLEUUID((uint16_t)0x181A))    //  Environmental Sensing Service shortcut

// Temperature Characteristic and Descriptor (default UUID)
// Check the default UUIDs here: https://www.bluetooth.com/specifications/assigned-numbers/
BLECharacteristic temperatureCharacteristic(BLEUUID((uint16_t)0x2A6E), BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor temperatureDescriptor(BLEUUID((uint16_t)0x2902));

// Humidity Characteristic and Descriptor (default UUID)
BLECharacteristic humidityCharacteristic(BLEUUID((uint16_t)0x2A6F), BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor humidityDescriptor(BLEUUID((uint16_t)0x2902));

// Pressure Characteristic and Descriptor (default UUID)
BLECharacteristic pressureCharacteristic(BLEUUID((uint16_t)0x2A6D), BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor pressureDescriptor(BLEUUID((uint16_t)0x2902));

// Create a sensor object
Adafruit_BME280 bme;

// Init BME280
void initBME(){
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

bool deviceConnected = false;

//Setup callbacks onConnect and onDisconnect
class MyServerCallbacks: public BLEServerCallbacks {
  void onConnect(BLEServer* pServer) {
    deviceConnected = true;
    Serial.println("Device Connected");
  };
  void onDisconnect(BLEServer* pServer) {
    deviceConnected = false;
    Serial.println("Device Disconnected");
  }
};

void setup() {
  // Start serial communication 
  Serial.begin(115200);

  // Start BME sensor
  initBME();

  // Create the BLE Device
  BLEDevice::init(bleServerName);

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

  // Create the BLE Service
  BLEService *bmeService = pServer->createService(SERVICE_UUID);

  // Create BLE Characteristics and corresponding Descriptors
  bmeService->addCharacteristic(&temperatureCharacteristic);
  temperatureCharacteristic.addDescriptor(&temperatureDescriptor);
  
  bmeService->addCharacteristic(&humidityCharacteristic);
  humidityCharacteristic.addDescriptor(&humidityDescriptor);

  bmeService->addCharacteristic(&pressureCharacteristic);
  pressureCharacteristic.addDescriptor(&pressureDescriptor);
  
  // Start the service
  bmeService->start();

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

void loop() {
  if (deviceConnected) {
    // Read temperature as Celsius (the default)
    float t = bme.readTemperature();
    // Read humidity
    float h = bme.readHumidity();
    // Read pressure
    float p = bme.readPressure()/100.0F;
    
    //Notify temperature reading
    uint16_t temperature = (uint16_t)t;
    //Set temperature Characteristic value and notify connected client
    temperatureCharacteristic.setValue(temperature);
    temperatureCharacteristic.notify();
    Serial.print("Temperature Celsius: ");
    Serial.print(t);
    Serial.println(" ºC");
   
    //Notify humidity reading
    uint16_t humidity = (uint16_t)h;
    //Set humidity Characteristic value and notify connected client
    humidityCharacteristic.setValue(humidity);
    humidityCharacteristic.notify();   
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.println(" %");

    //Notify pressure reading
    uint16_t pressure = (uint16_t)p;
    //Set humidity Characteristic value and notify connected client
    pressureCharacteristic.setValue(pressure);
    pressureCharacteristic.notify();   
    Serial.print("Pressure: ");
    Serial.print(p);
    Serial.println(" hPa");
    
    delay(10000);
  }
}