This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Heart Rate collector example - how is it suppose to work?

Hi, 

i'm running the Heart Rate collector example and have a question. What is the expected behaviour? From the description on the infocenter I read that it should print out the HR reading from the connected HRM. And while it does so the first time I run it on a fresh dongle, it doesn't do it the next time or any other time for that matter. I cannot figure out the difference and don't know what is going on. The following runs only print out the following info on the log:

00> <info> app_timer: RTC: initialized.
00> 
00> <info> app: Heart Rate collector example started.
00> 
00> <info> app: Starting scan.
00> 
00> <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update, no change
00> 
00> <info> app: Connected.
00> 
00> <info> app: GATT ATT MTU on connection 0x0 changed to 23.
00> 
00> <info> peer_manager_handler: Connection secured: role: Central, conn_handle: 0, procedure: Encryption
00> 
00> <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update, no change
00> 
00> <info> app: Data length for connection 0x0 updated to 27.
00> 
00> <info> peer_manager_handler: Connection secured: role: Central, conn_handle: 0, procedure: Encryption
00> 
00> <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update, no change
00> 
00> <info> app: Battery Level Read as 85 %.

PS: I use the NRF52 dongle together with a j-link debugger and I'm displyaing the logs via RTT. I use the example from the SDK 17.0.2, with SD 340.

  • Hi Lukasz, 

    Sorry for late response it was our public holiday on Monday. 

    Could you please send the sniffer trace when you use the nRF Connect app to connect to the Heart Rate Monitor ? 

     

    dragilla said:
    The app sends the write request and the hrm receives it, but ther is no response.

    Could you explain this ? I can see there is a write response in the screenshot you showed.  
    I suspect that there could be an issue on when you send the write request to the CCCD to enable notification. You may need to wait until it bonded before you enable notification. 

  • Could you please send the sniffer trace when you use the nRF Connect app to connect to the Heart Rate Monitor ? 

    Sure. I'm attaching the file.

    nordic ble vs garmin_hrm_dual.pcapng

    Could you explain this ? I can see there is a write response in the screenshot you showed.  
    I suspect that there could be an issue on when you send the write request to the CCCD to enable notification. You may need to wait until it bonded before you enable notification.

    Yes, sorry. There is a reponse but no HR i sent "in response". This is what I ment.

    Please remember that this is an example from the SDK17.0.2. I have not modified anything there (well almost, I just turned on RTT and switched off UART).

    Anywyays. I tried skipping the bonding. It doesn't change the behaviour.

  • Hi Lukasz, 

    The HRS_C was made to test with the HRM example. It was not made to work with all the HRM on the market as there could be incompatibility issue. (even thought BLE standard was created to avoid such incompatibility)

    Please confirm that you can use the HRM_C with the HRM example in the SDK . 

    Regarding your concern about " BLE_HRS_C uses Generic Attribute Profile (0x1801):" it was just the interpretation of wireshark of the handle 0x0028 based on the service discovery process. I'm not sure why it confused and say it's Generic Attribute Profile when it's obviously not. 
    From what I can see the command to enable notification are the same between the two traces:

    Same with the response. 

    So I'm not so sure why the Garmin didn't send the notification. 
    You may need to modify the HRM so that it would behave as similar as nRF Connect to make the Garmin HRM works. 

    I can see that in the hrs_c there was MTU request and LL_LENGTH_REQ, you can try to turn that off in the HRS_C firmware. Turn off pairing as well. 

    Try to match as much as possible to the nRF Connect trace. 

    The service discovery I don't think would cause any difference here. 

  • I can see that in the hrs_c there was MTU request and LL_LENGTH_REQ, you can try to turn that off in the HRS_C firmware. Turn off pairing as well. 

    Can you please give me a hint where I shoul look for it? How to turn it off?

    In the mean time I will try to make the HRS app work.

    edit: I think I found it. In function nrf_ble_gatt_on_ble_evt:

    void nrf_ble_gatt_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
    {
        nrf_ble_gatt_t * p_gatt      = (nrf_ble_gatt_t *)p_context;
        uint16_t         conn_handle = p_ble_evt->evt.common_evt.conn_handle;
    
        if (conn_handle >= NRF_BLE_GATT_LINK_COUNT)
        {
            return;
        }
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                on_connected_evt(p_gatt, p_ble_evt);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                on_disconnected_evt(p_gatt, p_ble_evt);
                break;
    
            case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
                on_exchange_mtu_rsp_evt(p_gatt, p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
                on_exchange_mtu_request_evt(p_gatt, p_ble_evt);
                break;
    
    /*#if !defined (S112) && !defined(S312) && !defined (S122)
            case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
                on_data_length_update_evt(p_gatt, p_ble_evt);
                break;
    
            case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
                on_data_length_update_request_evt(p_gatt, p_ble_evt);
                break;
    #endif // !defined (S112) && !defined(S312) && !defined (S122)
    */
            default:
                break;
        }
    /*
        if (p_gatt->links[conn_handle].att_mtu_exchange_pending)
        {
            ret_code_t err_code;
    
            err_code = sd_ble_gattc_exchange_mtu_request(conn_handle,
                                                         p_gatt->links[conn_handle].att_mtu_desired);
    
            if (err_code == NRF_SUCCESS)
            {
                p_gatt->links[conn_handle].att_mtu_exchange_pending   = false;
                p_gatt->links[conn_handle].att_mtu_exchange_requested = true;
    
                NRF_LOG_DEBUG("Requesting to update ATT MTU to %u bytes on connection 0x%x (retry).",
                              p_gatt->links[conn_handle].att_mtu_desired, conn_handle);
            }
            else if (err_code != NRF_ERROR_BUSY)
            {
                NRF_LOG_ERROR("sd_ble_gattc_exchange_mtu_request() returned %s.",
                              nrf_strerror_get(err_code));
            }
        }
    */
    }

    Same result :(

    edit2: Also, I think it's worth to note, that the Garmin has HAS the Body Sensor Location characteristic, just next to Hear Rate and the sniffer trace clearly shows an error (rcvd error response). So I think, that maybe this is the problem after all - the HRS_C is looking for both chars inside the "Gemeric Attribute Profile". I know they look the same as the Heart Rate char used by NRF Connect BLE, but there must be some difference that causes the problem. 

    edit3: I can confirm it works with the BLE_APP_HRS example. But It doesn't solve my problem.

  • Hi Lukasz, 

    You can remove the nrf_ble_gatt.h and .c module to avoid MTU request and data length exchange. 

    After you have done that, please try to compare the sniffer trace again. 

    Except for the service discovery process I don't see any difference. 

    If you can find away to not do service discovery from the phone (if devices are paired they wont do service discovery when reconnect) it would be even easier to match the activity from the hrs_c and the phone/PC. 

Related