I want to keep a project, preferably based on Callback LED Example. I want to request a double value from my nano from my nano 33 BLE. I am using the LightBlue App on my iPhone. My simple project is to send the phone a number which would create an event directing my code to go out and gather the necessary data and then send it back to the phone. I understand how to setup the event handler. But now I am looking for the was to send back to the phone more than an 8-bit value. I am just looking for direction of how to use the BLECharacteristic for the correct functions to use. I am learning bluetooth and getting a bit confused in the BLECharacteristic source files.
here is some simple code advertising a 15 byte buffer that I fill in with a changing value, millis formatted as a float @ 1/100th of second through this command: snprintf(payload, payloadSize, "%6.2f s", millis() / 1000.0);
here is the code
#include <ArduinoBLE.h>
// randomly generated UUIDs
const char * serviceUUID = "5ac1d00e-1ce6-4e53-b904-0822cd136d05";
const char * characteristicUUID = "43ada7f1-7ec0-4e14-a4af-920859b5a9e5";
const char * myName = "DataProvider";
const int payloadSize = 15; // max payload size for BLE
char payload[payloadSize] = ""; // start with empty string
BLEService dataService(serviceUUID);
BLECharacteristic dataCharacteristic(characteristicUUID, BLERead | BLENotify, payloadSize + 1); // remote clients will be able to get notifications if this characteristic changes
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected
Serial.begin(115200); while (!Serial);
if (!BLE.begin()) {
Serial.println(F("starting BLE failed!"));
while (true) yield();
}
dataCharacteristic.writeValue((const char*) payload, strlen(payload)); // set the initial value for the characeristic
dataService.addCharacteristic(dataCharacteristic); // add the characteristic to the service
BLE.setLocalName(myName); // set advertised local name
BLE.addService(dataService); // Add the data service
BLE.setAdvertisedService(dataService); // set advertised service UUID
BLE.advertise(); // start advertising
Serial.println(F("Ready to serve!"));
}
void loop() {
static uint32_t previousMillis = 0;
BLEDevice central = BLE.central();
if (central) {
digitalWrite(LED_BUILTIN, HIGH);
Serial.print("Connected to central: "); Serial.println(central.address());
while (central.connected()) {
uint32_t currentMillis = millis();
if (currentMillis - previousMillis >= 10) { // update every 10ms
snprintf(payload, payloadSize, "%6.2f s", millis() / 1000.0);
dataCharacteristic.writeValue((const char*) payload, strlen(payload));
previousMillis = currentMillis;
}
}
// when the central disconnects, turn off the LED:
digitalWrite(LED_BUILTIN, LOW);
Serial.println("Disconnected from central");
}
}
I used BlueSee on my Mac to connect to the device through its advertised name (DataProvider) and switched the view to ASCII and then Subscribed to the changes. --> I can see the time passing by being updated in the characteristic value field.
In Bluetooth 4.0, BLE has a maximum payload of 33 bytes and each layer in the protocol stack eats into it:
2 bytes for packet header (type and length),
4 bytes for MIC (when encryption is enabled),
4 bytes for L2CAP header (channel ID and packet length),
--> ATT protocol is left with 23 bytes, which is the default and minimal MTU for ATT protocol and 3 bytes are used by command type and attribute ID for a write request
So this MTU size of 23 bytes for BLE 4.0 (20b of data + 3b protocol wrapper) applies, hence keep the payload under 20 bytes.
BLE 4.2 or BLE 5.0 offer more, and if you were to use an ESP32 (BLE 5.0) you can get a larger MTU (but the central needs to be able to honour that)
Thank you so much Jackson. Let me play with example and see what I can do. I need to connect with an iPhone since my project is a mobile device. I'll report back what I see.
Also, I thought I remember seeing somewhere that Arduino wrote a BlueTooth tutorial on the web site, but now I can find it. It you or anybody else reading this could send my a link, it would be much appreciated.