Requesting data from nano 33 BLE via Bluetooth

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.

Any help is much apprecitated.

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.

Thanks

on my iPhone I prefer nrfConnect but Light Blue should be oK

Using nrfConnect

using Light Blue. it gets the wrong name (sees Arduino and make sure you pick UTF8 for the content)

In both cases the data is there and getting updated

may be this is the link you were looking for:

Much, much appreciated. I built your code and I am seeing what I wanted now. This is great.

-Greg

cool - have fun

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.