ble app uart

Hi:

I use nrf52832 to connect to the sensor module through uart. When the sensor device is turned off, I can repeat the pairing and unpairing of the Ble module through the nRF Connect app. But after the Ble module pairing is completed and the sensor is turned on, when I cancel the Ble pairing and want to re-pair, I cannot scan the Ble device and cannot pair. How can I solve it

Parents
  • Hello,

    If the device does not show up again in the nRF Connect application scanner after a disconnect it is likely due to the device not advertising. 
    Could you make sure that your device restarts advertising when a connection is disconnected?

    Do I understand you correctly that you are working with the BLE UART example? If so, have you made any modifications to the example application?

    Best regards,
    Karl

  • Yes, I am using the ble_app_uart example. For the example, I only modify MIN_CONN_INTERVAL and MAX_CONN_INTERVAL.

    This problem only occurs when the sensor device is turned on, how can I modify it for the ble example?

  • Sorry, the wrong code should be in the red box below

  • Hello again,

    Could you show me the entire error message, preferably as a text string instead of a screenshot?
    At the very end of the error message it tells you which line that failed the APP_ERROR_CHECK. Please also show me the code section (entire function) that triggered this APP_ERROR_CHECK. Please also use the Insert -> Code option when sharing code here on DevZone - this drastically increases it's readability.

    Best regards,
    Karl

  • Hi Karl:

    Do you want these messages?

    <info> app_timer: RTC: initialized.
    <info> app: Debug logging for UART over RTT started.
    <info> app: Connected
    <info> app: Data len is set to 0xF4(244)
    <info> app: Disconnected
    <info> app: Connected
    <info> app: Data len is set to 0xF4(244)
    <error> app: ERROR 13313 [Unknown error code] at C:\Users\user\Desktop\nordic\nRF5SDK1702d674dde\nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_uart\main.c:617
    PC at: 0x0003230B
    <error> app: End of error report

    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;
        uint32_t       err_code;
    
        switch (p_event->evt_type)
        {
            case APP_UART_DATA_READY:
                UNUSED_VARIABLE(app_uart_get(&data_array[index]));
                index++;
    /*
                if(data_array[0] == 0x02 && data_array[1] == 0x01 && data_array[2] == 0x04 && data_array[3] == 0x03)
                {
                
                  int dataLength = data_array[8] + data_array[9] * 256;
                    if (data_array[8 + dataLength] && data_array[9 + dataLength] && data_array[10 + dataLength] && data_array[11 + dataLength] == 0xff )
                    {
                        if (index > 1)
                        {
                            NRF_LOG_INFO("Send_data");
                            NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                            NRF_LOG_HEXDUMP_DEBUG(data_array, index);
    
                            do
                            {
                                uint16_t length = (uint16_t)index;
                                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);
                        }
    
                        index = 0;
                    }
    
                    else if((data_array[index - 1] && data_array[index - 2] && data_array[index - 3] && data_array[index - 4] == 0xff) ||
                            (index >= m_ble_nus_max_data_len))
                    {
                        if (index > 1)
                        {
                            NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                            NRF_LOG_HEXDUMP_DEBUG(data_array, index);
    
                            do
                            {
                                uint16_t length = (uint16_t)index;
                                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);
                        }
    
                        index = 0;
                    }
                }
    */
               // else
               // {
                   // if ((data_array[index - 1] && data_array[index - 2] && data_array[index - 3] && data_array[index - 4] == 0xff) ||
                   if ((data_array[index - 1] == '\n') || 
                       (data_array[index - 1] == '\r') ||
                       (index >= (m_ble_nus_max_data_len)))
                    {
                        if (index > 1)
                        {
                            NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                            NRF_LOG_HEXDUMP_DEBUG(data_array, index);
    
                            do
                            {
                                uint16_t length = (uint16_t)index;
                                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);
                        }
    
                        index = 0;
                    }
            //    }
                break;
    
            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;
        }
    }

  • nicky_liu said:
    Do you want these messages?

    Yes, exactly this, thank you.

    nicky_liu said:
    <error> app: ERROR 13313 [Unknown error code] at C:\Users\user\Desktop\nordic\nRF5SDK1702d674dde\nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_uart\main.c:617
    PC at: 0x0003230B
    <error> app: End of error report

    The error report states that the APP_ERROR_CHECK was triggered on line 617 of main.c
    Could you also confirm that the APP_ERROR_CHECK following the call to ble_nus_data_send in the code snippet that you have sent is in fact line 617 of your main.c?
    It seems strange to me that this could return an unknown error code such as 13313 - this is usually the case when a non-error code is passed to an APP_ERROR_CHECK, or in the case that an uninitialized error code is passed to an APP_ERROR_CHECK.

    Best regards,
    Karl

  • On a general note I also notice that you have quite a long path to your SDK location.
    Please be aware of Window's 260 character path limit - anything exceeding 260 characters will be truncated.
    This can cause quite a headache if not aware of it.
    I recommend that you move you SDK location to be on top of your hierarchy, like C:\nordic\ or similar.

    Best regards,
    Karl

