Bluetooth mesh network

In the last post in this series on Bluetooth mesh (found here), we provided a high-level overview of the nRF5 SDK for Bluetooth mesh. We also listed the different examples provided as part of the Nordic SDK. The most complete of these examples is the lighting example, and this is the one we’ll go forward with demoing and explaining. In this week’s post, we’ll go over building and running this example and understanding the different parts within it. In the upcoming posts, we’ll get into the details of the source code for each device.

Here’s a diagram showing the network and the devices we’ll be using within it:

nRF Mesh network diagram

Figure 1: nRF mesh network diagram


Hardware and Software Requirements

The different hardware devices required in this example include:

  • Two nRF52 boards (I will be using the nRF52840 development boards). One board will be programmed with the proxy server, and the other with the proxy client. We’ll be using proxy nodes to allow the mobile phone to discover and provision them (since mobile OS’s do not support communicating with non-proxy mesh devices).
  • A mobile phone (iOS or Android) running the nRF Mesh mobile application.
  • A PC to build the example code, interface with and program the development boards.

The different software packages required for building the examples are:

  • Segger Embedded Studio (SES) (found here).
  • Nordic nRF5 SDK version 15.0.0 (found here).
  • Nordic nRF5 SDK for Mesh version 2.2.0 (found here).
  • nRF Mesh iOS or Android app installed on your mobile phone (found here for iOS and here for Android).

The nRF5 SDK for Mesh requires nRF5 SDK version 15.0.0 to build. The steps needed to get this done are:

  • Make sure you download both the nRF5 SDK for Mesh and the nRF5 SDK.
  • Place the extracted folders (from the ZIP files) in the same folder. This is what my folder structure looks like:
    └── nRF Mesh Project/

    │          ├── nRF5_SDK_15.0.0_a53641a/
    │          └── nrf5_SDK_for_Mesh_v2.2.0_src/
  • By default, Segger Embedded Studio (SES) will pick up the nRF5 SDK if it’s placed alongside the nRF5 Mesh SDK. You can, however, place it in a different location and modify the SDK_ROOT macro from within SES to point to this different path (by following the instructions here).

The Light Switch Mesh Example

General Description of Operation

The basic operation of this example is to form a Bluetooth mesh network that consists of a smartphone (which is used as a provisioner) and two nRF52 development boards: one used as a light switch, and the other used as a light bulb. The provisioner (smartphone in this case) configures the whole network by:

  • Assigning each device a unique address.
  • Distributing the necessary network and application keys that are appropriate for each device.
  • Configuring the mesh models for each device.

The nRF Mesh mobile application (which we’ll be using as the provisioner) gives us a lot of flexibility and control over each step of the provisioning process. This can be a bit confusing and overwhelming at first, but it serves as a great way to learn about the different concepts and operations within a Bluetooth mesh network.

Running the Example Step-By-Step

Before building and flashing the development boards with this example for the first time, we will need to erase the flash.

Erase the Development Boards

To do that follow these steps for each of the two development boards:

  • First, connect only one of the development boards to your computer via the USB cable.
  • Open Segger Embedded Studio (SES). If you haven’t gone through downloading and setting up SES yet, you might want to check out my previous tutorial first: The complete cross-platform nRF development tutorial
  • Open one of the Solutions for the example: either the light switch proxy client or light switch proxy server:
    └── nrf5_SDK_for_Mesh_v2.2.0_src/
    │          ├── examples
    │                      ├── light_switch
    │                                  ├── proxy_client
    │                                              ├── light_switch_proxy_client_nrf52840_xxAA_s140_6_0_0.emProject
    │                                  ├── proxy_server
    │                                              ├── light_switch_proxy_server_nrf52840_xxAA_s140_6_0_0.emProject
  • Navigate to the Target menu item and choose Connect J-Link:

    Figure 2: Connecting J-Link in SES

  • Next, navigate to the Target menu again and verify that J-Link is now connected. You will now see that the other options (such as Reset, Download, Erase All, and Download) are all available (not grayed-out anymore). Select Erase All. This operation will take a few seconds, up to a minute or so, but is necessary to make sure the development board is cleared of any previous older versions of the SoftDevice and data saved in memory.

