BLE mesh: Using nRF52840 Dongle with sensor_server sample

When evaluating BLE mesh with multiple nodes the nRF52840 Dongle is perfect to keep cost and physical size down.

I thus have one nrf52840 DK and a couple of nRF52840 Dongles. To get started I would like to get the "sensor_client" and "sensor_server" samples provided with the nRF Connect SDK working on these. I know that these samples are not marked as compatible with the dongle, but I assume this is more due to missing support then missing HW capabilities (?)

Anyhow both samples seems to work fine on the DK and can be detected and provisioned by the nRF Mesh app. But none of them appears in the nRF Mesh app when programmed to the dongle. I am using Visual Studio Code with nRF Connect SDK, choosing the dongle board in the build configuration and flashing the dongle with the nRF programmer over USB. I have also verified that the dongle works fine with the "blinky" and "console" samples. This includes getting the console output to a serial terminal over USB.

Since there is no debugger in the dongle it would be very useful to get console access to monitor how the application is performing and find out why the BLE samples doesn't work on the dongle. I thus combined the "console" and the "sensor_server" samples from the nRF Connect SDK to a new application. This also works fine on the nrf52840 DK, and can be detected and provisioned by the nrf Mesh app. And the console is appearing on the nRF USB connector on the DK as expected, but with multiple lines like "[00:00:28.142,150] <inf> usb_cdc_acm: Ring buffer full, drain buffer" mixed with the printk() output from the app during boot. I also get similar output (including the ring buffer full spamming) when running this application on the dongle, but it stops after the "Initializing..." output from the sensor_server part of the code.

I am using:
Windows 10
nRF Connect for Desktop v3.12.0
ncs toolchain v2.20
zephyr v 3.2.99
nRF52840 DK v3.0.0 2022.34
nRF52840 Dongle v2.1.1 2022.37

So there are two issues:

1) What is preventing the sensor_ samples from running on the dongle? This should be easily reproducible by building and flashing the samples out of the box to a dongle with no changes except choosing the correct board.

2) Any suggestions on how to get rid of the console spamming during boot with the new combined application? I have googled and tried some of the suggestions from others having similar issues, but to no avail.

