New user - BLE question

I am new to Arduino, though not to firmware in general.

Trying to get a basic Bluetooth LE project going. Completely new to Bluetooth. At the moment I need a single service, containing a single characteristic containing 10 bytes. As necessary I update the bytes and write the characteristic. This is not a standard profile, the other end will know what to do with the 10 bytes.

Bit confused by the Arduino BLE documentation. The basic BLECharacteristic class constructors are defined as BLECharacteristic(uuid, properties, value, valueSize), and BLECharacteristic(uuid, properties, stringValue). (No data types, I see, perhaps that is normal for Arduino?)

However, trying to use the first one gave a syntax error. Looking through the header files it seems the constructor is actually BLECharacteristic(const char* uuid, uint8_t properties, int valueSize, bool fixedLength = false); - not the same.

So:

  1. Is there better documentation on this anywhere?
  2. In the absence of better documentation, how am I supposed to do this? Am I right is assuming that I should:

Declare the service (create my own GUID)
Declare the characteristic as
BLECharacteristic mycharacteristic("UUUUUUUU-UUUU-UUUU-UUUU-UUUUUUUUUUUU", BLERead | BLENotify, 10, true);
Add the characteristic to the service, and add the service
Advertise

Then as necessary when something is connected
Update the 10 bytes
Write the characteristic using int writeValue(const uint8_t value, int length, bool withResponse = true); (what does 'withResponse' do?)

Any helpful comments appreciated. If all this sounds a bit basic it's because I know nothing about Arduino or BLE at the moment.

thank you

May not be just what you want but check out my example UART codes at
Bluetooth Low Energy (BLE) made simple with pfodApp
If the other side handles Nordic UART then you can just use the bleSerial object to write/read

Thanks, yes, I had wondered about using serial, but felt custom characteristics was closer to the need.

The other end can do whatever I make it do - Android code, an existing app that I need to add BLE support to.

I do find it a bit odd that data types seem to be missing from the documentation, at least these bits. Means I have to go and read the library code. Maybe it's an Arduino thing to keep complexity down?

Welcome to the forum.

Are you using any of the original Arduino with BLE support e.g.

  • Arduino Nano 33 BLE or BLE Sense
  • Arduino Nano 33 IoT
  • Arduino RP2040 Connect

There are specific sub forums for each of these boards with a couple of examples in various posts.

https://forum.arduino.cc/c/hardware/nano-family

Are these 10 bytes a collection of standard data types or an array of bytes. I can modify and post a short example if you let me know.

The ArduinoBLE library reference is here:

https://www.arduino.cc/en/Reference/ArduinoBLE

Thanks for your reply. I'm using the Nano 33 BLE. I had found the documentation, but the forums you point to are useful.

The 10 bytes are not a standard type, they are encoded specifically for my task. I have actually moved on, and successfully created Characteristics (full UUID) for passing the data to and fro, tested with the nRF Android app.

I guess what confused me a lot was that the doc definition for the BLECharacteristic constructor is wrong, and that most examples I found were about using standard profiles. Also that there seems an Arduino desire to not document data types, so I end up reading the header files to find the details. I guess they are trying to hide complexity, but as a long time embedded designer I find that unhelpful - only my personal opinion, of course.

My task is not complex, and I'm just looking to soak up all the Information I can find on practical implementation of BLE. Some of it seems odd to me and leaves questions in my mind and I never like that!

For instance the BLECharacteristic() constructor takes a parameter n bytes and a fixed length flag. Why specify the n bytes if it is not fixed length? What happens if more (or less) than n bytes are written to a non-fixed length characteristic? How big can n be? Etc etc. Just lack of knowledge on my part.

I agree, I would like to see more documentation with data types. For some cases there are hints about the data type e.g., when it is likely to cause issues.
Arduino is mostly not for embedded developers but allows people with little knowledge of electronics to play with some complicated stuff.

In BLELocalCharacteristic.cpp you can find the following line:

  _valueSize(min(valueSize, 512)),

So, I guess the answer is 512 bytes.

In the same file, function write():

  _valueLength = min(length, _valueSize);
  memcpy(_value, value, _valueLength);

The write will be limited to the valueSize set before.

In the next line of code:

if (_fixedLength) {
    _valueLength = _valueSize;
  }
...
return ATT.handleInd(valueHandle(), _value, _valueLength);

Maybe fixed length is supposed to ensure that if you do not write enough bytes the rest of the bytes are filled or something. You would have to check what happens next in ATT.handle ...

Thanks for looking all that up, saved me from doing it!

I guess you are right on the target audience.

I'm only using it as it was a quick way of getting a processor on a board with Bluetooth hardware and - most importantly - the Bluetooth stack, which, from the code size, appears to be huge.

Working quite well, though, so far. The approach I'm aiming to take is just to use the one .INO with setup() and loop() in it and then write the rest in C/C++. I assume that'll work. I see there are a few C++ restrictions - no new and delete (no heap, I guess), no templates or exception handling, but that's OK.

Astonishingly slow to build the project for some reason, need to look into that. Some seem to think it's an AV interaction with the IDE.

That is mostly mbedOS source code as I understand. As long as you keep the IDE open, only the first compile will be a bit slow. After that the compilation should be faster using many of the previously compiled files.
This has been a lot worse in the beginning when this board was new. The Arduino team improved this quite a bit.

Yes, I noticed about the first compile.