Figure 3: Erase All option in SES

  • Wait for the operation to finish (usually when the following message shows up):

    Figure 4: Erase All done

Building and Flashing the Example

Once you’re finished with erasing each of the development boards, you’re now ready to build the proxy server and proxy client projects and flash each of them to a development board.


  • Make sure you have only one development board connected to your computer.
  • Open one of the SES Solution files for either the light switch proxy client or light switch proxy server.
  • Build and Flash the project. You can use the Build and Debug option under the Build menu for this.
  • Once you’ve flashed the board and you’ve started the debugging process, you’ll see that the application halts at main() waiting for you to continue execution. You’ll also see the following in the debug terminal output window:
    Light Switch Proxy Server:

    Figure 5: Proxy Server demo debug output

    Light Switch Proxy Client:

    Figure 6: Proxy Client demo debug output

  • At this point, you can simply turn off the development board (or disconnect it), and move on to flashing the other one. Turning on the development board later will run the application as it has already been flashed and no need to execute it from the computer anymore.
  • If you see a message telling you that the RAM start can be adjusted to a different address, then you’ll have to modify the project macros to match the suggested values. You can do this by:
    • Right-clicking on the Project name
    • Clicking on Edit options
    • From the Configurations drop-down menu, choose Common
    • Select Linker
    • Double-click on Section Placement Macros
    • Modify RAM Start to match the value printed in the Debug Terminal window
  • Make sure you have each development board labeled or at least recognized with the role it was flashed with (Client/Switch or Server/Light). This will make it easier to identify later when provisioning and when operating and testing the network.
  • Once you have the development boards flashed with the server and client examples, you’re ready to move on to running the example and configuring the mesh network.

Configuring the Network (Provisioning)

Now, we’re ready to configure our mesh network and provision each of the light switch proxy server and proxy client devices.

  • First, make sure you have the iOS or Android nRF Mesh app installed on your smartphone
  • Launch the nRF Mesh app
  • Click on Add new device
  • The app will start scanning for devices that are unprovisioned and beaconing in the surrounding area
  • You should see both the nRF5x Mesh Light and nRF5x Mesh Switch devices show up in the list
  • Click on one of them in the list and then click on Identify
  • Wait for the process to finish and populate the information, then hit Provision
  • This process will take a few seconds, up to a minute or so (the progress will be shown at the bottom right-hand corner of the screen indicating the percentage completed)
  • Repeat the provisioning process is finished for the other device

Here’s a video showing the process:

  • Once you have both devices provisioned, you’re ready to configure them.
  • From the Network tab, you’ll see the list of two devices: nRF5x Mesh Switch and nRF5x Mesh Light.
  • Click on the nRF5x Mesh Switch. This is the device we want to configure to behave as a client (a light switch that controls other light bulbs in the network).
  • Click on Generic OnOff Client. The GenericOnOff model is a Bluetooth SIG-defined model which the use case of a basic on/off switch (such as a light switch).
  • Next, we want to bind the Client to an AppKey. Let’s choose the first one in the list (AppKey 1). Once it’s bound, you’ll see that it’s listed as Key index 0000.
  • Since this is a Client, we want it to publish to an address. So, let’s define that. Select Publication Address and enter an address if not already set (I entered CEEF in my case). Once you enter it, you can hit Apply Publication.
  • If successful, you should then see it listed under Publication Address.
  • Now, let’s configure the Server. Go back to the Network tab and select the nRF5x Mesh Light device in the list.
  • Click on Generic OnOff Server. Select AppKey Binding and choose the first key in the list (AppKey 1).
  • Next, we want to set the Subscription Address since this device will behave as a Server, meaning it will listen and act on messages and commands sent to it from Clients.
  • Enter the same address (CEEF in my case). You should now see it listed under Subscription Addresses.

Here’s a recording of this process:

Testing the Network Operation

  • Now, you’re ready to test the operation of the network.
  • Press Button #1 on the Client/Light Switch board.
  • You should see that LED #1 on the other board (Server/Light Bulb) turns on.
  • Press Button #2 on the Client/Light Switch board and it should turn LED #1 off on the other board (Server/Light Bulb).


