Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Issue when calling "ble_nus_c_string_send" multiple times to send multiple single bytes

Hi,

I am using the ble_app_uart_c example for the ble_central of SDK 12.2.0 to send data over UART to a nrf52832 based peripheral. When following the format as suggested in the example everything appears to be working fine (terminate data to be sent with \n). I sucessfully sent commands with 60 bytes and \n terminated spread across 3 BLE packets at 20 bytes payload each.

However, when commenting out the section that tests for \n or size>20 bytes my code stops working (see attached code snippet). I am basically trying to force sending each individual byte,  not only when certain conditions are met. When sending small amounts (less than 5 bytes) it still works ok, but when sending more than 5 bytes the code seems to be stuck at line "while (ble_nus_c_string_send(&m_ble_nus_c, data_array, index) != NRF_SUCCESS)" and I am struggling to find out why. Could someone please point me in the right direction?

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint8_t index = 0;

    switch (p_event->evt_type)
    {
        /**@snippet [Handling data from UART] */
        case APP_UART_DATA_READY:
            UNUSED_VARIABLE(app_uart_get(&data_array[index]));
            index++;

            //if ((data_array[index - 1] == '\n') || (index >= (BLE_NUS_MAX_DATA_LEN)))
            //{
                while (ble_nus_c_string_send(&m_ble_nus_c, data_array, index) != NRF_SUCCESS)
                {
                    // repeat until sent.
                }
                index = 0;
            //}
            break;
        /**@snippet [Handling data from UART] */
        case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        default:
            break;
    }
}