Reply Children
  • Yes, line 617 in main.c is the APP_ERROR_CHECK following the call to ble_nus_data_send.
    What should I do?

  • Hi Karl:
    After doing some experiments, I found that the problem of not being able to re-pair seems to occur when the Uart RX listen is not stopped and the device is unpaired. When I stop Uart RX listen first, and then unpair the device, this problem will not occur.
    Is there a solution to this?

  • nicky_liu said:
    Yes, line 617 in main.c is the APP_ERROR_CHECK following the call to ble_nus_data_send.

    Thank you for confirming this.
    The 13313 error returned from ble_nus_data_send propagates from sd_ble_gatts_hvx, and as I've understood it usually means that you've tried to queue a notification for sending for a connection handle that the SoftDevice has not been provided any system attributes for. This should then generate a BLE_GATTS_EVT_SYS_ATTR_MISSING event, if it is the case. Are you seeing this 13313 error frequently, or only at a given time in your program? Other user's I've seen experience this reported that this error was only returned as a result of a call to queue a notification interrupted by a disconnected event or connected event - could this also be the case here?
    If you retry the call to ble_nus_data_send once immediately after having received the 13313 error, does it still return 13313 on the second try?

    When not using pairing / bonding this can be handled by adding the following into the ble_evt_handler:

    case BLE_GATTS_EVT_SYS_ATTR_MISSING:
        err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
        APP_ERROR_CHECK(err_code);
        break;


    When using pairing / bonding this should then instead be handled by the peer manager.
    Could you check whether you are receiving this event in your PM event handler or not?

    nicky_liu said:
    After doing some experiments, I found that the problem of not being able to re-pair seems to occur when the Uart RX listen is not stopped and the device is unpaired. When I stop Uart RX listen first, and then unpair the device, this problem will not occur.
    Is there a solution to this?

    This points in the direction of the aforementioned - that CCCD (notify) is enabled on the peripheral, and when the connection is broken the device may still be trying to send a notification, and/or upon the next reconnection it may generate the BLE_GATTS_EVT_SYS_ATTR_MISSING event to see if it has stored any information about this peer and its attributes (like the CCCD already being enabled from the previous connection).

    Does the applications UART RX callback include a call to queue a notification with the received data? Could it be that the function attempts to queue data for a recently disconnected / unpaired device?
    If so, you may handle this error by stopping the UART RX and storing the data you attempted to queue for transfer later, or discard the data entirely if it is not relevant later. How does this work with your application's constraints and requirements?

    Best regards,
    Karl

  • Hi Karl:

    1.Are you seeing this 13313 error frequently, or only at a given time in your program?

       Ans : Currently the 13313 error only appears when I want to re-pair the device.

    2.Could you check whether you are receiving this event in your PM event handler or not?

      Ans : I have added the following LOG_INFO in the PM event, but it seems not to be executed.

            case PM_EVT_CONN_SEC_CONFIG_REQ:
            {
                // Allow or reject pairing request from an already bonded peer.
                pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true};
                pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
                NRF_LOG_INFO("device re-pair/n")  
            }
                break;

    3.Does the applications UART RX callback include a call to queue a notification with the received data? Could it be that the function attempts to queue data for a recently disconnected / unpaired device?
    If so, you may handle this error by stopping the UART RX and storing the data you attempted to queue for transfer later, or discard the data entirely if it is not relevant later. How does this work with your application's constraints and requirements?

     Ans : I hope it can run correctly without stopping Uart RX, but I still can't achieve it at the moment.

      

  • Hello,

    Thank you for your patience with this.

    To elaborate a little on what I said earlier; error  13313=0x3401 corresponds to BLE_ERROR_GATTS_SYS_ATTR_MISSING and is likely returned by  ble_nus_data_send() because it's called before the system attribute table has been updated in the Softdevice, similar to the NRF_ERROR_INVALID_STATE error you get if you try to send notifications before notifications has been enabled by the GATT client .

    The attribute table (contain CCCD configurations) is restored on connection if you use the Peer manager module. Maybe ble_nus_data_send() is called before the Peer manager has had time to restore the attributes, or similar.

    nicky_liu said:
    I hope it can run correctly without stopping Uart RX, but I still can't achieve it at the moment.

    If it is important not to stop the UART RX then perhaps we should redirect the messages received on the UART to RAM or Flash storage (depending on the amount of data received in the time that a connection is broken), as a fix to this.
    Could this be an option?
    If this issue only is present when re-pairing, then you could add a specific error handling for this error, which is to store the data for later transfer, and then try again sometimes later. This error should disappear as soon as the Peer Manager has had enough time to update the attribute table, as mentioned above.
    Could you try this, and see if it resolves your issue? I.e implement specific error handling for the 13313 error that stores the data you attempted to queue for later transfer, so that the peer manager has enough time to populate the attribute table.

    Best regards,
    Karl

Related