Using BLE with 1.3. How to set the local name of the device to show in the advertising packet

I have taken the example code and added one line data.appendLocalName("Test"); in setup. The resulting code looks like this.

void setup() {
    Serial.begin(115200);

    LOG(TRACE, "Application started.");

    BLE.addCharacteristic(txCharacteristic);
    BLE.addCharacteristic(rxCharacteristic);

    BleAdvertisingData data;
    data.appendServiceUUID(serviceUuid);
    data.appendLocalName("Test");
    BLE.advertise(&data);
}

When using the Adafruit BLE app it sees the device as a UART capable device which is great but continues to show a device name of Argon-X3JDSM, not Test. Could this be a caching issue on iOS or am I needing to do something additional to get the same to set properly?

1 Like

Interestingly the local name shows up in the detail on the advertisement but does not affect the displayed name in the Adafruit app. Again maybe a caching issue.

2 Likes

I’m just starting to look at integrating BLE. Watching this thread as I’ll want to change the advertising name as well.

Yup, I also think it’s a caching issue with the app.
I use nRF Connect App and that reports the device with the set local name while the Bluefruit App still reports the first name it saw of said device.

1 Like

So the minimum code I need to change the BLE advertised device name is the code circled in red in the screenshot below?

I’m using one of Ricks new BLE Serial Libraries and in setup all I have is what is below. I just wondering if I add the &data to the bleSerial.advertise() if it will change the data I’m sending out or if that will only change the Local Name that is Advertised? I’ll give it a try. If I’m missing anything let me know please.

appendLocalName() is not that different to appendServiceUUID() which Rick has mentioned in his post

With appendLocalName() you are not adding another service but the name.
However, you need to bundle the BLE UART UUID and the name into a "shared" set of advertising data and then advertise that bundle the standard BLE.advertise() way.

That's where the curiosity to understand how it works beats just being conent with prefab solutions :wink:

I have modified Ricks latest example and it’s working just fine as far as pushing out the data I want. I only want to change the Device localname that shows up.

I can see how we can easily change the UART UUID and it sounds like you saying I can’t change the Local name without also adding the BLESerial UUID? Am I understanding you correctly?

The UUID is not called but automatically set to UART Serial in Ricks example so to change the Local name am I required to add the recommended BLESerial UUID that is being used automatically when we just call:

Do I need to add the UUID as shown in the screen shot below even if I’m only advertising one service (BLE Serial UART)?

I’m slowly learning how to take advantage of these BLE features.

@iitgrad Did the new Local BLE name you programmed show up correctly on apps when it was the first time recognizing the BLE device where it’s previous advertised name was not already saved?

I’ve tried various things recommended above but the default ARGON-xxxxx name remains as the device name when scanned by BLE applications.

Did you ever figure this out?

@ScruffR Were you able get this to work for yourself so it shows up with your customized name on your phone?

Yes. I just did This with a class of 15 students and made sure they set a unique name before ever connecting to the phone and it worked

@iitgrad And that was possible with this code only?

I haven't tried it, but the previous statements came from my understanding of how advertising works

You have only one set of advertising data you can tell the BLE hardware to advertise, hence it has to contain all info you want to advertise and all services as well as the local name and potentially custom data.

For the sake of advertising it's quite irrelevant whether you want to bundle the bleSerial service with another service or a local name or a custom data block.
You just have one instance of BleAdvertisingData to pass to BLE.advertise() and bleSerial.advertise() does not take any parameters, hence you can't just hand it a BleAdvertisingData instance that only contains the local name.

For Rick's statement in your screenshot:
That portion you undlerlined in green has to be read in connection with the comment
// append your own service UUIDs here
If you don't want any services added but a name (which Rick didn't explicitly state but the common pattern should be self-explanatory) you'd replace that comment with
data.addLocalName("yourDesiredName");

To break it down

BleAdvertisingData data;                            // prepare a fresh/empty advertising data instance
data.appendLocalName("yourDesiredName");            // give the device a name to advertise (can be anywhere in the bundle)
data.appendServiceUUID(bleSerial.getServiceUuid()); // add the UUID that is created by the bleSerial object
// optionally add any additional service UUIDs
// optionally add any custom data you want (if it still fits)
BLE.advertise(&data);                               // tell BLE to advertise all of the above

I’m kinda confused but think I get that what your saying about the BLE Data Burst has to contain the Serial UART Data + the LocalName Data.

Based on @iitgrad 's example that he says worked for him I feel as if the code below would be the minimum required to only change the BLE Local Name? Is that right?

I loaded it but didn’t see the Local Name Change and didn’t see it in the iOS nRF app but I was having issues with the iOS version in previous testing. Maybe it is working and its a App or caching issue where the old Local Name is still stored.

void setup() {
    Serial.begin(115200);

    BleAdvertisingData data;
    data.appendLocalName("Test");
    BLE.advertise(&data);
}

If the UUID is required to be added for Serial BLE to also be broadcast then I would think the code should look like below where the UUID has been added:

void setup() {
    Serial.begin(115200);

    BleAdvertisingData data;
    data.appendServiceUUID(bleSerial.getServiceUuid());
    data.appendLocalName("Test");
    BLE.advertise(&data);
}

Should one of those be actually working?

I don’t know if it’s the code or BLE App Caching issues causing the Local Name not to change?

Correct!

