Dear, I m working app with bluetooth BLE where I need too send a long string with these arguments
serviceUuid (text) — The unique identifier of the service passed in the read or register call.
characteristicUuid (text) — The unique identifier of the characteristic in the read or register call.
utf16 (boolean) Send the string encoded as UTF-16 little endian (true) or UTF-8 (false) code points.
values (list) — A list of values to write to the device.
And this is what I get on the other end
void onWrite(BLECharacteristic* pCharacteristic) {
std::string value = pCharacteristic->getValue();
Serial.println(pCharacteristic->getValue().c_str());
The problem is when I print it... I not getting the whole string.
Soo what I have to do is use a loop and convert/print each byte from the .data() method of std::string.
But I cannot get it to work. Correct me if I am wrong... I have too convert the "String value" from the std:: string methode (Question: Do I not lose the rest of my string) and put it in a byte array and than somehow convert it to a readable string. Soo I went form UTF-8 string -> Bytes -> ASCII string I believe.
Can anybody help me too get started with this. It would be very much appreaciated.
Are there any null characters in the characteristic value? (When sending UTF-16, there definitely can be null bytes, and if the boolean utf16 flag is zero, that's a null byte too.)
If so, there are two places where it will go wrong: the std::string constructor you're using copies its value from a C-string, so it stops reading as soon as it encounters the first null byte. To include any null characters, use the constructor that takes a pointer to the string and the number of characters:
std::string value { pCharacteristic->getValue(), pCharacteristic->valueLength() };
Similarly, Serial.println() also stops after the first null byte. This is a sensible thing to do, since (IIRC) the serial monitor uses UTF-8 and doesn't expect null. If you want to send all characters, including null, you can use
Serial.write(value.c_str(), value.size());
For dealing with UTF-16, you probably want to use std::u16string, not std::string.
Other than that, you'll have to post a minimum example, leave out the BLE stuff, instead of using pCharacteristic.getValue(), store one of your packets in a character array.
Are you using an ESP32? I assumed the official ArduinoBLE library (ArduinoBLE - Arduino Reference). That shouldn't really matter though, as long as you have a way to determine the actual number of bytes stored in pCharacteristic->getValue().
You can easily check that the string constructor I referred to works correctly even if the data contains null bytes: Compiler Explorer
You'll have to be more specific than “nothing's coming out”. Please post a minimal example and including the data you're testing with.
Initially BLE was limited to 20bytes per msg. This has been increased now in the later specs but not sure what is supported by the code library you are using.
utf8 excludes nulls and so is my preferred encoding. Suggest you translate your utf16 to utf8 for transmission.
This project Arduino NANO 33 Made Easy sets up a serial UART stream connection that lets you send long strings of data while respecting a 20byte msg limit. I regularly use it to send 1Kb utf8 text strings.
The pfodParser code I use for handling menus is just tacked on top of the UART stream and can be readily omitted.
The project sets up a BLE/Wifi bridge which may be of interest.
The sizeof operator returns the number of bytes the object representation of a class requires, it has nothing to do with the number of characters stored in a string. You need std::string::size().
It's been a while since I've used BLE on ESP32, but IIRC, the default MTU is 23 bytes, which allows for 20 bytes of actual payload. I don't recall how to increase the MTU or how to enable long reads/writes. In fact, I don't even know if it's possible using the BLE library from the ESP32 Arduino Core, I seem to recall this was one of the limitations that caused me to switch to the native Espressif C API for BLE.
I have found out there is a way to do that by define custom callbacks and characteristics. So I could recieve the whole package and then decode it. If I am doing that this topic has no use anymore. So I will close it.
It’s been a while since I’ve used BLE on ESP32, but IIRC, the default MTU is 23 bytes, which allows for 20 bytes of actual payload. I don’t recall how to increase the MTU or how to enable long reads/writes. In fact, I don’t even know if it’s possible using the BLE library from the ESP32 Arduino Core, I seem to recall this was one of the limitations that caused me to switch to the native Espressif C API for BLE.