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

BLE lost messages

Hi, as part of my project i have 2 nordic 52dks one as a pheripheral (sending) and on as a client (recieving). where i am sening a buffer of 8, in the order

buffer[0] = 10

buffer[1}= X gyro lsb

buffer[2] = X gyro msb

buffer[3] = y gyro lsb

buffer[4] = y gyro msb

buffer[5] = z gyro lsb

buffer[6] = z gyro msb

buffer[7] = 36   //terminator $

however sometimes i seem to lose a byte over ble such that the next byte received will be less and hence the order is correupted thus making processing rather and unpredictable for a large sample size like 1000000 samples.

how may i ensure that my ble settings are correct such that i ensure to limit this issue.

my code was based of the examples ble_app_uart and ble_app_uart_c for the peripheral and client respectivly.

thank u in advance 

Parents
  • Hello,

    however sometimes i seem to lose a byte over ble such that the next byte received will be less and hence the order is correupted thus making processing rather and unpredictable

    No byte is lost over the BLE link, it is not possible as the protocol uses the CRC field to verify that the contents of the packet is uncorrupted and received as it was sent. If the CRC does not match, the packet is discarded and not acknowledged - leading to a re-transmission of the same packet.
    If you would like to confirm the communication happening on-air between the devices you could use the nRF Sniffer tool to trace the communication and read the individual packet contents.

    How is your handling / processing of the received data? How are you alerted to the seemingly corrupted data? Have you checked whether the corrupted values could be what the peripheral intended to send?

    Looking forward to resolving this issue together!

    Best regards,
    Karl

  • Firstly i would like to thank you for your reply, and for the sniffer, is there any documentation on how to install this please?

    The way im checking that the data is being missed is through the uart terminal of the client (recieving) board and also i have a matllab script that is reading serially aswell. to check this i sent known data meaning sending 8 bytes (hex) 10-16 and a terminator 36.

    and as u can see in the first colomn its fine but then in the second colom the 12 didnt send or be recieved which will therefore mess up my data 

  • NikTheNordicUser said:
    yes i understood now, thank you

    Great! Thank you for confirming :) 

    NikTheNordicUser said:
    i changes some of the code and the error is now at line 911 and at this point i have the funcction app_error_chcek

    Yes, and which function return the error code that fails this APP_ERROR_CHECK? 

    NikTheNordicUser said:
    ideally i dont have any delays however by having a large enouugh delay it results in a less probability of the client mcu resetting.

    This is just treating the symptoms of the error - we should instead focus on identifying and resolving the root of the error itself.

    NikTheNordicUser said:
    what im not understanding is that the code im alteringis the pherihperal code but it seems that the client is the one being effected and resetting 

    Is the client encountering any errors? Are you saying that the code we are looking at right now is for the peripheral - but that the resetting happens on the central, and not on the peripheral?

    NikTheNordicUser said:

    this will thus result in a perfect harmony and would probably be the most efficient.

    i think that the interupt of a ble tx ready is called BLE_GATTS_EVT_HVN_TX_COMPLETE but im not sure where to place it and how to use it unfortunetly

    NikTheNordicUser said:
    and maybe i could somehow ensure that the tx buffer of the ble is empty such that i dont ever overfill and lose data

    Calling ble_nus_data_send queues data for sending as a notification during the next connection event. However, if you try to queue too many notifications too fast, the ble_nus_data_send function will return NRF_ERROR_RESOURCES, indicating that its buffer is full, and that the call to queue data failed.
    You may then use the BLE_GATTS_EVT_HVN_TX_COMPLETE event to know when a notification successfully has been sent - meaning that you may now queue another notification for transfer, because it is now room in the buffer.

    It is not really an issue to get the NRF_ERROR_RESOURCES, it just means that the call to queue data for transfer failed because the buffer is full. The returned error code lets us know that the program can not proceed as usual - instead, we must do some sort of error handling to bring the application back on track.

    Best regards,
    Karl

  • Yes, and which function return the error code that fails this APP_ERROR_CHECK?

    uint32_t err_code2 =ble_nus_data_send(&m_nus,send_buffer3, &length3, m_conn_handle);  line 910
    APP_ERROR_CHECK(err_code2); line 911

    Is the client encountering any errors? Are you saying that the code we are looking at right now is for the peripheral - but that the resetting happens on the central, and not on the peripheral?

    yes exactly that , the central doesnt seem to return error codes but when it resets it gets stuck in a nrf_breakpoint_condition 

    Calling ble_nus_data_send queues data for sending as a notification during the next connection event. However, if you try to queue too many notifications too fast, the ble_nus_data_send function will return NRF_ERROR_RESOURCES, indicating that its buffer is full, and that the call to queue data failed.
    You may then use the BLE_GATTS_EVT_HVN_TX_COMPLETE event to know when a notification successfully has been sent - meaning that you may now queue another notification for transfer, because it is now room in the buffer.

    can you maybe show me how i can do this , such that i can do a while loop to wait for the tx buffer to be sent to ensure i dont queue too many notifications. can you show me how i need to use it and wherre i need to place this event please.

    you think this could work?

  • NikTheNordicUser said:
    uint32_t err_code2 =ble_nus_data_send(&m_nus,send_buffer3, &length3, m_conn_handle);  line 910
    APP_ERROR_CHECK(err_code2); line 911

    Thanks. So, now we know both which function that returned the error, and which error it returned.
    Looking into the source code of ble_nus_data_send, we see that it forwards error codes from sd_ble_gatts_hvx. Then we check why the sd_ble_gatts_hvx would return the NRF_ERROR_RESOURCES error, the exempt from the API Reference reads:

    NRF_ERROR_RESOURCES Too many notifications queued. Wait for a BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.

    So we know that we need to wait for an BLE_GATTS_EVT_HVN_TX_COMPLETE event before we queue more data for transfer. We also read from the note section that the hvx_queue size can be changed to accommodate for more samples queued for transfer before the NRF_ERROR_RESOURCES is generated.
    What is your current size of BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT?
    If you know how many notifications will be queued between each connection event, you could set this buffer to at least be able to hold this number of notifications (plus a couple more for good measure in case of re-transmissions).

    NikTheNordicUser said:
    can you show me how i need to use it and wherre i need to place this event please.

    The ble_evt_handler is passed all the SoftDevice events. You could implement the logic for the BLE_GATTS_EVT_HVN_TX_COMPLETE here.

    Best regards,
    Karl

  • What is your current size of BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT?

    i found that in the ble_gatts.h (of the pheripheral code) it is set as 1

    You could implement the logic for the BLE_GATTS_EVT_HVN_TX_COMPLETE here.

    is it possible to maybe show me how ? please

  • NikTheNordicUser said:
    i found that in the ble_gatts.h (of the pheripheral code) it is set as 1

    So there is only space to queue 1 notification for transfer before you will generate the NRF_ERROR_RESOURCES.
    How many notifications do you intend to queue between each connection event?

    NikTheNordicUser said:
    is it possible to maybe show me how ? please
    Karl Ylvisaker said:
    The ble_evt_handler is passed all the SoftDevice events. You could implement the logic for the BLE_GATTS_EVT_HVN_TX_COMPLETE here.

    Add a case for this event into the ble_evt_handler, then implement the logic you would like to have happen when this event is generated. What do you intend to have happen when this event is generated?

    Best regards,
    Karl

