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

Sending a CSV File over ble Gatt connection

Hi,

I need to send data from a CSV file on the nordic board(Via fatfs library). I have presently gotten a Gatt service up and running.

I have a mobile application which, can see the gatt service and write to the characteristics. From a specific write command from the mobile device I want the nordic board to send the CSV file over.

I can presently read a single line of the CSV file formatted like this: (Time stamp, data1, data 2, data3, data 4, data 5).

What I need to implement is:

  • Reading the whole file but, one or multiple lines at a time due to the size of the CSV
  • Changing the read pointer of the SD card (So I know where to continue to read from)
  • Send this data to the characteristic
  • Read this characteristic data.

My code is based upon :  https://github.com/bjornspockeli/custom_ble_service_example

My CSV file size depends on the length of time I have been storing data from. It could be upto around 1-2mbytes. I beleive I need to set up some kind of notification service. Where I read a line(or several) of the SD card, set the GATT characteristic value to this. Then change the SD card pointer. Wait till the data is received by the mobile application. Then repeat until the file is read full.y

Note I am using SDK 16 NRF52840-dk PCA 10056 S140.

This post is similar and mentions using two characteristics one from commication from the mobile app and, one for receiving the data.

https://devzone.nordicsemi.com/f/nordic-q-a/53987/nrf52840-file-transfer-via-ble

  • When you say have gatt_init() and gatt_evt_handler in my function what do you mean by this?

    I call gatt_init in my main before the main loop runs. I  did add the gatt event handler too.

    I changed the mtu size to 247 and NRF_SDH_BLE_GAP_DATA_LENGTH from 27 to 251. As this is what is done inside the app_uart example.

    Then I programmed it and it crashed. It needed a change in ram start location and ram size.

    Then I run it and it goes but, when I call my function to send 51 bytes of data i get :sd_ble_gatts_hvx result: 3401.

    Ok sorry this is a dug with my android application. So I have a bug where I need to press notify twice for it to send the notification request to the nordic board. Then I can submit my gatt request to send the data. I pressed it twice and I cansee a line of my CSV on my phone!

    The output however is far too long why is this?

    The below image is my application. And the top line is the first of my CSV. The rest is junk and I dont know why nor do i want it. How do I get rid of it?

  • I can't say what your mobile application outputs. Do you send more than one packet from the nRF? Because the app is printing far more than 51 bytes. Did you check what the return message 0x3401 means?

    Hint: Check all the return values found in the description of sd_ble_gatts_hvx(). If you use sdk_16.0.0 this is found in ble_gatts.h line 573-636. Then a short google search reveals threads like this one:

    https://devzone.nordicsemi.com/f/nordic-q-a/17688/ble_error_gatts_sys_attr_missing-from-sd_ble_gatts_hvx

    Although I give you the answer here, please do the exercise, so that you see how you find the cause of these return values.

    Since you print out a lot more than the 51 bytes that you send, I suspect that you just print out random bytes in the RAM in your phone app, and not the actual length of the packet. 

  • I manged to look up and get rid of my error. However, I believe my nordic application is output too much data.

    Below is the nordic nrf connect output and, my code:

    As the NRF connect has too much data as well. I think the nordic board is outputting far too much data. 

    void SEND_CSV()//Send the CSV file
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint8_t index = 0;
        ret_code_t err_code;
        SD_CARD_Read_Line();//Gets a line of 51bytes of data
        NRF_LOG_INFO("D1: %s\r\n",ble_csv_data);
        
        uint16_t data_length = 0;
        data_length =sizeof(ble_csv_data);
        err_code = ble_cus_send_csv(&m_cus, ble_csv_data,&data_length, m_conn_handle);//Too much data
               
        APP_ERROR_CHECK(err_code);
         
    }

    Update characteristic value

    uint32_t ble_cus_send_csv(ble_cus_t * p_cus, uint8_t   * p_data, uint16_t  * p_length, uint16_t    conn_handle)
    {
        ble_gatts_hvx_params_t hvx_params;
        NRF_LOG_INFO("Sending CSV.\r\n"); 
        if (p_cus == NULL)
        {
            return NRF_ERROR_NULL;
        }
    
        uint32_t err_code = NRF_SUCCESS;
        uint8_t length = 51;
        // Send value if connected and notifying.
        if ((p_cus->conn_handle != BLE_CONN_HANDLE_INVALID)) 
        {
            
            memset(&hvx_params, 0, sizeof(hvx_params));
    
            hvx_params.handle = p_cus->custom_value_handles.value_handle;
            hvx_params.p_data = p_data;
            hvx_params.p_len  = p_length;
            hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
    
            err_code = sd_ble_gatts_hvx(p_cus->conn_handle, &hvx_params);
            NRF_LOG_INFO("sd_ble_gatts_hvx result: %x. \r\n", err_code); 
        }
        else
        {
            err_code = NRF_ERROR_INVALID_STATE;
            NRF_LOG_INFO("sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE. \r\n"); 
        }
        return err_code;
    }

    NRF connect output

  • Where do you declare ble_csv_data? Can you show me?

  • Its in another file thats custom called SD_Card.c

    char ble_csv_data[51]={0}; /* Line buffer */

    It prints out to a terminal correctly though.

Related