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

Parents
  • Hello,

    So you want to send a CSV file rom the SD card to the connected mobile phone, right?

    If I were you, I would start with the ble_app_uart example, and use ble_nus_data_send() to send your notifications. You can probably do it in the application you have started developing now. Just send the data using notifications.

    I didn't really see any questions in your post. Have you attempted this? Did you get stuck somewhere?

    Best regards,

    Edvin

  • Yes I want to send a CSV file from the SD card on the nordic board to a mobile phone. 

    Is there an example of this?

    I have not used the ble_app_uart example for this. However I do have my own custom service and Gatt connection working. My question is

    • How do I change the pointer location for the SD card?
    • How do I setup the notifications? As in how do I get them to work and change the value to be sent via this notification to the value of the CSV data?

    Also does with ble_app_uart example have a custom service? As I will need to move alot of my functionality too it.

    Also how does ble_nus_data_send work?

    Is there some guidance for how to setup notifications?

    Thanks

  • Cheers, I do use SES.

    I did set the data length to 51 made no difference. Below is my output

    So the first bits of data are fine but the rest is 0. This is the same for the NRF connect application.

    SEND_CSV is sent once. If i press a specific command on my phone. Which writes gatt data to another characteristic. Then runs in the main loop.

  • So it seems like you do not want to send 51 bytes, then? In this case, it looks like you would only want to send 41 bytes? Perhaps you should try to cut after you see "0D 0A", since each line would end with this?

    I suspect that you read it into the same area each time, so the next time you would call this, and the new line is shorter than the previous one, you probably don't reset this string, and you send the full 51 bytes again, is that correct?

    1st line:

    31 35 38 34 39 36 39 30 36 35 2C 31 38 37 35 26 31 38 34 33 2C 31 38 36 32 2C 31 38 36 32 2C 2D 30 2E 30 32 30 30 30 30 0D 0A 00 00 00 00 00 00 00 00 00

    Then for the argument's sake, let us say that your second line is only: "1,2,3", which would be "31 32 33 0D 0A", then that would not be the case if you send the entire 51 bytes. It would be:

    31 32 33 0D 0A 36 39 30 36 35 2C 31 38 37 35 26 31 38 34 33 2C 31 38 36 32 2C 31 38 36 32 2C 2D 30 2E 30 32 30 30 30 30 0D 0A 00 00 00 00 00 00 00 00 00

    Remember that the softdevice will do exactly what you tell it to do. If you tell it to send 51 bytes from a pointer, it will do that. If you tell it to send 247 bytes from a pointer, it will do that too. You must find out based on your readouts where the line ends, and then send that many bytes.

    BR,

    Edvin

    • Thank you for your response. I do want to send 51 bytes. 
    • You are correct it reads the same data each time as I am just reading the first line of my CSV at the moment for testing purposes.
    • But, where in my code does it say send more than 51 bytes?
    • The data length I send into my ble_cus_send_csv is 51. But this function clearly sends more.
    • Also what do you mean by cut off? I read 51 bytes via my reading CSV function yes this will include commas, and return characters.
    • Or do I need to change this in the sdk_config.h? As NRF_SDH_BLE_GAP_DATA_LENGTH i have set to 251 from 27.

    Also to have only the specified bytes sent aka 51. Do I need:

    blcm_link_ctx_storage_t * const p_link_ctx_storage; /**< Pointer to link context storage with handles of all current connections and its context. */

        ble_nus_client_context_t * p_client;
    
        VERIFY_PARAM_NOT_NULL(p_nus);
    
        err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, conn_handle, (void *) &p_client);
        VERIFY_SUCCESS(err_code);

  • It is the "sizeof()" that doesn't work exactly as you expect. Try to log the output from sizeof and see what it says.

     

    Thomas said:
    Or do I need to change this in the sdk_config.h? As NRF_SDH_BLE_GAP_DATA_LENGTH i have set to 251 from 27.

     No. You don't need to do that.

    As long as you set the length to 51, it will send 51 bytes.

     

    Thomas said:
    I did set the data length to 51 made no difference. Below is my output

     From the post where you said this, it clearly sent 51 bytes. Is that the behavior that you want? 

    The blcm_link_ctx_get() is a function used to fetch the notification status. Just to check whether notifications are enabled or not. It is not crucial, but nice to have. You can see where p_client is used later in the function where you found blcm (ble_nus_data_send()).

    Best regards,

    Edvin

  • In my send CSV function. I used the size of command and it is 51 bytes. I do want it to send just 51 bytes at the moment.

    Therefore, surely it should be sending 51 bytes but, it is not.

    But inside my ble_cus_send_csv p_length is much larger.

    I do not know why this is. I have tried setting the length manually to 51 inside my ble_cus_send_csv function but, it still has a value of 2003ffc6.

Reply
  • In my send CSV function. I used the size of command and it is 51 bytes. I do want it to send just 51 bytes at the moment.

    Therefore, surely it should be sending 51 bytes but, it is not.

    But inside my ble_cus_send_csv p_length is much larger.

    I do not know why this is. I have tried setting the length manually to 51 inside my ble_cus_send_csv function but, it still has a value of 2003ffc6.

Children
  • p_length is a pointer. Press the arrow to the left to see the content of p_length.

  • Thanks. It is 51.

    Therefore, I am not sure what the issue is.

  • What step should I take next to fix this issue? I have tried changing the data i send from a char to uint8_t. That made no difference. 

    Could it be some sdk setting thats incorrect or something not working correctly about sd_ble_gatts_hvx?

    Or is my init incorrect. I am missing add_char_params.is_var_len  = true;

    But, I don't use add_char_params.is_var_len as I dont have add_char_params in my code.

  • Can you zip the project folder and upload it here so that I can try to replicate the behavior that you are seeing? If possible, please try to strip away the CSV file part. Just a project that can send a 51 byte long array that replicates the behavior that you are seeing.

  • Hi Edvin,

    Cheers for offering to have a look. I've taken my project and removed a bunch of code to make it simpler for you to test still having the same issue. I have just tested it on a NRF52840-dk board with nothing connected to the GPIOs and the issue still persists.

    To get the code to work and show you the bug please do the following steps. Place inside the ble_peripheral folder. Then the includes should not need changing. Also I use Jlink rtt for my terminal.

    Then build and run. To show the bug:

    • Open nrf connect
    • Should see a device with data 0x0003E804.....
    • Press connect
    • On the unknown service request notifications from the second characteristic should have the 3 arrows(UUID with 1402)
    • Then write to the other characteristic 2 values
    • 10(Uint32) this is my start command
    • 60 (uint32) this is my read command. It will then show the data to the nrf connect app with the bug
    • 20(uint32) stop command

    Hopefully you will see the same result thanks,

    gatt_issue.zip

    Below is what I expect you will see from the nrf connect application.:

Related