How to add mesh into nRF5 SDK v14.1 BLE application ?

hungbui gravatar image

asked 2017-10-30 17:01:16 +0100

What do I need to know to add mesh functionality into a normal BLE application ?

edit retag flag offensive close delete report spam


1 answer

Sort by » oldest newest most voted
hungbui gravatar image

answered 2017-10-30 17:39:31 +0100

updated 2018-01-12 17:14:36 +0100

We currently working on a tutorial on how to merge a mesh application into our nRF5 SDK BLE example. We will update this thread when we finish. For now we provide a quick example so that you can follow.

Mesh stack operates on the timeslot feature provided by the same softdevice used on the nRF5 SDK. So it requires little modification in the Mesh stack to be integrated into a normal BLE example. In fact only modification in the application code needed.

Attached here is an example that we merge the light control server example into ble_app_uart.


  • NRF SDK v14.1 ; Mesh SDK v0.10.1 ; S132 v5.0.0; PCA10040, Segger Embedded Studio

How to test:

  • Copy Mesh SDK into a "mesh" folder inside "components" folder in SDK v14.1
  • Unzip the ble_app_uart - MESH into \examples\ble_peripheral in SDK v14.1
  • Edit PERSISTENT_STORAGE define in nrf_mesh_config_code.h to 0
  • Build and flash the example. It should work as both ble_app_uart and light control server


  • Permanent storage of provisioning and configuration is not stored on flash. After reboot, the device would require provisioning again. We are working to fix this. The reason is the flash management on 2 SDKs are not the same and can conflict.

  • Only S132 v5.0, PCA10040, and SES is supported in the example for now.

  • Connection interval of BLE application have to be changed >100ms to give enough time for mesh

