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

How to handle UART data? (nRF52832)

Hi. I'm using external board with nRF52832 and GPS. (SDK15.0.0)

I used ble_app_uart example and succeed in receive data in my nRF UART v2.0 app.

I got this kind of data every 1sec.

$GPGGA,215235.670,3735.0064,N,12701.6746,E,1,03,50.0,0.0,M,19.6,M,0.0,0000*4F
$GPGSA,A,2,10,08,02,,,,,,,,,,50.0,50.0,20.0*0A
$GPGSV,3,1,10,26,78,314,00,29,71,017,00,24,48,156,00,10,44,079,46*79
$GPGSV,3,2,10,21,39,309,32,08,21,046,36,09,16,187,00,02,14,151,35*73
$GPGSV,3,3,10,06,14,296,00,15,06,319,00*7F
$GPRMC,215235.670,A,3735.0064,N,12701.6746,E,0.000000,,060905,,*12
$GPGGA,215236.670,3735.0066,N,12701.6748,E,1,03,50.0,0.0,M,19.6,M,0.0,0000*40

However I want to receive only $GPRMC related lines with every 2 or 3sec.

I found uart_event_handle() function is related with receving data, but I don't know how to modify it.

Here's the function

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(&b[index]));
            index++;
      
         if (   data_array[4]=='M' && ((data_array[index - 1] == '\n') || (index >= (m_ble_nus_max_data_len)) ) )
         {
           NRF_LOG_DEBUG("Ready to send data over BLE NUS");
           NRF_LOG_HEXDUMP_DEBUG(data_array, index); //No matter
            
           do
           {
             uint16_t length = (uint16_t)index;
             //if(data_array[3]=='R')
              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_BUSY) &&
                (err_code != NRF_ERROR_NOT_FOUND) )
             {
               APP_ERROR_CHECK(err_code);
             }
           } while (err_code == NRF_ERROR_BUSY);

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

I tried ' if(data_array[4]=='M') ' and it's not working.

Help! Thanks.

ps. I'm not living in English speaking country. So I'm not fluent in writing english. Sorry

Parents
  • Hello,

     

    You are on the right track. You should use the uart_event_handle() function.

    Originally it works this way:

    It is called every time the function gets called every time the nRF receives a byte/char on the UART. It stores that character in an array, data_array[], and checks if the array is full, or if the last char was '\n'. If it was, it will send the array on the BLE link.

     

    I notice that $GPRMC is the only sequence startin with '$', and 'R' is the 4th char.

    You will have to test and verify that this is working yourself, but I may give you some hints to get started.

     

    Since you only are looking for strings starting with $, you can do something like:

            case APP_UART_DATA_READY:
          
                UNUSED_VARIABLE(app_uart_get(&b[index]));
                index++;
                if (data_array[0] != '$')
                {
                    index = 0;
                }

    This way, you will not start to store data until you get a '$'.

    Then, when index reaches 3, you can check for an 'R':

            case APP_UART_DATA_READY:
          
                UNUSED_VARIABLE(app_uart_get(&b[index]));
                index++;
                if (data_array[0] != '$')
                {
                    index = 0;
                    break;
                }
                if ((index-1 >= 3) && (data_array[3] != 'R'))
                {
                    index = 0;
                    break;
                }
                
                

    If the code passes this point, it will write to the data_array only when it starts with $GPRMC (or actually $**R), and you can continue to collect the data from the UART.

     

    if you only want to do it every third second, you can either use a timer to set a variable that you also check before collecting data, or you can set a counter to only collect the data every third time you get a message starting with $GPRMC.

     

    Did this make any sense, or was it only confusing?

     

    Best regards,

    Edvin

  • hello edvin , 

     i am kishor new to this nrf52 module  , actually iam   implementing the  code  for  gps master and slave clock , i want to send  total gprmc packet  after receiving the master ble to slave ble ..   i am usng the sample code ble_app_uart(), in that rx buffer  sige having the only one byte  sholu i chage that bugger size, and can u  suggest the  little code  

Reply
  • hello edvin , 

     i am kishor new to this nrf52 module  , actually iam   implementing the  code  for  gps master and slave clock , i want to send  total gprmc packet  after receiving the master ble to slave ble ..   i am usng the sample code ble_app_uart(), in that rx buffer  sige having the only one byte  sholu i chage that bugger size, and can u  suggest the  little code  

Children
No Data
Related