Reply
  • NikTheNordicUser said:
    i found that in the ble_gatts.h (of the pheripheral code) it is set as 1

    So there is only space to queue 1 notification for transfer before you will generate the NRF_ERROR_RESOURCES.
    How many notifications do you intend to queue between each connection event?

    NikTheNordicUser said:
    is it possible to maybe show me how ? please
    Karl Ylvisaker said:
    The ble_evt_handler is passed all the SoftDevice events. You could implement the logic for the BLE_GATTS_EVT_HVN_TX_COMPLETE here.

    Add a case for this event into the ble_evt_handler, then implement the logic you would like to have happen when this event is generated. What do you intend to have happen when this event is generated?

    Best regards,
    Karl

Children
  • How many notifications do you intend to queue between each connection event?

    umm.. im not really sure is there a max value ? My application requires for fast transfer as i mentioned in the very begining the pheripheral board contains a gyro and acc sensor which communicates via spi and this pheripheral board sits on a motor such that i measure RPM in matlab after the hex data of sensor is sent via ble to the client pcb. is there a max number of queue as ideally meanwhile i am filling up the sending buffer with the spi data i would be sending a previously filled buffer. thats why i would like to monitor the ble gatts event tx complete flag such that i can remove all delays and ensure that data is fully sent and there are no queuse before i send another buffer

    im not sure if wat im saying is understandable.

  • NikTheNordicUser said:
    im not sure if wat im saying is understandable.

    I think I get the picture, but thank you for the understanding.

    NikTheNordicUser said:
    umm.. im not really sure is there a max value ?

    I dont think there is a max value other than the physical limitations of the SoC - i.e how much RAM do you have to spare?
    However, allocating everything that you have spare is not the best approach for this. Rather, you should look at how much that will actually be transferred in each interval.
    For example, how much throughput do you need to have all the necessary sensor data sent each second, and how much latency can you have in your system?
    If you group multiple measurements together up till the MTU size, and increase the connection event lengths, you will be able to send multiple larger packets per connection interval, for instance.
    But, in order to determine what configuration you should use, you need to know more exactly how many bytes you intend to transfer, and how often you intend to transfer them.
    You could take a look at the BLE throughput tables in the SoftDevice docuementation to determine the best connection parameters and configuration for your application.

    It could also be helpful for you to check out the the Online Power Profiler to visualize how each transfer will happen, with the different connection configurations.

    Please do not hesitate to ask if any part of my answer should be unclear!

    Best regards,
    Karl

  • ok so let say i want to have this configuration 

    is it possible to be shown how or what i would need to change. also as previously mentioned i would like to remove the delay such that i make it interrupt based and use the BLE_GATTS_EVT_HVN_TX_COMPLETE event which should ensure no resetting of the mcu .

    i would like to transfer a max of 242 bytes at once if possible with an output data rate of max 400 (the sesnor supports a data rate of 2000) but this setting should be enough for my application which setting do you suggest and the connection between the pheripheral and client is always active such that if theres data is constantly sent at the set settings

Related