Parents
  • Hi,

    It would be interesting to see what value ble_nus_c_string_send() returns if not NRF_SUCCSS. Maybe you can change your code to something like this, and then debug to find out:

    uint32_t err_code;
    do
    {
        err_code = ble_nus_c_string_send(&m_ble_nus_c, data_array, index);
    }while(err_code != NRF_SUCCESS);

    You can also add APP_ERROR_CHECK(err_code) between line 4 and 5 to have your code end up in an error handler and print your errors to a terminal. 

  • Hi Martin,

    thanks for your help. I changed my code to what you suggested and also added the APP_ERROR_CHECK(err_code). The error code is 0x3004 and the error handler prints this:

    0> SDH:DEBUG:sd_ble_enable: RAM start at 0x20001fe8
    0> BLE_DB_DISC:INFO:Starting discovery of service with UUID 0x1 for Connection handle 0
    0> BLE_DB_DISC:INFO:Found service UUID 0x1
    0> BLE_DB_DISC:INFO:Discovery of service with UUID 0x1 completed with success for Connection handle 0
    0> APP_ERROR:ERROR:Fatal

    Can you see from that what the issue is?

    Thanks

  • Hi,

    When I looked at your original code again I realized that you are not handling the index variable correctly. In your code index is initialized to 0. Then used to put your UART byte into an array. At line 11 index is incremented to 1 and then it is used as length of the string you want to transmit with ble_nus_c_string_send(). And then, at line 19 index is set to 0 again. And so it goes over and over. You will in other words never transmit more than 1 byte at the time.  I'm a little short of time so I haven't had the time to figure out why this seemingly causes everything to stall in an endless loop though. Anyway, you should try to implement some code that puts together a longer packet before you transmit the data. 

  • Hi,

    yes my intention is to send single bytes. The problem is that my payload does not have a termination character and also does not have a fixed length. Therefore I don't know how many bytes are going to be sent and it is possible that my payload consists of only one byte.

  • Hi,

    Sorry for the long wait. I have been out of office for a while.

    Have you made any progress? I did some more testing and it seems like you may have stumbled upon a bug in S132 v3.0.0. If you try to upgrade to e.g. SDK v13.1 and S132 v4 then det code above seems to work. 

  • Hi,

    thanks for your reply. Unfortunately I'm not having much luck with this. I compiled and flashed the UART examples for central and peripheral from SDK v13.1 and S132 v4 but still get an error when trying to send single bytes multiple times. At the moment the maximum amount of bytes I can send is 27 (that's 27 times 1 byte payload, so 27 packets). When attempting to send 28 bytes the transmitter resets and I am getting the following error message on the Segger RTT terminal:

     0> :ERROR:Error: ID: 16385, PC: 0x0
     0> :ERROR:Error: ID: 1, PC: 0x1AAA4
     0> :ERROR:Error: Code: 0x0579 (1401), Line: 1024, File: KGJ`hó

    Are you able to decipher this error message?

    Thanks.

  • Hi,

    In this case the program counter (PC) points to an assert that originates inside the Softdevice (PC value is smaller than the Softdevice's flash size). I'll have to consult with the Softdevice team to get an explanation of the assert. Are you using S132 v4.0.2 which is bundled with SDK 13.1 by default? If so, can you try upgrading to v4.0.5? (Upgrading to v4.0.5 requires no changes in your code)

Reply
  • Hi,

    In this case the program counter (PC) points to an assert that originates inside the Softdevice (PC value is smaller than the Softdevice's flash size). I'll have to consult with the Softdevice team to get an explanation of the assert. Are you using S132 v4.0.2 which is bundled with SDK 13.1 by default? If so, can you try upgrading to v4.0.5? (Upgrading to v4.0.5 requires no changes in your code)

Children
  • BTW: I'll be traveling the rest of the week, so the progress might be slow until next week. 

  • Hi, yes I originally used the SDK13.1 with bundled s132 v4.0.2 softdevice. I upgraded to S132 v4.0.5 but I am still getting an error and the firmware resets when attempting to transmit more than 28 bytes of payload. I am attaching the full debug log of one session which attempts to transmit 29 bytes. It's itneresting that when transmitting 28 bytes there is no issue at all. But when attempting to transmit 29 bytes not a single byte actually arrives at the receiver, although the RTT log would indicate that it started transmitting over BLE.

     0> SDH:DEBUG:RAM start at 0x200020c8.
     0> APP:INFO:BLE UART central example started.
     0> APP:INFO:Connecting to target 19f0a32761e0
     0> APP:INFO:Connected to target
     0> BLE_DB_DISC:DEBUG:Starting discovery of service with UUID 0x1 on connection handle 0x0.
     0> nrf_ble_gatt:DEBUG:Requesting to update ATT MTU to 158 bytes on connection 0x0.
     0> nrf_ble_gatt:DEBUG:sd_ble_gattc_exchange_mtu_request() on connection 0x0 returned busy, will retry.
     0> nrf_ble_gatt:DEBUG:Requesting to update data length to 162 on connection 0x0.
     0> nrf_ble_gatt:DEBUG:Peer on connection 0x0 requested an ATT MTU of 64 bytes.
     0> APP:INFO:ATT MTU exchange completed.
     0> BLE_DB_DISC:DEBUG:Found service UUID 0x1.
     0> nrf_ble_gatt:DEBUG:Data length updated to 162 on connection 0x0.
     0> nrf_ble_gatt:DEBUG:max_rx_octets: 162
     0> nrf_ble_gatt:DEBUG:max_tx_octets: 162
     0> nrf_ble_gatt:DEBUG:max_rx_time: 1408
     0> nrf_ble_gatt:DEBUG:max_tx_time: 1408
     0> BLE_DB_DISC:DEBUG:Discovery of service with UUID 0x1 completed with success on connection handle 0x0.
     0> APP:INFO:Discovery complete.
     0> APP:DEBUG:Ready to send data over BLE NUS
     0> APP:DEBUG:
     0> 31                                               1               
     0> APP:DEBUG:Ready to send data over BLE NUS
     0> APP:DEBUG:
     0> 32                                               2               
     0> APP:DEBUG:Ready to send data over BLE NUS
     0> APP:DEBUG:
     0> 33                                               3               
     0> APP:DEBUG:Ready to send data over BLE NUS
     0> APP:DEBUG:
     0> 34                                               4               
     0> :ERROR:Error: ID: 1, PC: 0x11994
     0> :ERROR:Error: Code: 0x0579 (1401), Line: 1024, File: KGJ`hóˆ@h

  • Hi,

    I went ahead and tested the latest SDK 15.0.0 with S132 v6.0.0 and received the following error when sending more than 18 bytes of payload:

     0> <info> app: BLE UART central example started.
     0> <info> app: Connecting to target 19F0A32761E0
     0> <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
     0> <debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
     0> <info> app: Connected to target
     0> <debug> ble_db_disc: Starting discovery of service with UUID 0x1 on connection handle 0x0.
     0> <debug> nrf_ble_gatt: Peer on connection 0x0 requested an ATT MTU of 247 bytes.
     0> <debug> nrf_ble_gatt: Updating ATT MTU to 247 bytes (desired: 247) on connection 0x0.
     0> <debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
     0> <info> app: ATT MTU exchange completed.
     0> <info> app: Ble NUS max data length set to 0xF4(244)
     0> <debug> ble_db_disc: Starting discovery of service with UUID 0x1 on connection handle 0x0.
     0> <debug> nrf_ble_gatt: Data length updated to 251 on connection 0x0.
     0> <debug> nrf_ble_gatt: max_rx_octets: 251
     0> <debug> nrf_ble_gatt: max_tx_octets: 251
     0> <debug> nrf_ble_gatt: max_rx_time: 2120
     0> <debug> nrf_ble_gatt: max_tx_time: 2120
     0> <debug> ble_db_disc: Found service UUID 0x1.
     0> <debug> ble_db_disc: Discovery of service with UUID 0x1 completed with success on connection handle 0x0.
     0> <info> app: Discovery complete.
     0> <info> app: Connected to device with Nordic UART Service.
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  31                     |1       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  32                     |2       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  33                     |3       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  34                     |4       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  35                     |5       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  36                     |6       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  37                     |7       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  38                     |8       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  39                     |9       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  30                     |0       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  31                     |1       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  32                     |2       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  33                     |3       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  34                     |4       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  35                     |5       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  36                     |6       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  37                     |7       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  38                     |8       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  39                     |9       
     0> <debug> app: Ready to send data over BLE NUS
     0> <debug> app:  30                     |0       
     0> <error> app: Error: ID: 16385, PC: 0x2BCC9
     0> 
     0> <error> app: Error: Code: 0x0013 (19), Line: 246, File: ..\..\..\main.c
     0> 
     0> <error> app: ERROR 19 [NRF_ERROR_RESOURCES] at ..\..\..\main.c:246
     0> PC at: 0x0002BCC9
     0> <error> app: End of error report

  • Hi

    Error NRF_ERROR_RESOURCES means that you are still filling up the Softdevice's transmit queue too fast. What kind of central device do you use for testing? Have you tried more than one?

    There are a couple of suggestions here. Have you tried something similar?

    Can you upload your project if you are still stuck?

  • Hey,

    I am using two of the Rigado BMD-300 evaluation kits ( Rigado Eval Kit ) which are similar to the Nordic pca 10040 boards. One is configured as central and the other one as peripheral device. My project is the exact SDK UART example code (ble_app_uart_c and ble_app_uart) and I only made a small change to the function uart_event_handle of the file main.c of the central example. The single change was to comment out the if statement as indicated in my very first post here. The peripheral example code is unchanged.

Related