If you are having issues with the exercises, please create a ticket on DevZone:
Click or drag files to this area to upload. You can upload up to 2 files.

Exercise 3

In this exercise, we will switch gears from non-connectable advertising, which we covered in Exercises 1 and 2, to connectable advertising. Connectable advertising is used by peripherals to advertise their presence and allows centrals to establish a connection to it.

We will also include the UUID for the LBS service in the advertising data, which can be used by a central to determine whether it wants to connect based on available services. Lastly, we will learn how to manually configure the Bluetooth LE address of the peripheral. Note, the address will only appear when using Android phones, not iOS.

The LED Button Service (LBS) is a custom service created by Nordic, and will be covered in more depth in lesson 4.

Exercise steps

In the GitHub repository for this course, go to the base code for this exercise, found in lesson2/blefund_less2_exer3.

1. Include support for the peripheral role from the Bluetooth LE stack.

Add the following line in prj.conf

When you enable this flag, you will get the functionalities needed for the peripheral role, including GATT and ATT. The default number for simultaneous connections CONFIG_BT_MAX_CONN is 1.

2. Change the Bluetooth LE device name from Nordic_Beacon to Nordic_Peripheral.


3. Prepare the advertising data.

3.1 Set the flags and populate the device name in the advertising packet.

As done before, we are including the device name in the packet. We are also enabling the discovery mode flag, as the device will act as a Bluetooth LE peripheral, not a beacon. We will set the discovery to BT_LE_AD_GENERAL.

Add the following lines inside the definition of the ad


3.2 Populate the scan response packet with the LBS service UUID.

3.2.1 Include the header file of the UUID helper macros and definitions.

#include <zephyr/bluetooth/uuid.h>

3.2.2 Include the 128-bit UUID of the LBS service in the scan response packet.

This UUID can be found here.

Add the following line inside sd:

BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_128_ENCODE(0x00001523, 0x1212, 0xefde, 0x1523, 0x785feabcd123)),

4. Set up the random static address.

4.1 Include the header file for managing Bluetooth LE addresses.

#include <zephyr/bluetooth/addr.h>

4.2 Change the random static address.

In the past two exercises, the Bluetooth LE address generated was a Non-Resolvable Random Private Address, which is generated randomly every time on bootup. This is the default type of address set for non-connectable advertising. For connectable advertising, the default is a random static address. We will learn how to manually configure the random static address in this step and set it to the address FF:EE:DD:CC:BB:AA

We will use the function bt_id_create() to set a new random static address. We will use the function bt_addr_le_from_str() to convert a string to a Bluetooth LE address. For types, it supports “random” and “public” addresses

Add the following code snippet inside main.c

    bt_addr_le_t addr;
    err = bt_addr_le_from_str("FF:EE:DD:CC:BB:AA", "random", &addr);
    if (err) {
        printk("Invalid BT address (err %d)\n", err);

    err = bt_id_create(&addr, NULL);
    if (err < 0) {
        printk("Creating new ID failed (err %d)\n", err);

5. Start to advertise connectable advertising.

This is done by calling bt_le_adv_start(). To specify it is connectable advertising, we could either do it by passing BT_LE_ADV_CONN (instead of the BT_LE_ADV_NCONN macro used in exercise 1) as the first parameter. Or we can set an advertising parameter as we did in exercise 2. The advantage of creating an advertising parameter is that it gives us more control over advertising.

5.1 Create the advertising parameter for connectable advertising. Again, this is optional, you could also simply pass BT_LE_ADV_CONN as the first parameter to bt_le_adv_start().

static struct bt_le_adv_param *adv_param = BT_LE_ADV_PARAM((BT_LE_ADV_OPT_CONNECTABLE|BT_LE_ADV_OPT_USE_IDENTITY), 
                800, /*Min Advertising Interval 500ms (800*0.625ms) */
                801, /*Max Advertising Interval 500.625ms (801*0.625ms)*/
                NULL); /* Set to NULL for undirected advertising*/

5.2 Start advertising by calling bt_le_adv_start() and passing the advertising parameter along with the advertising packet and scan response and their sizes.

6. Build and flash the application on your board.

You should notice that LED1 on your board is blinking now. Indicating that your board is advertising.

7. Open nRF Connect for Mobile on your smartphone and start scanning.

nRF Connect for Android

We should see now that the address of the device is set to FF:EE:DD:CC:BB:AA , and the UUID of the LBS service is now advertised. Also, we should notice the CONNECT button next to the device name, indicating that the device is advertising in connectable mode. We will cover connections in the next couple of lessons.


We should see that the UUID of the LBS service is now advertised. Also, we should notice the Connect button next to the device name, indicating that the device is advertising in connectable mode. We will cover connections in the next couple of lessons.

More on this

Since the iOS Bluetooth LE stack filters out the Bluetooth address of the device, it isn’t possible to see the address using iOS phones. In lesson 6 we will use a Bluetooth sniffer to capture and analyze packets, in which case we can see the device address.

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

  • 8 or more characters
  • Upper and lower case letters
  • At least one number or special character

Forgot your password?
Enter the email associated with your account, and we will send you a link to reset your password.