The problem is I can't get the BLE Characteristic update to work.
BLE updates are carried out and optimized in the following way. The code is shortened for readability, but this method means all necessary information can be sent in one BLE packet (<20 bytes), at the required high speed:
Code: Select all
void setAdvData() {
std::string strServiceData = "";
strServiceData += (char)(transmission_num & 0xff); // Lower byte of transmission number
strServiceData += (char)((transmission_num >> 8) & 0xff); // Upper byte of transmission number
strServiceData += (char)(temp & 0xff); // Lower byte of temperature
strServiceData += (char)((temp >> 8) & 0xff); // Upper byte of temperature
strServiceData += (char)(humid & 0xff); // Lower byte of Humidity
strServiceData += (char)((humid >> 8) & 0xff); // Upper byte of Humidity
myCharacteristic.notify(strServiceData); // Set characteristic message, and notify client
}
My solution was to change strServiceData from type "std::string" to type "String". I then had to further convert it using c_str(), otherwise there would be a similar compilation error:no matching function for call to 'BLECharacteristic::notify(std::string&)'
no matching function for call to 'BLECharacteristic::notify(String&)'
This is the resulting semi-working code:
Code: Select all
void setAdvData() {
String strServiceData = ""; <=== Changed here
strServiceData += (char)(transmission_num & 0xff); // Lower byte of transmission number
strServiceData += (char)((transmission_num >> 8) & 0xff); // Upper byte of transmission number
strServiceData += (char)(temp & 0xff); // Lower byte of temperature
strServiceData += (char)((temp >> 8) & 0xff); // Upper byte of temperature
strServiceData += (char)(humid & 0xff); // Lower byte of Humidity
strServiceData += (char)((humid >> 8) & 0xff); // Upper byte of Humidity
myTestString = strServiceData.c_str(); <=== Changed here
myCharacteristic.notify(strServiceData); // Set characteristic message, and notify client
}
Doing this conversion now means the MTU size must be increased. This isn't an issue in itself, but the data being sent over on each packet is exactly the same each time and totally wrong.
For instance, the transmission_number, the first 2 bytes in each message are expected to be, "1, 2, 3, 4, 5..." and this is confirmed by Serial.print. Instead '4836' is received as the transmission_number for each message.
I have tried looping the BLE message 10x before each .notify() since the MTU size must now be increased, and something strange happens. To be clear, it now means the String strServiceData is 10x longer, and then a notification is sent.
In this case, the transmission number is still corrupt, but the following bytes: for temp, humidity, etc., now contain the correct data. Except, this is only true for the first 6 loops. The last 4 loops have nonsensical data, and then this repeats. The next 6 semi-work, the next 4 are nonsense. On each of these cycles the corrupt data is the same. That is the 7th, 17th, 27th, etc. BLE message has the exact same wrong data. The same is true for the 8th, 9th, and 10th message, each having their own respective repeating information.
The easiest approach to solve this I think would be to find a way to get std::string, or something of that sort, to work with the BLECharacteristic::notify() function. I think in all the conversions from String to c_str, the data is getting changed and the intended optimization is not working. I don't want to have to change this because (1) it works really well as proven by my previous boards (2) I'll have to rewrite a good part of the Android app
Any help with this would be greatly appreciated.