Mutlilink central with multiple different peripheral with different service advertisements

Hello, 

We are developing an application to work as a multilink central with 3 different kind of BLE devices that include 1 custom device which advertise customised NUS service, 1 Polar belts which advertise HRS, BAS and DIS services and 1 EMG sensors which has a single notification service.

We would like to connect 6 custom device, 6 polar belts (of any kind such as Polar Belt H10, H7 etc) and 4 EMG sensors at the same time (or any configuration of such). 

We are using Nordic SDK v15 with NRF52840 but eventually it will be used on NRF52849 dongle. We have developed multilink central application for the dongle where each kind of devices separately can connect and send notifications to central. For these applications, we have taken reference from ble_app_multilink_central and ble_app_hrs_c and from ble/ble_services/ble_lbs_c, ble_hrs_c, ble_bas_c and ble_nus_c.

 

However, we are now trying to see if we can combine these 3 applications to make only 1 central. 

For testing purposes, we are only currently using one H10 Polar belt with one custom device for now. The problems we are facing are as follows: 

1) After registering 6 arrays for hrs_c, bas_c and nus_c, we need to assign handles in BLE_GAP_EVT_CONNECTED for each kind of services. The problem is that we don't know how to keep track of handles. Considering that Polar belt and custom device can have any addr value (in ble_gap_addr_t), the assignment of handle is  a problem. Is there any trick to keep track of handle assignment? The same thing goes when a specific device disconnects. I understand that a conn_handle is assign for each device in SoftDevice however, this does not tell us what kind of device it is?

2) After discovering the first custom device, the central application will find the polar belt (i.e. BLE_GAP_EVT_CONNECTED is triggered) but its service such as BLE_HRS_C_EVT_DISCOVERY_COMPLETE or BLE_BAS_C_EVT_DISCOVERY_COMPLETE events are never triggered. We are sure that we are doing correct assignment of handles i.e. ble_hrs_c_handles_assign or ble_bas_c_handles_assign in BLE_GAP_EVT_CONNECTED as we used device address with if-else conditions to check if the problem (1) is causing this. The NRF_DEBUG_LOG does not print any logs in case of polar belt after its discovery. 

Strangely enough, if the central is restarted with custom device 1 turned off, the Polar Belt HRS and BAS services are discovered and HRS notifications are received fully. 

3) We will eventually be using CDC ACM to send the data receive on each notification to each service for each device to the computer. Considering that the custom device sends a notification of 64 bytes / 100 m-secs, Polar Belt sends about 8 bytes / 1 secs and the EMG sensors sends 2 bytes / 100 m-secs , and that there will be 6+6+4 device connected (in worst case), what are the best possible way to structure the data and send it through CDC ACM in timely manner with possibly some device-id identifier for data-device recognition on our main PC-application? 

Looking forward for any suggestions/solutions. 

 

Thank you 

Parents
  • Hi

    1. If I recall correctly, the lowest connection handle that is free is always given to a new connection by the SoftDevice. The Multiperipheral application uses the Connection state Library to keep track of different connections and what state they're in, so I would suggest that you check out that library as well.

    2. The discovery issues you're having I think are due to the device trying to connect to the next device before discovery is completed on the central end. Please make sure that you wait for the COMPLETE events before you let the central application start scanning again. You can also use a sniffer trace if you're not getting it to work to see what is going on over the air. That might help us pinpoint what exactly is going wrong.

    3. I guess this would be mostly up to you as we don't have a specific "how to" on this. I would think forwarding the data to CDC ACM and the computer whenever it's incoming with as you say with a way to identify the data (device id or name for example).

    Best regards,

    Simon

Reply
  • Hi

    1. If I recall correctly, the lowest connection handle that is free is always given to a new connection by the SoftDevice. The Multiperipheral application uses the Connection state Library to keep track of different connections and what state they're in, so I would suggest that you check out that library as well.

    2. The discovery issues you're having I think are due to the device trying to connect to the next device before discovery is completed on the central end. Please make sure that you wait for the COMPLETE events before you let the central application start scanning again. You can also use a sniffer trace if you're not getting it to work to see what is going on over the air. That might help us pinpoint what exactly is going wrong.

    3. I guess this would be mostly up to you as we don't have a specific "how to" on this. I would think forwarding the data to CDC ACM and the computer whenever it's incoming with as you say with a way to identify the data (device id or name for example).

    Best regards,

    Simon

