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

How to retrieve Value from multiple Characteristics based Service Handler p_ble_evt->header.evt_id.?

Hi,

 I have one service UUID ffe0 that has two characteristics: one of has UUID ffe4 use for "notify" and other one has UUID ffe5 use for "write and read".

Now i want to get the data from the FFE5 and reply accordingly as per the data that I received from FFE5 suppose I write send data from mobile App to board is "SEND=1" as string to characteristic  UUID FFE5 now according to the message received from the FFE5 service i.e. SEND=1 I want to reflect the characteristic UUID FFE4 as "OK" if the string matches as SEND=1. Now My main Question is How i know when the data is being received from FFE5 characteristic UUID. If I get that as an interrupt or anything I will send a reply as "OK" over the characteristic  UUID FFE4.

I have also created NRF_SDH_BLE_OBSERVER for that service.

But how to get value from the different characteristics UUID like 0xFFE5 and so forth if any .

	switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                p_our_service->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                break;
            case BLE_GAP_EVT_DISCONNECTED:
                p_our_service->conn_handle = BLE_CONN_HANDLE_INVALID;
                break;
            default:
                // No implementation needed.
                break;
        }
        
        


Thanks in advance.

Parents
  • Hello,

    I suggest that you check out the ble_app_uart example, which works pretty much the way that you describe. There is one characteristic for notifications, and one with write (not read).

    Check out how ble_nus.c generates the event BLE_NUS_EVT_RX_DATA from the BLE_GATTS_EVT_WRITE event in ble_nus_on_ble_evt()

    ble_nus_on_ble_evt() is assigned through NRF_SDH_BLE_OBSERVER(), probably like you have done.

    BR,

    Edvin

Reply
  • Hello,

    I suggest that you check out the ble_app_uart example, which works pretty much the way that you describe. There is one characteristic for notifications, and one with write (not read).

    Check out how ble_nus.c generates the event BLE_NUS_EVT_RX_DATA from the BLE_GATTS_EVT_WRITE event in ble_nus_on_ble_evt()

    ble_nus_on_ble_evt() is assigned through NRF_SDH_BLE_OBSERVER(), probably like you have done.

    BR,

    Edvin

Children
  • Thank you @Edvin for your prompt reply,

    I will surely look into the example code ble_app_uart  and will let you know over here about how it will fit and work it out in my application.



  • As a pointer, it will be all about using the BLE_GATTS_EVT_WRITE and check what is written (whether it is CCCD change, which would be to enable notifications or a write to the RX characteristic), and passing it on to the BLE_NUS_EVT_RX_DATA event in main. 

    I did a small course once, which followed this tutorial. This one forwards the notification enabled and notification disabled events to main.c, but the method is pretty much the same. Check out "Step 8" from the guide if you need more input than the ble_app_uart example gives.

    BR,

    Edvin

  • OK thanks Really Appreciated !

    I will surely look in to that and get hands on with it!

  • I have made certain changes in the code that you suggested to go through for the quick checking I bypass the app_uart_put that is sending the received data from  Nordic UART BLE Service to UART and instead according to my application I fetch it for my purpose and got trigger for new data as I just wanted for my application explained above and send that received bytes from nus_data_handler over BLE TX Service as Notification.

    As per below code :

    static void nus_data_handler(ble_nus_evt_t * p_evt)
    {
    
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        if (p_evt->type == BLE_NUS_EVT_RX_DATA)
        {
            uint32_t err_code;
    
            NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
            NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
    /* Do Not Send to UART 
            for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
            {
                do
                {
                    err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
                    if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                    {
                        NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                        APP_ERROR_CHECK(err_code);
                    }
                } while (err_code == NRF_ERROR_BUSY);
            }
            if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r')
            {
                while (app_uart_put('\n') == NRF_ERROR_BUSY);
            }
     */
    
    
                do
                {
                    uint16_t length = (uint16_t)p_evt->params.rx_data.length;
                    memcpy(data_array , p_evt->params.rx_data.p_data, length);
                    err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
                    if ((err_code != NRF_ERROR_INVALID_STATE) &&
                        (err_code != NRF_ERROR_RESOURCES) &&
                        (err_code != NRF_ERROR_NOT_FOUND))
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                } while (err_code == NRF_ERROR_RESOURCES);
        }
    
    }



    Is this way correct, as such i am half way instead of bridging the same data i want to analysis the received data from the BLE_NUS_EVT_RX_DATA and then after this I will call ble_nus_data_send .


    Please check the same so that it will get verified from your end also for future use.

    Thanks in advance

  • Looks good!

    One tiny thing you can look into if you want to power optimize your application (minor detail). 

    Your do{} while() loop will make sure that the packet is sent in a proper way. However, if you ever get the NRF_ERROR_RESOURCES return value, you will not allow the chip to go to sleep before it returns NRF_SUCCESS. To further optimize this, you can save the data in some array in your application, leave the event, and then retransmit it on the next BLE_GATTS_EVT_HVN_TX_COMPLETE (you can add this event to your main.c's ble_evt_handler()).

Related