Board: Sparkfun ESP32 Thing
Core Installation/update date: ?
IDE name: Arduino IDE
Flash Frequency: 80Mhz
Upload Speed: 115200
When trying to create a BLE server I found out there were no pre-defined characteristics that support voltage or current units. I then tried to create a custom characteristic only to find out that it can only support 8 bit int values. Unfortunately, all my values are float and all of them need to be passed on as a number higher than 256 so I can then do the conversion.
For example, when I receive my temperature read I have a value of say 27.28, I then transform it to a uint16_t value of 2728 so I can pass it along to my phone. However, when using NRF connect, it just reads as an hexadecimal value, so I'm assuming that, for custom made characteristics, the default variable type is Hex.
I've tried passing them as strings as such:
std::string myString((char*)&myValue16, 2);
Which didn't work.
I then tried to separate my value into two uint_8 values and place them in a string with 2 positions like this:
tempData[0]=tempBLE;
tempData[1]=tempBLE>>8;
tempCharacteristics.setValue(tempData,2);
It also didn't work although I wasn't expecting it to work either, it would be fine if I used a pre-defined GATT characteristic which isn't the case.
So my question is: how can I pass a value any other than an uint8_t through ble to receive on NRF connect? Do I just need to separate it into two and have an App to get it back together?
Thanks
```cpp
//Change the code below by your sketch
HardwareSerial Serial2(2);
uint8_t i=0, j=0, k=0;
int count=0, cpy_index;
float temp, current, voltage;
uint8_t tempData[2], voltageData[2];
uint16_t tempBLE, voltageBLE;
byte data_buffer[N_BYTES];
std::string my_string;
union{
byte variable_buffer[4];
float value;
}tx_data;
byte flags = 0b00111110;
bool _BLEClientConnected = false;
byte park[8] = { 0b00001110, 60, 0, 0, 0 , 0, 0, 0};
BLECharacteristic tempCharacteristics(tempCharacteristicUUID, BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_READ);
BLECharacteristic voltageCharacteristics(voltageCharacteristicUUID, BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_READ);
//BLEDescriptor tempDescriptor(BLEUUID((uint16_t)0x2901));
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
_BLEClientConnected = true;
};
void onDisconnect(BLEServer* pServer) {
_BLEClientConnected = false;
}
};
void InitBLE() {
BLEDevice::init("My_BLE");
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pPark = pServer->createService(sensingService);
pPark->addCharacteristic(&tempCharacteristics);
pPark->addCharacteristic(&voltageCharacteristics);
//tempCharacteristics.addDescriptor(&tempDescriptor);
tempCharacteristics.addDescriptor(new BLE2902());
voltageCharacteristics.addDescriptor(new BLE2902());
pServer->getAdvertising()->addServiceUUID(sensingService);
pPark->start();
// Start advertising
pServer->getAdvertising()->start();
}
void clear_buffer(){
for(j=0;j
}
}
//passar array como parametro e copiar os dados para la
void copy_data(){ //int k e a posicao
for(k=0;k<4;k++){
tx_data.variable_buffer[k]=data_buffer[k];
}
}
void setup(void)
{
Serial.begin(115200);
Serial2.begin(57600, SERIAL_8N1, 16, 17);
InitBLE();
}
void loop() {
while(Serial2.available()){
data_buffer[i]=Serial2.read();
i++;
if(i>3){
count++;
i=0;
if(count==1){ //if ctrl variable is 1, its a temperature read
copy_data();
current=tx_data.value;
Serial.print("\nCorrente: ");
Serial.print(current);
//tempCharacteristics.setValue(current); //o size tem de estar em bits
//tempCharacteristics.notify();
break;
}
else if(count==2){ //if ctrl variable is 2, its a current read
copy_data();
voltage=tx_data.value;
Serial.print("\nTensao: ");
Serial.print(voltage);
voltageBLE=voltage*100;
//voltageCharacteristics.setValue(voltageBLE);
break;
}
else if(count==3){ //if ctrl variable is 2, its a current read
copy_data();
temp=tx_data.value;
tempBLE=(uint16_t)(temp*100);
Serial.print("\nTemperatura: ");
Serial.print(tempBLE);
tempData[0]=tempBLE;
tempData[1]=tempBLE>>8;
tempCharacteristics.setValue(tempData,2);
tempCharacteristics.notify();
count=0; //colocar count = 0 na ultima leitura para voltar ao inicio sem gastar um ciclo
break;
}
}
}
}
tl;dr. You are looking for sprintf
float test=1.23456;
char testStr[10];
sprintf(testStr,"%4.4f",test);
Yeah no clue why it never occurred to me to use sprintf duh It worked fine with NRF connect, thanks.
A question just popped up though: why did it work with sprintf but it didn't when I tried to pass it to an std::string? Is it because the characteristic can only be read as a char array?
https://github.com/nkolban/ESP32_BLE_Arduino/blob/7951347ed68313d75c367e1f2cce763cb56d1eb2/src/BLECharacteristic.h#L76
setValue is overloaded with a number of different parameter types, but if you put a number in there after the value, it can only be a char*. Header files are there for you, as well as the compiler.
Please close the issue if your problem is solved.
The thing is the problem wasn't in sending the information, I managed to run the setValue function with an std::string parameter just fine, the problem is on the receiving end, NRF connect recognizes only the char array or simple 8 bit integers and I'm trying to understand why it wouldn't regonize any other variable formats.
Very off topic. Please ask at https://github.com/nkolban/esp32-snippets/issues, or NRF's forum.
Allright, thanks for the help!
Most helpful comment
tl;dr. You are looking for sprintf