BLE Central and Mesh

Hi,

I want to implement a system in which a thingy:53 will scan for beacons, gets their RSSI value and publishes them to a mesh network using custom models.

Then I want to use a RPi 4B to get these values and publish them to a cloud.

Can anyone guide me and let me know where I should start and steps to follow.

Regards,
Jeason

Parents
  • Hi,

    In Mesh, All messages delivered to the model handlers carries the RSSI information in bt_mesh_msg_ctx passed to the handler. You can inspect https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/connectivity/bluetooth/api/mesh/msg.html#c.bt_mesh_msg_ctx for more details.

    Using this information together with our guide for creating custom models you can write your own model similar to the RSSI model from nRF5 SDK

    Regarding how to get this up on a cloud you will have to think about what cloud you're aiming to use and what communication you aim to use. Unless you will be using nRF Cloud, we have limited resources available for how to do this, but you might find some inspiration or other developers who have done so on the Zephyr discord forum. See the community tab at https://www.zephyrproject.org/# for a link to the discord

     

    Kind regards,
    Andreas

  • Thanks for the reply Andreas.

    The thing is, the beacon I am using is not a mesh compatible device. It is a Minew B7 tag which has a n52810 chip.

    I created a custom model for RSSI in thingy:53, but when I try to get rssi values by scanning for ble devices, it gives me a Socket already connected error.

  • Jeason said:
    As far as I know the thingy has a nRF5340 chip and it supports both Mesh and BLE concurrently.

    Yes, that is correct. I should've been more specific. What I meant is if your application supports both protocols concurrently

    Thank you for clarifying. I will dig around some and see if I can find an answer to your questions

    I will get back to you when I know some more

    Kind regards,
    Andreas

  • In my application I have enabled mesh and observer role in the prj.conf file. I don't really know what else to configure in my application to concurrently use both protocols at the same time.

    Since I did not know if my custom model has having the issue I was using the sensor model and instead of getting the sensor value, I initiate a BLE scan, gets RSSI of one beacons and pass that to rsp->val1.

    But this also gave me the same error. However if I give a bt_le_scan_stop() command before I initiate my scan it does not give me an error and I am getting my reading on the nrF mesh iOS app.

    # Use deferred logging
    CONFIG_NCS_SAMPLES_DEFAULTS=n
    CONFIG_LOG=y
    CONFIG_ASSERT=y
    CONFIG_ASSERT_NO_COND_INFO=y
    CONFIG_ASSERT_NO_MSG_INFO=y
    
    # General configuration
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    CONFIG_FLASH=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_NVS_LOOKUP_CACHE=y
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_NVS_NAME_CACHE=y
    CONFIG_HWINFO=y
    CONFIG_DK_LIBRARY=y
    CONFIG_PM_SINGLE_IMAGE=y
    CONFIG_PM_PARTITION_SIZE_SETTINGS_STORAGE=0x8000
    CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE=y
    
    # Temperature sensor
    CONFIG_SENSOR=y
    CONFIG_BME680=y
    
    # Bluetooth configuration
    CONFIG_BT=y
    CONFIG_BT_CENTRAL=y
    CONFIG_BT_COMPANY_ID=0x0059
    CONFIG_BT_DEVICE_NAME="Mesh Sensor"
    CONFIG_BT_L2CAP_TX_MTU=498
    CONFIG_BT_L2CAP_TX_BUF_COUNT=8
    CONFIG_BT_BUF_ACL_TX_SIZE=37
    CONFIG_BT_OBSERVER=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_SETTINGS=y
    CONFIG_BT_SCAN=y
    CONFIG_BT_FILTER_ACCEPT_LIST=y
    
    # Disable unused Bluetooth features
    CONFIG_BT_PHY_UPDATE=n
    
    # Bluetooth mesh configuration
    CONFIG_BT_MESH=y
    CONFIG_BT_MESH_RELAY=y
    CONFIG_BT_MESH_FRIEND=y
    CONFIG_BT_MESH_ADV_BUF_COUNT=13
    CONFIG_BT_MESH_TX_SEG_MAX=10
    CONFIG_BT_MESH_PB_GATT=y
    CONFIG_BT_MESH_GATT_PROXY=y
    CONFIG_BT_MESH_PROXY_USE_DEVICE_NAME=y
    CONFIG_BT_MESH_DK_PROV=y
    CONFIG_BT_MESH_SUBNET_COUNT=2
    CONFIG_BT_MESH_APP_KEY_COUNT=3
    CONFIG_BT_MESH_CRPL=32
    CONFIG_BT_MESH_MSG_CACHE_SIZE=64
    
    # Bluetooth mesh models
    CONFIG_BT_MESH_SENSOR_SRV=y
    CONFIG_BT_MESH_ONOFF_SRV=y
    CONFIG_BT_MESH_SENSOR_SRV_SENSORS_MAX=5
    

  • Hi again,

    Jeason said:
    In my application I have enabled mesh and observer role in the prj.conf file. I don't really know what else to configure in my application to concurrently use both protocols at the same time.

    If you haven't done so already, you could have a look at https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/samples/bluetooth/mesh/ble_peripheral_lbs_coex/README.html and modify this so it acts as a central instead of a peripheral and test if that works or to validate that you've configured everything correct by examining that sample. 

    I'm waiting for a reply from the developers regarding if it is possible to modify the peripheral coexistence sample to be a central instead, but I suspect there are some considerations that you need to make. One item is that you may get some degradation of the Mesh network as the device needs to act as a BLE Central and scan for the nodes instead of listening to the Mesh network as a mesh device. But with moderate

    BLE activity I believe this should be possible. 

    Jeason said:
    But this also gave me the same error. However if I give a bt_le_scan_stop() command before I initiate my scan it does not give me an error and I am getting my reading on the nrF mesh iOS app.

    Could you post the section of the code for the case where you have a successful scan?

    Kind regards,
    Andreas

  • void update_scan_filter(void)
    {
        int err;
    
        err = bt_le_filter_accept_list_clear();
        if (err) {
            printk("Clear filter on device address error: %d\n", err);
        }
        static bt_addr_le_t m_dev_address_tag1 =
        {
            .type   = BT_ADDR_LE_PUBLIC,
        };
        memcpy(m_dev_address_tag1.a.val, tag1ID, BT_ADDR_SIZE);
    
        err = bt_le_filter_accept_list_add(&m_dev_address_tag1);
        if (err) {
            printk("Set filter on device address error: %d\n", err);
        }
    
    
    
    }
    
    
    
    
    
    static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
                 struct net_buf_simple *ad)
    {
        char addr_str[BT_ADDR_LE_STR_LEN];
        if (type != BT_GAP_ADV_TYPE_ADV_IND &&
            type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
            return;
        }
    
        bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
        printk("Device found: %s (RSSI %d)\n", addr_str, rssi);
        Rssi = rssi;
        bt_le_scan_stop();
    }
    
    static void start_scan(void)
    {
        int err;
    
        bt_le_scan_stop();
        update_scan_filter();
    
        struct bt_le_scan_param param ={
            .type = BT_LE_SCAN_TYPE_PASSIVE,
            .options = BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST,
            .interval = BT_GAP_SCAN_FAST_INTERVAL,
            .window = BT_GAP_SCAN_FAST_WINDOW,
        };
        err = bt_le_scan_start(&param, device_found);
        if (err) {
            printk("Scanning failed to start (err %d)\n", err);
            return;
        }
    
        printk("Scanning successfully started\n");
    }
    
    int AmbientTemperatureGet(struct bt_mesh_sensor_srv *srv,
                 struct bt_mesh_sensor *sensor,
                 struct bt_mesh_msg_ctx *ctx,
                 struct sensor_value *rsp)
    {
    
    
        start_scan();
       
        rsp->val1 = Rssi;
        rsp->val2 = 0;
        return 0;
       
    }

  • Hi,

    I've discussed this with the Mesh team.

    First of, the stop scan is necessary as you can't start another scanning since the Mesh stack already has one ongoing. This is the reason for why you need to stop it using bt_scan_stop(). 

    The second thing is that we have another option for you. Rather than configuring the device as a Mesh + BLE central, you can register another callback using bt_le_scan_cb_register and read the RSSI value from the struct bt_le_scan_recv_info structure.

    In addition using acceptance filters you will create conflicts in the Mesh

    So in other words, unless you specifically need BLE Central features, this other option is what we recommend

    Kind regards,
    Andreas

Reply
  • Hi,

    I've discussed this with the Mesh team.

    First of, the stop scan is necessary as you can't start another scanning since the Mesh stack already has one ongoing. This is the reason for why you need to stop it using bt_scan_stop(). 

    The second thing is that we have another option for you. Rather than configuring the device as a Mesh + BLE central, you can register another callback using bt_le_scan_cb_register and read the RSSI value from the struct bt_le_scan_recv_info structure.

    In addition using acceptance filters you will create conflicts in the Mesh

    So in other words, unless you specifically need BLE Central features, this other option is what we recommend

    Kind regards,
    Andreas

Children
Related