i am using a Nano 33 iot as a BLE peripheral, with two characteristics
BLEByteCharacteristic byte, write only, , works fine
BLEStringCharacteristic, read and write, write works fine
but READ has a problem, and I don't know why
I HAD the event handler pretty simple
void configCharacteristicRead(BLEDevice central, BLECharacteristic characteristic){
Serial.print("config string characteristic read, length=");
String x = JSON.stringify(configInfo);
Serial.println(x.length());
characteristic.writeValue(x.c_str());
Serial.println("done writing config info");
}
configInfo is a global JSONVar variable.
this has worked fine for the last month or so, I do see multiple calls to the event handler for each read from the central app. (both android and ios) app store ble scanners
now for some reason read doesn't return anything..
the string is 110 chars, and could grow to 160, depending on the data in the JSON object.
these are a set of values that would be set all at the same time. thus the json string.
I see that the max transfer is 512 octets. and the mtu size is typically 23 (data size = 20 bytes)
the write event handler gets called multiple times, and the data is 20bytes(ish) each time and i can accumulate them and get the right result..
the read handler gets called 5 times.. the data is 110 .. that doesn't work out
there isn't a sequence number in the characteristic at eventhandler time. so I don't know which piece is being asked for.
I tested with data length at 129 chars, and still only got 5 calls to the read eventhandler. still doesnt work out.. 110/20 or 129/20 both should be asking for 20 bytes each time or the remainder .. the characteristic valueLength() is the size at characteristic creation time.
part of routine that creates service and characteristics.
// convert config object to string
String jsonString = JSON.stringify(configInfo);
Serial.print("config length=");
Serial.println(jsonString.length());
// create the characteristic , use the length of the current
// this WILL be a problem later as the write will change the size
// so we will have to delete this service and rebuild it with the current length
// might only change 2-3 times in the devices lifetime (2+ years)
configCharacteristic = new BLEStringCharacteristic("9AFF", BLERead|BLEWrite, jsonString.length());
configCharacteristic->setEventHandler(BLERead, configCharacteristicRead);
configCharacteristic->setValue(jsonString);
configCharacteristic->setEventHandler(BLEWrite, configCharacteristicWrite);
// add the characteristics to the service
ourService->addCharacteristic(*configCharacteristic);
this is the serial output of the read event handler
12:48:19.169 -> config string characteristic read, size=110
12:48:19.169 -> done writing config info
12:48:19.269 -> config string characteristic read, size=110
12:48:19.269 -> done writing config info
12:48:19.368 -> config string characteristic read, size=110
12:48:19.368 -> done writing config info
12:48:19.466 -> config string characteristic read, size=110
12:48:19.466 -> done writing config info
12:48:19.565 -> config string characteristic read, size=110
12:48:19.565 -> done writing config info
I made the data smaller (88 bytes) and it fails at the BLE app on my phone..(4 calls to event handler,420, 8 bytes missing).. I made it larger (117) and it worked at the BLE app on my phone..(6 calls to event handler... room left over 620=120)
note the arduino gets called for read.. so at least the characteristic 'works' from that perspective
what am I missing here? none of the samples do anything big like this String
Arduino ide 2.0.4 , ArduinoBLE 1.3.4 installed
I 'did' sort of expect the BLEStringCharacteristic lib code to handle the buffering of the transmissions under the covers (call the event handler once) . as it IS a different type than a BLEByteCharacteristic