BLETypeCharacteristic Byte characteristic

Hi all,

I'm using the library BLEPeripheral.h and an nRF52-DK for sending data from sensors to an app.
I want to send the data by byte packages. I manage to do it with 4 bytes as the characteristic type is set as INT.
The problem is if I want to send more bytes (as int has only 4 bytes).
My code (not all):

#define bytes_to_u32(a,b,c,d) (((unsigned int) ((unsigned char) a)) & 255)<<24 | (((unsigned char) b)&255)<<16 | (((unsigned char) c)&255) <<8 | (((unsigned char) d)&255) 

BLEService wifiIP_service = BLEService("faa0");
BLEUnsignedIntCharacteristic wifiIP1_Char("faa1", BLERead  | BLENotify | BLEWrite);
BLEDescriptor wifiIP1_Descriptor = BLEDescriptor("2901", "IP");

and the function for this:

byte dataArray[4];
void WIFI(){
// RECEIVE IP ADDRESS
  Wire.requestFrom(106, 4);    // request 6 bytes from slave device #8
  
  while (Wire.available()) {

    for(int i=0; i<4; i++){
       dataArray[i] = Wire.read();
    }

  uint32_t ip = bytes_to_u32(dataArray[0],dataArray[1],dataArray[2],dataArray[3]);

  wifiIP1_Char.setValue(ip);

    delay(500);
  }
}

In this example it works because I have only 4 values, but I have other characteristics with 6 values.

instead of using a BLEUnsignedIntCharacteristic which sets the size to an unsigned int as you noticed, you should create your own characteristic for the service using

BLECharacteristic(uuid, properties, value, valueSize); // https://www.arduino.cc/reference/en/libraries/arduinoble/blecharacteristic/

(the value is seen as a string)

I'm trying but I don't know how to declare it.
What would be the equivalent to BLEUnsignedLongCharacteristic wifiIP1_Char("faa1", BLERead | BLENotify | BLEWrite);?
Any example?

Sorry I just (stupidly) copied/paste the doc and it is wrong, you don't pass the value at that time, only its size

This is documented in the code for the constructor

  BLECharacteristic(const char* uuid, uint8_t properties, int valueSize, bool fixedLength = false);

So for your case that would be

BLECharacteristic wifiIP1_Char("faa1", BLERead | BLENotify | BLEWrite, 6, true); // 6 bytes, fixed length

if you read the code, you'll see they actually use those parameters to instantiate a BLELocalCharacteristic

BLECharacteristic::BLECharacteristic(const char* uuid, uint8_t properties, int valueSize, bool fixedLength) :
  BLECharacteristic(new BLELocalCharacteristic(uuid, properties, valueSize, fixedLength))
{}

and this is where the memory buffer is dynamically allocated on the heap, matching the size of your valueSize

  _value = (uint8_t*)malloc(valueSize);

When you ask for the value, you get a pointer (uint8_t* ) to that buffer. (see ArduinoBLE/BLECharacteristic.cpp at 4c149a206c3e36c909cbb6a9c6032940fc806a88 · arduino-libraries/ArduinoBLE · GitHub)

The problem is that this is the library ArduinoBLE which is a bit different from BLEPeripheral, I tried to use ArduinoBLE with no luck.

do you have a link to that library?

Maybe I just need to check for another library or another way to do this.

it seems very close to the other one.

have you tried

BLECharacteristic wifiIP1_Char("faa1", BLERead | BLENotify | BLEWrite, 6, true); // 6 bytes, fixed length

does it compile?

I tried but I have these errors:

no instance of constructor "BLECharacteristic::BLECharacteristic" matches the argument list`
no matching function for call to 'BLECharacteristic::BLECharacteristic(const char [5], int, int, bool)'

And then if I try to set the value with: wifiIP1_Char.setValue(ip); I have:

no instance of overloaded function "BLECharacteristic::setValue" matches the argument list

drop the true at the end

BLECharacteristic wifiIP1_Char("faa1", BLERead | BLENotify | BLEWrite, 6);

for the second one you want to pass an array and the size

unsigned char ip[6] =  "HELLO"; // for testing purpose
wifiIP1_Char.setValue(ip, 6);
1 Like

It works! With some changes. In my case it would be:

BLECharacteristic wifiIP1_Char("faa1", BLERead | BLENotify | BLEWrite, 4);
char IP[4] ={dataArray[0],dataArray[1],dataArray[2],dataArray[3]};
wifiIP1_Char.setValue(IP);

Not sure if I can use unsigned char, but I don't really need it.
Thank you!

Glad you got it to work

(the function setValue expects unsigned char so you should provide this for type coherence and an IP only has numbers between 0 and 255 so you don't want a signed char - which some compilers could give you)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.