Time managing data from several peripherals - BLE over uart

Hello everyone,

I am working with the SDK v17.1.0 with the DK nRF52832 with the examples of ble_app_uart and ble_app_uart_c.

I managed to implement a multilink communication of BLE over UART with two peripherals and a central. 

Each peripheral is sending 6 frames of 18 bytes of data. My issue is that when I print the received data in the central console, some frames of the first peripheral are intermingled with some frames of the second peripherals. 

I would like to add a temporal sequencing to receive the data from the first peripheral first, and then allows to receive the data from the second peripheral. 

I need to implement this in the Central code in the ble_nus_chars_received_uart_print function but I don't know how? 

Any ideas?

Thank you for your time and help!

Vincent

  • Hi,

    The BLE_NUS_C_EVT_NUS_TX_EVT is generated when data is received from a peer regardless of which peer that is sending the data. To only print data from one peer at a time, you could declare two buffers of 6*18 bytes for each peer and only print them when the buffer has been filled. The event structure will contain the connection handle which you can use to differentiate between the two peers.

    regards

    Jared 

  • Hello, thank you for the answer. 

    I work with only 2 peripherals but I could have around 20 peripherals in my future development. 

    Do you think it could be an idea to create as many buffers as perripherals connected? 

    If so, that means I could create a for loop in the ble_nus_c_evt_handler in the BLE_NUS_C_EVT_NUS_TX_EVT case, where, for each handle, I would print the buffer associated to each peer?

  • Hmm, maybe it isn't the best solution for many connections. You shouldn't have to have a for loop in the ble event handler. You only need to direct ble_nus_chars_received_uart_print() to the data buffer when it has been filled and provide the buffer length. 

  • So I would have a buffer declared in the function ble_nus_chars_received_uart_print() common to all the peer, and while this buffer is not filled with the data, I would block any other data to be put in the uart? (through app_uart_put). 

    like: 

    uint8_t buffer[107];

    const uint8_t buffer_length = sizeof(buffer);

    memset(buffer, 0 , buffer_length);

    while (buffer[107] != \n) { //because the data will end with a \n

            for (uint32_t i = 0; i < data_len; i++)
            {
                 do
                 {
                      ret_val = app_uart_put(p_data[i]);
                      buffer[i] = p_data[i];
                      if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
                       {
                             NRF_LOG_ERROR("app_uart_put failed for index 0x%04x.", i);
                             APP_ERROR_CHECK(ret_val);
                       }
                  } while (ret_val == NRF_ERROR_BUSY);
            }

    }

  • I was thinking that you could have a global buffer for each peer and fill the corresponding buffer when your receive data from a peer. You check the size of the buffer each time you fill and if it's full then you print it out.. Again, this would not be quite optimal memory wise when you have a lot of peers.. 

Related