uart_event_handle Data Issue

Hello,

I want to communicate with the one master and four slave devices. For this I have merged ble_uart for the data communication and multirole exmple for the multiple connection. 

I want to send the data from the master to the several peripheral devices. For this I have connected master to the computer and sending data from terminal to the peripheral module.

APP_UART_DATA_READY in uart_event_handle function is called after every byte reception. 

Issues:

1. It does not terminate on the first 0x0A character instead it terminates on the second time 0x0A reception. It does not send 2nd 0x0A on the terminal As per the attached screenshot.

2. Received 0x0A character in the previous transmission is considered as terminating character in the next transmission and in next transmission only 0x0A is printed on the uart and the sent characters are missing and sent in the next tx.

For e.g. if I send 04,hello\r\n\n for the first transmission then only it enter in the ble_nus_c_string_send function but does not send the 2nd \n.

2nd \n is received in the next transmission when I send some other bytes but other bytes are not received only terminated on previous \n.

Please suggest the solution of the problem, I am stuck here.

My function is attached as 

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t  cmd_mode=0;
    uint32_t ret_val;
    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
                    //nrf_drv_timer_disable(&TIMER_UART_RX);
                    
                    UNUSED_VARIABLE(app_uart_get(&UART_RX_BUF[UART_RX_STA]));
                    UART_RX_STA++;	// Record the uart received data frame length
                    if((strstr(UART_RX_BUF, "@#$"))!=0 && UART_RX_STA>=2)        //To enter into Command Mode 
                    {
                         // Enter into the AT Command Configuration Mode
                         NRF_LOG_INFO("AT Command Mode");
                         NRF_LOG_HEXDUMP_INFO(UART_RX_BUF, UART_RX_STA);
                         uart_print("\r\nOK\r\n");

                         cmd_mode = 1;  
                         //app_fifo_flush(data_array);
                         memset(UART_RX_BUF, 0, sizeof(UART_RX_BUF));
                         UART_RX_STA=0;
                         app_uart_flush();
                    }
                    else if(cmd_mode == 1)
                    {
                        if(AT_cmd_check_valid(UART_RX_BUF, UART_RX_STA))  // AT command
			{
				AT_cmd_handle(UART_RX_BUF, UART_RX_STA);
                                UART_RX_STA=0;
			}
                    
                    }

                    else if (((UART_RX_BUF[UART_RX_STA - 1] == 0x0A) || (UART_RX_STA >= (m_ble_nus_max_data_len)))&& cmd_mode==0)   // data mode 
                    {
                            NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                            NRF_LOG_HEXDUMP_DEBUG(UART_RX_BUF, UART_RX_STA);
                            NRF_LOG_HEXDUMP_INFO(UART_RX_BUF, UART_RX_STA);

                            do
                            {
                                    for (uint32_t i = 0; i < NRF_SDH_BLE_CENTRAL_LINK_COUNT; i++)
                                    {
                                            ret_val = ble_nus_c_string_send(&m_ble_nus_c[i], UART_RX_BUF, UART_RX_STA);
                                            if ( (ret_val != NRF_ERROR_INVALID_STATE) && (ret_val != NRF_ERROR_RESOURCES) )
                                            {
                                                    APP_ERROR_CHECK(ret_val);
                                            }
                                    }
                            } while (ret_val == NRF_ERROR_RESOURCES);

                            UART_RX_STA = 0;
                            memset(UART_RX_BUF, 0, sizeof(UART_RX_BUF));
                            app_uart_flush();
                 
                    }
                    //nrf_drv_timer_enable(&TIMER_UART_RX);
            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;
    }
}

Parents
  • uart_event_handle() will trigger for each byte received on the UART interface, and you can see from the event handler that the handler will simply check for new line character or buffer full before sending data by calling ble_nus_data_send(). Feel free to change this as you see fit.

    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[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;
        }
    }

  • Hello,

    I have already used the code you have shared and modified it accordingly but always getting issue in the next string.

    void uart_event_handle(app_uart_evt_t * p_event)
    {
            static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
            static uint16_t index = 0;
            uint32_t ret_val;
    
            switch (p_event->evt_type)
            {
    
            case APP_UART_DATA_READY:
                    UNUSED_VARIABLE(app_uart_get(&data_array[index]));
                    index++;
                   /* if((index>=3) &&((data_array[index - 2] == '@') ||  \
                    (data_array[index - 1] == '#') ||                   \
                    (data_array[index - 0] == '$')))
                    {
                       // Enter into the AT Command Configuration Mode
                    }*/
                    if ((data_array[index - 1] == 0x03) || (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);
                            //NRF_LOG_HEXDUMP_INFO(data_array, index);
    
                            do
                            {
                                    for (uint32_t i = 0; i < NRF_SDH_BLE_CENTRAL_LINK_COUNT; i++)
                                    {
                                            ret_val = ble_nus_c_string_send(&m_ble_nus_c[i], data_array, index);
                                            if ( (ret_val != NRF_ERROR_INVALID_STATE) && (ret_val != NRF_ERROR_RESOURCES) )
                                            {
                                                    APP_ERROR_CHECK(ret_val);
                                            }
                                    }
                            } while (ret_val == NRF_ERROR_RESOURCES);
    
                            index = 0;
                           // app_uart_flush();
                           }
                    }
                    break;
    
            case APP_UART_COMMUNICATION_ERROR:
                    NRF_LOG_ERROR("Communication error occurred while handling UART.");
                    APP_ERROR_HANDLER(p_event->data.error_communication);
                    break;
    
            case APP_UART_FIFO_ERROR:
                    NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
                    APP_ERROR_HANDLER(p_event->data.error_code);
                    break;
    
            default:
                    break;
            }
    }

    As per the screenshor attached, I have transmitted 04,hiki with CR and ETX but I have received in the data_array 004,hiki with CR and ETX. \

    I have received extra '0' character at  data_array[0].

    '0' is the byte which I have transmitted on terminal randomly. It always appends the last transmitted byte (whether it is \n or any byte) to the start of the new array which is erroneous.

    Problem:

    if ((data_array[index - 1] == 0x03) || (index >= (m_ble_nus_max_data_len)))  condition is true when 0x03 is transmitted 2 times and 2nd transmitted 0x03 is appended at the start of the next string and only send 0x03 since it is the terminating character.

    Please provide the solution why last byte of the string is not flushed and getting appended to the start of the next string. I have also used app_uart_flush() to clear the buffer but no good luck.

  • If you are receiving bytes on the UART that you are not expecting, then you need to connect a logic analyzer on the UART and check where, how and when the unexpected data is received on the UART. I suggest to use a different UART terminal than SES. For instance the old Tera Term is the one I typically use.

    Kenneth

Reply Children
Related