Parents
  • Hello Ove, and thank you for your patience.

    So there are several things that can make it difficult to use the Dongle for development, as opposed to a development kit. One thing is flashing, that you can circumvent by essentially doing a DFU with the Programmer App. This takes advantage of the legacy nRF5 SDK bootloader that comes with the Dongle, that can swap one image with another. Though it doesn't really read the flash, nor delete it if that was something you would need to do.

    The first issue you might run into then is getting the new image to fit into this old bootloader set-up. Here you have the bootloader in red, app in green, and MBR in yellow. NCS automatically know that you want to move the application up to 0x1000 when you build for the Dongle - though it doesn't know about the Bootloader placed on the top. Having the bootloader there is rarely a problem, unless you are planning on using that space for another partition. Which is what you are when running a Mesh sample, which needs a settings partition for provisioning.

    app:
      address: 0x1000
      end_address: 0xf8000
      region: flash_primary
      size: 0xf7000
    nrf5_mbr:
      address: 0x0
      end_address: 0x1000
      placement:
        after:
        - start
      region: flash_primary
      size: 0x1000
    settings_storage:
      address: 0xf8000
      end_address: 0x100000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x8000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000
    

    The Mesh light sample genereates this partitions.yml file, which shows that it wants to place the settings partition at 0xf8000. We can overrule this by creating a 'pm_static.yml' which we move out of the build folder and into our project. We can here move our settings storage someplace else. 

    app:
      address: 0x1000
      end_address: 0xD8000
      region: flash_primary
      size: 0xD7000
    nrf5_mbr:
      address: 0x0
      end_address: 0x1000
      placement:
        after:
        - start
      region: flash_primary
      size: 0x1000
    settings_storage:
      address: 0xD8000
      end_address: 0xE0000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x8000
    legacy_bootloader_storage:
      address: 0xE0000
      end_address: 0x100000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x20000  
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000
    

    Now it should be possible to run and provision the Mesh samples. Though before you do, remember that you can't delete anything using the DFU Flashing with the Programmer app. So, if you do want to re-provision the nodes, or if the node thinks that the data in the settings partition has gone bad, I don't think you will be able to do anything about it without using an external programmer. Or what you can do, is to somehow erase this data programmatically.

    Regards,

    Elfving

  • I just want to share a trick for anyone by mistake did not reset the node during unprovisioning using the NRF52840 usb dongle. As mentioned by Elfving, the bootloader/DFU can not erase the `settings_storage` section. 

    Not resetting the node from the Mesh mobile App will leave the setting and prevent the dongle to show in the scanning list. To solve this either one on of the following need to be followed: 

    1- Using external programmer. This is not desirable for most of us. 

    2- Erase the `settings_storage` section using a dummy firmware with calling erasing APIs. This is complicated solutions. 

    3- Modifying the start address of `settings_storage` section from the old start address  0xD8000 -> to a new one .i.e 0xD0000. 

    The modified pm_static.yml to the Elfving's would be: 

     

    app:
    address: 0x1000
    end_address: 0xD0000
    region: flash_primary
    size: 0xCF000
    nrf5_mbr:
    address: 0x0
    end_address: 0x1000
    placement:
    after:
    - start
    region: flash_primary
    size: 0x1000
    settings_storage:
    address: 0xD0000
    end_address: 0xE0000
    placement:
    align:
    start: 0x1000
    before:
    - end
    region: flash_primary
    size: 0x10000
    legacy_bootloader_storage:
    address: 0xE0000
    end_address: 0x100000
    placement:
    align:
    start: 0x1000
    before:
    - end
    region: flash_primary
    size: 0x20000
    sram_primary:
    address: 0x20000000
    end_address: 0x20040000
    region: sram_primary
    size: 0x40000

  • bt_mesh_reset() works for me, but make sure only if the call is made after ble and mesh has been initialized the settings are removed from the storage partition.

    int main(void)
    {
    	enable_usbcdc();
    	console_init();
    	int err;
    
    	printk("Initializing...\n");
    	
    	err = bt_enable(bt_ready);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    	}
    	k_sleep(K_MSEC(2000));
    	printk("delete flash? y/n\n");
    	uint8_t c = console_getchar();
    	if (c == 'y') {
    		printk("deleting flash\n");
    		erase_flash_area();
    	} else {
    		printk("not deleting flash: %c\n", c);
    	}
    
    	return 0;
    }

    I use usb-cdc to output to the vcom console of the dongle.

  • Hello Boris,

    As this is a somewhat older case now, it would great if you could open a new case with this question.

    Regards,

    Elfving

  • Thanks, but I found out the answer, I edited my previous post accordingly for anyone with the same issue.

  • First of all, I would really like to thank all of you in this thread for it has been extremely useful for me and the dev team I'm working in to solve these dongle-related problems. Jfc I just want to add a couple other insights to what   and   said:

    In the official sample for bt mesh light there's already a snippet of code including bt_mesh_reset. This being said, using the standard configurations, it doesn't fully reset the state of a node. This is because, as the documentation says, for the node to result unprovisioned it must call the bt_mesh_prov_enable which, technically, is the next instruction in the function.

    This being said, though, checking the provisioned state after a couple seconds returns a positive answer, the node is still provisioned. This is because, as the comment in the sample says,

    /* This will be a no-op if settings_load() loaded provisioning info */

    Therefore, for bt_mesh_reset to fully work you must set CONFIG_BT_SETTINGS=n in the prj.conf file.

    I find this solution to be very clean so I wanted to share it with you, hoping not to be redundant.

    Thank you  ,   and everyone for this thread.

    Edit: by setting the configuration macro CONFIG_BT_SETTINGS=n we avoid loading settings, but at the same time we also avoid storing settings, resulting in a clean factory state each time the device is rebooted. To avoid this on the dongle, we figured out that it is possible to reset the state of the dongle by calling bt_mesh_reset after having called load_settings. For some reason bt_mesh_reset doesn't store the fresh changes onto a persistent state so if the function is called before load_settings, this would not result in a reset since the latter function call would just restore the previous settings.

Reply
  • First of all, I would really like to thank all of you in this thread for it has been extremely useful for me and the dev team I'm working in to solve these dongle-related problems. Jfc I just want to add a couple other insights to what   and   said:

    In the official sample for bt mesh light there's already a snippet of code including bt_mesh_reset. This being said, using the standard configurations, it doesn't fully reset the state of a node. This is because, as the documentation says, for the node to result unprovisioned it must call the bt_mesh_prov_enable which, technically, is the next instruction in the function.

    This being said, though, checking the provisioned state after a couple seconds returns a positive answer, the node is still provisioned. This is because, as the comment in the sample says,

    /* This will be a no-op if settings_load() loaded provisioning info */

    Therefore, for bt_mesh_reset to fully work you must set CONFIG_BT_SETTINGS=n in the prj.conf file.

    I find this solution to be very clean so I wanted to share it with you, hoping not to be redundant.

    Thank you  ,   and everyone for this thread.

    Edit: by setting the configuration macro CONFIG_BT_SETTINGS=n we avoid loading settings, but at the same time we also avoid storing settings, resulting in a clean factory state each time the device is rebooted. To avoid this on the dongle, we figured out that it is possible to reset the state of the dongle by calling bt_mesh_reset after having called load_settings. For some reason bt_mesh_reset doesn't store the fresh changes onto a persistent state so if the function is called before load_settings, this would not result in a reset since the latter function call would just restore the previous settings.

Children
No Data
Related