In this post, we went through the basics of building, flashing and running the Light Switch mesh example on the nRF development kits. We only covered the basics of getting the network set up and tested. As you’ve probably noticed, the nRF Mesh mobile app is full of options and configurations, but it’s always a good idea to start with just a simple example and then expand into the different bells and whistles once we have a basic network set up.

In the following posts, we’ll start digging into the actual source code for the different types of devices (Client and Server Nodes) as well as into more details of the provisioning process.



  1. Avatar Mim on June 26, 2019 at

    I’ve resolved the above issue!

  2. Avatar Mim on June 24, 2019 at

    Hi again,

    I can’t seem to get the debug logging to work, as soon as I enable logging using the configuration wizard and rebuild (NRF_LOG_ENABLED – nrf_log – Logger), I get a bunch of linker errors. I assume that I’m missing things in the sdk_config.h, but I’m not sure specifically what.

    I also can’t copy the errors, but this is the first of 19 similar errors:
    Linking light_switch_client_nrf52840_xxAA_s140_6.1.0.elf
    build/light_switch_client_nrf52840_xxAA_s140_6.1.0_Release/obj/nrf_sdh_ble.o: in function nrf_sdh_ble_default_cfg_set':
    nrf_sdh_ble.c:(.text.nrf_sdh_ble_default_cfg_set+0x34): undefined reference to

  3. Avatar Mim on June 24, 2019 at

    Hi Mohammed,

    Thank you for these wonderful tutorials!
    I (for some reason) was unable to reply to the first comment, but I wanted to let you both know that, although I had both the nRF5_SDK_15.3.0_59ac345 and the nrf5SDKforMeshv310src extracted in the same folder, I still had to set the macro following the instructions Muhammad Saud had posted.

    This resolved the issue of missing header files for me 🙂

    Point of clarity: “SDK_ROOT=” must of course be followed by the path to your nRF5_SDK_15.3.0_59ac345,
    SDK_ROOT=/Users/miriamlennig/Library/Mobile Documents/com~apple~CloudDocs/Education/SUMMER ’19/NASA/nRF52840/nRF5_SDK_15.3.0_59ac345

  4. Avatar Jerry on June 14, 2019 at

    Hi Mohammad,

    Thank you so much for the tutorials,It’s very useful to me.I have problems,Figure 1 show nRF mesh network diagram:a provisioner ,a proxy client node,a proxy server node.

    1.But nRF’reference explain the Proxy Client role is not supported
    2. why need a proxy client node in the example?


    Both the light switch server and light switch client examples have provisionee role.
    They support provisioning over Advertising bearer (PB-ADV) and GATT bearer (PB-GATT) and also support
    Mesh Proxy Service (Server). Read more about the Proxy feature in @ref md_doc_getting_started_gatt_proxy.

    @note The Proxy Client role is not supported.

    • Mohammad Afaneh Mohammad Afaneh on June 25, 2019 at

      Hi Jerry,

      Do you have a link where it’s mentioned that the Proxy Client role is not supported? It may be a difference in the nRF for Mesh SDK versions (I was using 2.20 vs 3.10 which is available now). That said, I do see in the documentation for the 3.0 version that they integrated the Proxy functionality into the Client examples (see here under the “Examples” section:

      The Proxy functionality is used primarily for allowing a smartphone to interface with the mesh network (via the GATT bearer (PB-GATT)).


  5. Avatar Carlos on March 8, 2019 at

    I cannot for the life of me get the nRF5x Mesh Switch to appear in the phone app. The nRF5x Mesh Light appears and I can interact with it to turn the led on/off. But it does not find the switch. Flashed already many times, adjusted the RAM start when requested but to no avail. Any ideas?

  6. Avatar Hitesh on February 18, 2019 at

    Will the same process work to relay the message signal to server which is not in range of client but is in range of other server.

  7. Avatar Pegah on January 15, 2019 at

    Dear Mohammad,
    First off, thank you for this step by step tutorial. It helped me a lot.
    However, I have some doubts regarding the NetKey usage in this demo. As far as I understand, according to Bluetooth Mesh specification, each node is assigned with a NetKey at the end of Provisioning, along with the unicast address. And then, in the configuration process the AppKeys are assigned and then each model is bounded with one of the AppKeys.
    Here I can see all the steps, except NetKeys. So if I want to have multi subnets (for example imagine a pair of switch and light in different floors of a building), how can I manage that using NRF Mesh app?
    I also checked the “nrf_mesh_config_app.h” and the “DSM_SUBNET_MAX ” value is set to 4. but I couldn’t understand how can I configure to have for example three subnets.
    It would be great if you could help me with this issue.


  8. Avatar Muhammad Saud on December 5, 2018 at

    Dear Mohammad Afaneh,
    I placed the mesh and normal SDK side-by-side and it resolved the issue.
    Thank you so much!

    On reading your another reply for Rosa,
    I have also confronted with the issue,What happened is when I opened the nrf mesh app,while provisioning for 3 or 4 times things were working well.But suddenly,the app was unable to scan or find the available devices.I checked it with normal phone’s bluetooth scanning,it was working fine and discovering all that.Then after deleting the app mant times and again loading the source code in devices it was working but again the issue was same after sometime.What I did,instead of using nrf mesh app directly,I downloaded nrf Toolbox app and from there I opened the mesh.I tested it repeatedly,It was working fine.Still not sure if this will work all time or not but it was working for me.

  9. Avatar Rosa on December 4, 2018 at

    Hi Mohammad,

    Thank you so much for the tutorials. I just started studying Bluetooth Mesh, your tutorials really helped me a lot.

    I’ve followed the steps above but I’m seeing an issue in my phone, when click into node configuration, it’s showing N/A instead of all the parameters, in that case I was not able to find the Generic OnOff option. Do you have any ideas on what caused that or have you met the same problem when you were setting the board up? Please let me know, thank you thank you!


    • Mohammad Afaneh Mohammad Afaneh on December 5, 2018 at

      Hi Rosa,

      Thanks for the kind words, and I’m glad you’ve found the tutorials helpful!

      I have seen intermittent issues, maybe once or twice, where the provisioning process doesn’t go through and it may have caused a similar issue to what you’re seeing. Did you try deleting the device from the mobile app, Resetting All for the Target, flashing it again, and the provisioning it? Are you seeing this consistently? What versions of the nRF SDK and nRF Mesh SDK are you using?

      • Avatar rosa on December 5, 2018 at

        Hi Mohammad,

        Thank you for the reply, I tried to download the code again and reloaded the app. It’s working now!

  10. Avatar Muhammad Saud on December 1, 2018 at

    Dear Mohammad Afaneh ,
    Your work is amazing and beautifully explained,thumbs up.I am having a problem starting with mesh sdk.When I opened mesh switch example in the segger embedded studio(SES),I got this in start:
    “Segger Embedded Studio determines the location of the nRF5 SDK through macros.
    Before building the example, you must first configure the SDK_ROOT macro
    in Segger Embedded Studio. This is a one time global configuration that will
    still be valid the next time you open Segger Embedded Studio. The SDK_ROOT
    variable defaults to an nRF5 SDK 15.2.0 instance unzipped right next to the mesh
    folder if not set.

    The SDK_ROOT macro can be set by navigating to Tools -> Options, then
    “Building”. Under “Build” in the configuration list, edit “Global macros” to
    contain SDK_ROOT=. Save the

    The path can be verified by opening one of the source files under the “nRF5 SDK”
    file group. If the macro was set correctly, the file should open in the editor
    window. If not, it will show an error message telling you that the file couldn’t
    be found.

    For more info on Segger Embedded Studio macros, see
    I have tried to do it by hook and crook,but couldn’t able to do that.I searched on Devzone,infocenter but nothing happened.
    Please help and guide me,how can i resolve this issue.
    Thank you!

    With regards,
    Muhammad Saud

    • Mohammad Afaneh Mohammad Afaneh on December 3, 2018 at

      Thank you, Muhammad! I appreciate the kind words.

      You should not have to set that macro if you place the mesh and normal SDK side-by-side. Have you tried that? Simply unzip both SDKs that you download and place them next to each other in the same folder.

      Let me know if you’re still running into issues.

Leave a Comment