How to integrate into your own application:

  • Include all the source file from Mesh example

  • Include all header folders from Mesh example in Project Option -> Common -> Preprocessor -> Include Directories

  • Include Preprocessor Definitions in mesh example ( same setting tab as above).

  • Customize the simple_hal.c to not use GPIOTE_IRQHandler() as it conflicts with the gpiote driver in the SDK


  • Edit main.c to add mesh init functions and define.

  • Add nrf_mesh_evt_handler to SOC observer list with NRF_SDH_SOC_OBSERVER for example:

    void nrf_mesh_evt_handler(uint32_t sys_evt, void * p_context) {



    NRF_SDH_SOC_OBSERVER(m_nrf_mesh_observer, 0, nrf_mesh_evt_handler, NULL);

  • Add nrf_mesh_on_ble_evt((ble_evt_t *)p_ble_evt); to BLE observer list with NRF_SDH_BLE_OBSERVER; or just simply add it into ble_evt_handler(). (Optional)



UPDATE 12Jan2018

Example for SDK v14.2 and Mesh v1.0, nRF52840 and nRF52832:

Light switch client + ble app uart . Send BLE command on NUS service with '0' '1' '2' '3' as button press. Copy mesh SDK into mesh_sdk folder inside nRF5 SDK folder.


Light switch server + ble app proximity


edit flag offensive delete publish link more



I would like to combine ble_app_uart with light_switch_client for PCA10056 or PCA10040. So I did example for PCA10056 using your advices but I get a few similar errors like: errors and I dont know where I did mistake. Could you help me with this problem? I have tried many times but I do not find solution. I enclose my example. I would be grafefull if you could help me. ble_app_uart_client.rar Also I have tried to do example for PCA10040, it compiles without errors but it does not work. Neither mesh nor ble.

Butu ( 2017-11-06 22:06:01 +0100 )editconvert to answer

Hi Butu,

Seems that NRF52_SERIES is not defined. Please add that into Preprocessor Definitions in Project Option -> Common -> Preprocessor

Hung Bui ( 2017-11-08 10:27:13 +0100 )editconvert to answer

Thank you. I merged ble_app_uart and light_switch, sometimes works, sometimes it does not work. I have to reset my DK a few times and it starts working. I turned on RTT Viewer and saved logs from client. After flashing: warnings_after_flashing I connect client with smartphone (nRF Uart App) and get error: error; When I send 3 times message from app to client I get information that: Cannot send.Device is busy: device_is_busy I have to reset a few times becasue I still get message that Device is busy and it does not work. After a few resets everthing is good. everything_works

I have to reset many times and it is very problematic. Do you have any ideas?

Butu ( 2017-11-13 23:18:02 +0100 )editconvert to answer

Hi Butu,

Have you made sure you have the connection interval (with the phone) >100ms . This is to make sure mesh stack have enough time domain to function. Please try to test first without any BLE activity, no advertising, no connection. Try to test and make sure provisioning works fine, client can send data to server.

I suspect the short connection interval is the culprit here.

Hung Bui ( 2017-11-14 13:37:39 +0100 )editconvert to answer

Hi Hung, I still get message that: "Cannot send. Device is busy.". I have changed inverval:


And removed errror related to ble_gatt which I have mentioned before. However the message is still present and I can not send data via mesh. It seems that provisioning is fine because the message "Successfully provisioned" is visible in server logs. Maybe I have changed wrong values in connection interval.

Butu ( 2017-11-22 13:22:31 +0100 )editconvert to answer

Any update on this issue, I am having the same problem. If I disable all the BLE activity it does work but when I have it enabled it will not work. I get the " device is busy ".

These are my BLE settings :

#define SCAN_INTERVAL             0x00A0                                /**< Determines scan interval in units of 0.625 millisecond. */
#define SCAN_WINDOW               0x0050                                /**< Determines scan window in units of 0.625 millisecond. */
#define SCAN_TIMEOUT              0x0000                                /**< Timout when scanning. 0x0000 disables timeout. */

#define MIN_CONNECTION_INTERVAL   MSEC_TO_UNITS(100, UNIT_1_25_MS)      /**< Determines minimum connection interval in milliseconds. */
#define MAX_CONNECTION_INTERVAL   MSEC_TO_UNITS(500, UNIT_1_25_MS)       /**< Determines maximum connection interval in milliseconds. */
#define SLAVE_LATENCY             0                                     /**< Determines slave latency in terms of connection events. */
#define SUPERVISION_TIMEOUT       MSEC_TO_UNITS(4000, UNIT_10_MS)       /**< Determines supervision time-out in units of 10 milliseconds. */
ToasTer86 ( 2017-11-28 13:46:15 +0100 )editconvert to answer

I also added the nrf_mesh_on_ble_evt((ble_evt_t *)p_ble_evt); same as in the BLE uart example. When I follow the code and go to the definition of the code it takes me to nrf_mesh.c.

There I see the following function :

uint32_t nrf_mesh_on_ble_evt(ble_evt_t * p_ble_evt)
     * @todo Populate with GATT handling when the time comes.
    return NRF_SUCCESS;

Can I make the assumption this piece of code has not been implemented yet and BLE GATT + BLE mesh models do not work together yet ?

ToasTer86 ( 2017-11-28 15:16:21 +0100 )editconvert to answer

@Toaster: Please try increasing the scan interval and limit the scan window. The mesh stack and BLE stack both requires the radio, so the BLE stack shouldn't occupy the radio for too long. i would suggest to try giving 80% to mesh and 20% for BLE.

Hung Bui ( 2017-11-29 12:36:12 +0100 )editconvert to answer

@Hung Bui: Could you tell me where can I change values in example ( ble_app_uart combined with light_switch_client) . I do not see variables like SCAN_INTERVAL in light_switch_client and do not know what can I change.

Butu ( 2017-11-29 13:21:30 +0100 )editconvert to answer

@Hung Bui: I have been playing around with the variables you mentioned:

#define SCAN_INTERVAL             0x0020                                /**< Determines scan interval in units of 0.625 millisecond. */
#define SCAN_WINDOW               0x0010                                /**< Determines scan window in units of 0.625 millisecond. */
#define SCAN_TIMEOUT              0x0000                               /**< Timeout when scanning. 0x0000 disables timeout. */

#define SCAN_INTERVAL             0x0050                                /**< Determines scan interval in units of 0.625 millisecond. */
#define SCAN_WINDOW               0x0020                                /**< Determines scan window in units of 0.625 millisecond. */
#define SCAN_TIMEOUT              0x0000                               /**< Timeout when scanning. 0x0000 disables timeout. */

#define SCAN_INTERVAL             0x00A0                                /**< Determines scan interval in units of 0.625 millisecond. */
#define SCAN_WINDOW               0x0050                                /**< Determines scan window in units of 0.625 millisecond. */
#define SCAN_TIMEOUT              0x0000                               /**< Timeout when scanning. 0x0000 disables timeout. */

Does not seem to have a lot of succes. Everytime I do something with BLE all my mesh packets are not received or processed. Also the scanning settings should not matter when I put the amount of central links ...(more)

ToasTer86 ( 2017-11-29 14:17:13 +0100 )editconvert to answer

And I know you are all doing your best, so thanks for all the help. BL mesh is all still so new, seems like your openThread SDK has more support and documentation at the moment. What would your recommendation be? Switch over to Thread or keep trying BLE and BL mesh ?

ToasTer86 ( 2017-11-29 14:23:57 +0100 )editconvert to answer

I think there is an issue with the scanner and mesh stack. Tested here showed that after the first BLE scanning period the mesh stack didn't work after that. I will take a look.

@Toaster: It's hard to give you recommendation without knowing the application. Mesh and Thread are a little bit different. One is routed mesh and one is flood mesh. They do have some overlapping but has their own pros and cons depends on the application.

Hung Bui ( 2017-11-29 16:24:24 +0100 )editconvert to answer

Hey Hung, thanks again for your response. Such committed and involved developers is rare (as far as I know). I will wait for your response, I am doing research into Thread now as well to check its capabilities. As an answer for my application I want to share the Thingy52 sensor data over a mesh network.

My other question does the nRFsniffer work with BL 5 / BL mesh, or should I make a different question for this?

ToasTer86 ( 2017-11-29 16:54:58 +0100 )editconvert to answer

Hi Toaster,

I'm travelling for a week, so there won't be update until after next week. Regarding the nRFSniffer, no it only support BLE 4.0 so no BLE 5.0 or Mesh supported.

Hung Bui ( 2017-12-01 08:21:42 +0100 )editconvert to answer

Hi Hung, I have the same problem like Butu. I've mearged two examples from SDKv14.1 and SDK for Mesh. I have done everything like Butu after your recomendations. Now, I see the same message "Device is busy". Butu asked (Nov 29) where to change intervals value, but did not get any answer. Could you help us?

aszka ( 2017-12-02 10:11:50 +0100 )editconvert to answer

@aszka: As mentioned in the comment on 29Nov, I found an issue when integrating observer and mesh. I haven't got time to work on a workaround yet. I will get back in about 1 week.

Hung Bui ( 2017-12-04 00:10:35 +0100 )editconvert to answer

Has going , everyone? I look foward to getting a fixed thing, too. Need a Beta version ASAP, please!

hiroponie ( 2017-12-04 05:01:08 +0100 )editconvert to answer

@Hung Bui: Do you know something more about above problem with combined SDKs? Why have I message that "device is busy"? I tried 3 times to combine ble_app_uart and light_swtich_client and always I had the same issue. I think about connect two DK via etc. GPIO_UART, on one DK I will have ble_app_uart, on the second DK light_switch_client and send data between them. What do you think about this solution? Is it possible? I was trying find more about this solution in the forum, but I can not find something useful.

Butu ( 2017-12-13 11:25:17 +0100 )editconvert to answer

"device is busy" meaning the reliable packet has not been acked by the peer device. Most likely happens when mesh communication is not operate as it should. I assume you have the issue when testing with mesh + BLE central ? There is a bug with that combination that I haven't got time to look into it yet. Will try to find some time this week or next week.

Hung Bui ( 2017-12-14 09:46:05 +0100 )editconvert to answer

A quick update, we found that even with the example provided above, mesh only worked for a few dozens of second. After that timeslot is not given to mesh from softdevice. It's regardless it's advertising or scanning. This is resulted in "device is busy" as some of you already observed. We are investigating it.

Hung Bui ( 2017-12-19 18:04:29 +0100 )editconvert to answer

Hi all,

Thanks to Rick who helped me on this. My example was missing the nrf_mesh_on_sd_evt() handle, the following code should be added to main.c. Tested and the scanner also works:

void nrf_mesh_evt_handler(uint32_t sys_evt, void * p_context) 



NRF_SDH_SOC_OBSERVER(m_nrf_mesh_observer, 0, nrf_mesh_evt_handler, NULL);

We will update the example to MeshSDK v1.0

Hung Bui ( 2017-12-28 17:06:24 +0100 )editconvert to answer

Hi Hung Bui Thanks for the update I have been working with the nRF52840 chip and this was the piece we needed to move forward.
Also I have added the Long range PHY for mesh into my project and so far so good with the testing.

Jeff ( 2018-01-15 20:23:21 +0100 )editconvert to answer

Hi, I have a setup with 6 BMD-301 dev boards using this project (I am using the first project you posted) and I am finding a couple issues that are holding us up.

1) In the mesh sdk, I am getting a MESH ASSERT from the advertiser.c file from the "setup_next_timeout" on line 127. I did not ever see this when I was using just the mesh sdk. Do you know what might be causing this?

2) Secondly, when I am publishing 2 sets of "unreliable" messages (3 repititions each) within 1 second, I get NRF_ERROR_NO_MEM. I assume that the buffer is full, but I cannot verify. Do you know how the buffers for the mesh are defined, or how to make them bigger?

Before I found this project that you posted, I had tried several times to make it myself (and failed). I really appreciate your work on this.

Biff ( 2018-01-16 02:17:08 +0100 )editconvert to answer

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer. Do not ask a new question or reply to an answer here.

[hide preview]

User menu

    or sign up

Recent questions

Question Tools



Asked: 2017-10-30 17:01:16 +0100

Seen: 604 times

Last updated: jan. 12