Children
  • Hi, 

    1) Your suggestion for connection state library seems really good. Thank you, I will check it out. 

    2) You are right, I did start scanning again in the BLE_GAP_EVT_CONNECTED & in BLE_GAP_EVT_DISCONNECTED  instead of SERVICE_DISCOVERY_COMPLETED events (either for HRS, BAS, NUS or LBS) - bad copy/paste on my end. :) 

    I re-checked the application code and managed to connect to 1 Polar belt, 2 EMG and 2 custom devices at the same time. 

    However, I am having a hard time reconnecting to the device if I disconnect the peripheral by powering it down and powering it up again.

    I am using the following services for each type of device: 

    Custom Device -> NUS Service (with modified UUIDs)

    Polar Belt -> HRS & BAS Service 

    EMG -> LBS Service (with modified UUIDs).

    I am restarting scanning in each service discovery completed event. However, the problem is that Polar Belt has 2 services so the nrf_ble_scan_start function is called probably twice and when I try to reconnect another peripheral, it won't reconnect. 

    I tested the above situation by not using the Polar Belt and just using the other two types of devices. 

    So my question is how can I check if the scanning is already in process and if it is, I do not call the nrf_ble_scan_start again. Is there an internal state that keeps track of the scanning mode?

    3) Actually we tried to send the data as soon as possible i.e. whenever the central receive notification from one of the device, we check if the cdc_acm_port is open, and if it is, we send the data. However, considering that the custom device sends data at 64-bytes / 100 m-secs and there can be up to 6 devices, this became a problem even when we only developed a multilink central application for the custom device. It may be that the 2 device sends notification with short period of time apart and that can cause the port to close (as far as I understand) and on our software device, the time sync for the data becomes a mess. 

    I was hoping that there might be a queue-dequeue class/library already implemented in the Nordic SDK which I can use along with a timer to repeatedly send 64 * 6 * 10 (6 custom device notifications) + 8 * 6 (6 Polar Belts notifications) + 2 * 10 * 6 (4 EMG sensors notifications) = 4008 bytes + device identifiers bytes / second? 

    Thank you

    Best regards,

    arsh

  • Hi, 

    These are the errors on logs when I use peer manger (merged from HRS_C example) in a loop.

    <info> app_timer: RTC: initialized.
    <error> app: RNG context cannot be allocated on the stack.
    <error> nrf_ble_lesc: nrf_crypto_init() returned error 0x8515.
    <error> peer_manager: pm_init failed because sm_init() returned Unknown error code.
    <error> app: Fatal error
    <warning> app: System reset

    When I do not use the Peer Manager, I face the reconnection issue. As you can see from the logs, the Polar H10 band was found again and after that I am unable to reconnect any device.

    <info> app: --------  Start here -------
    <info> app: Multilink example started.
    <info> app_timer: RTC: initialized.
    <info> app: Scanning Started...
    <info> app: Device Name: ANR Corp M40V found in advert data
    <info> app: Scan event connected
    <info> app: Discovering serivces for ANR Corp EMG
    <info> app: DB DISCOVERY FOR  found for 0
    <info> app: DB Discovery error code: 0x0
    <info> app: LBS discovered on conn_handle 0x0
    <info> app: Scanning Started...
    <info> app: Device Name: Polar H10 B184ED2BV found in advert data
    <info> app: Scan event connected
    <info> app: Discovering serivces for Polar Belt
    <info> app: DB DISCOVERY FOR  found for 1
    <info> app: DB Discovery error code: 0x0
    <info> app: Scanning Started...
    <info> app: Scanning Started...
    <info> app: Device Name: ANR Corp M40V found in advert data
    <info> app: Polar Battery     Link:  0x1     Data: 100 %.
    <info> app: Scan event connected
    <info> app: Discovering serivces for ANR Corp EMG
    <info> app: DB DISCOVERY FOR  found for 2
    <info> app: DB Discovery error code: 0x0
    <info> app: LBS discovered on conn_handle 0x2
    <info> app: Scanning Started...
    <info> app: Device Name: Polar H10 B184ED2Bk found in advert data

Related