Yup, that should do the trick - notwithstanding any roadblocks any given mobile app might throw at you with local name caching of any known device.

OK, so that’s pretty simple.

So to confirm, I do need to add the UUID changing the BLE Local Name?

The required code to get both the Serial UART UUID + The custom Local Name to broadcast together is below?

void setup() {
    Serial.begin(115200);

    BleAdvertisingData data;
    data.appendServiceUUID(bleSerial.getServiceUuid());
    data.appendLocalName("Test");
    BLE.advertise(&data);
}

Not quite the way you formulate it there :wink:
You need to add/append the UUID in order to advertise the UART service.
You need to add/append the Local Name in order to tell the outer world about the name.
And you need to do both when you want both things advertised simultaneously.

On holiday you don't need to pack your swim shorts in order to have your passport with you but if you want to go swimming it would be good to pack them anyway :wink:

Am I missing the Add Characteristic first?

If so what is exactly required when I’m just using Serial UART and Changing the Local Name? I see @iitgrad Added txCharacteristic() + RxCharacteristic() but I’m not sure if that required when using Ricks New BLE Serial UART library?

I think what is confusing me is that I’m not seeing what is being set in the background when I’m just running the code below which sends and receives Serial BLE data perfectly. In the example below none of the addCharacteristic’s or data.Append functions need to be added or called.

Now when all I want to do is change the BLE Local Name I have to start adding Characteristics + data.append the added characteristic’s. It just feels like it’s getting more complicated than it needs to be.

I’m trying to just keep it simple for the sake of the code and for the sake of my understanding.

#include "BleSerialPeripheralRK.h"
SerialLogHandler logHandler;
SYSTEM_THREAD(ENABLED);
// First parameter is the transmit buffer size, second parameter is the receive buffer size
BleSerialPeripheralStatic<256, 256> bleSerial;
const unsigned long TRANSMIT_PERIOD_MS = 1000;
unsigned long lastTransmit = 0;
int counter = 0;
void setup() {
    Mesh.off();
    WiFi.off();
    Serial.begin();
    // This must be called from setup()!
    bleSerial.setup();
    // If you don't have any other services to advertise, just call advertise().
    // Otherwise, call getServiceUuid() to get the serial service UUID and add that to your
    // custom advertising data payload and call BLE.advertise() yourself with all of your necessary
    // services added.
    BleAdvertisingData data;
 
    bleSerial.advertise();

    // take control of the LED to turn it off to lowest power operation. Prevents LED from lighting up on every wake. 
  RGB.control(true);
  // scales brightness of all three colors, 0-255.
  // the following sets the RGB LED brightness to 25%:
  RGB.brightness(0);
}
void loop() {
    // This must be called from loop() on every call to loop.
    bleSerial.loop();
    // Print out anything we receive
    if(bleSerial.available()) {
        String s = bleSerial.readString();
        Log.info("received: %s", s.c_str());
    }
    if (millis() - lastTransmit >= TRANSMIT_PERIOD_MS) {
        lastTransmit = millis();
        // Every two seconds, send something to the other side
        bleSerial.printlnf("Bat V %d, I %d, W %d / Solar V %d, I %d, W %d", counter,counter,counter,counter,counter, counter);
        Log.info("counter=%d", counter++);
    }
}

That shouldn't be required as all that should be done by the bleSerial.setup() call.

However, I was going to put all the theory into practice and found that something seems to be fishy.
The UUIDs for service and characteristics don't seem to be advertised (not even with bleSerial.advertise().

Nice to know I’m not the only one this is not working for.

Did the vanilla sample with that library work for you at all (before trying to add the name)?

I had accidentally left this added line in that code above.

This line was removed from Ricks example code: BleAdvertisingData data;

I’m running exactly what’s below.

#include "BleSerialPeripheralRK.h"
SerialLogHandler logHandler;
SYSTEM_THREAD(ENABLED);
// First parameter is the transmit buffer size, second parameter is the receive buffer size
BleSerialPeripheralStatic<256, 256> bleSerial;
const unsigned long TRANSMIT_PERIOD_MS = 1000;
unsigned long lastTransmit = 0;
int counter = 0;
void setup() {
    Mesh.off();
    WiFi.off();
    Serial.begin();
    // This must be called from setup()!
    bleSerial.setup();
    // If you don't have any other services to advertise, just call advertise().
    // Otherwise, call getServiceUuid() to get the serial service UUID and add that to your
    // custom advertising data payload and call BLE.advertise() yourself with all of your necessary
    // services added.

    bleSerial.advertise();

    // take control of the LED to turn it off to lowest power operation. Prevents LED from lighting up on every wake. 
  RGB.control(true);
  // scales brightness of all three colors, 0-255.
  // the following sets the RGB LED brightness to 25%:
  RGB.brightness(0);
}
void loop() {
    // This must be called from loop() on every call to loop.
    bleSerial.loop();
    // Print out anything we receive
    if(bleSerial.available()) {
        String s = bleSerial.readString();
        Log.info("received: %s", s.c_str());
    }
    if (millis() - lastTransmit >= TRANSMIT_PERIOD_MS) {
        lastTransmit = millis();
        // Every two seconds, send something to the other side
        bleSerial.printlnf("Bat V %d, I %d, W %d / Solar V %d, I %d, W %d", counter,counter,counter,counter,counter, counter);
        Log.info("counter=%d", counter++);
    }
}