3

I would like to download my log file from the flash of my ESP32 to my Android Phone.

I knew that we can only send files with 20 bytes at a time. Hence, I partitioned the file into chunk of 20 Bytes. Here's my code :

#define PAYLOAD_CHUNK_SIZE 20

for (int i = 0; i < file_size; i = i+PAYLOAD_CHUNK_SIZE){
    uint8_t file_buffer[PAYLOAD_CHUNK_SIZE];
        
    for (int j = 0; j <20; j++){
        file_buffer[j] = (uint8_t) buffer[i+j];
    }

    update_char_file_value(file_buffer, PAYLOAD_CHUNK_SIZE);
    count++;
    printf("sending data! %d", count);
    ets_delay_us(10000);
}

void update_char_file_value(uint8_t *data, uint16_t len){
    uint16_t handle = sensor_handle_table[IDX_CHAR_FILE_VAL_TX];
    esp_ble_gatts_set_attr_value(handle, len, data);

    if (isNotifyEnabled == true){
        esp_ble_gatts_send_indicate(sensor_profile_tab[PROFILE_APP_IDX].gatts_if, sensor_profile_tab[PROFILE_APP_IDX].conn_id, handle,
                                    len, data, false);
    }
}

The following code works with small size file (max 400 Bytes), but beyond that I will get the following result:

sending data! 1sending data! 2sending data! 3sending data! 4sending data! 5sending data! 6sending data! 7sending data! 8sending data! 9sending data! 10sending data! 11sending data! 12sending data! 13sending data! 14sending 
data! 15sending data! 16sending data! 17sending data! 18sending data! 19sending data! 20sending data! 21sending data! 22sending data! 23sending data! 24sending data! 25sending data! 26sending data! 27sending data! 28sending data! 29sending data! 30sending data! 31sending data! 32sending data! 33sending data! 34sending data! 35sending data! 36sending data! 37sending data! 38sending data! 39sending data! 40sending data! 41sending data! 42sending data! 43sending data! 44sending data! 45sending data! 46sending data! 47sending data! 48sending d

After this is printed, the ESP32 will just be stuck and not respond to anything, unless you reset it again.

I am not sure whether this is the problem from the Android application, but I think it's leaning more towards the esp32 handling the text transfer.

Has anyone here ever done sending a large file via BLE successfully before? Your help is greatly appreciated!

Michael Kotzjan
  • 2,093
  • 2
  • 14
  • 23
coyodha
  • 135
  • 1
  • 2
  • 10
  • 1
    You don't check for errors when calling `esp_ble_gatts_set_attr_value()` and `esp_ble_gatts_send_indicate()`. Doing so might reveal the cause for your failure. – Tarmo Feb 08 '21 at 09:17

2 Answers2

1

I wrote this BLE-FTP service to transfer configuration files back-and-forth from my ESP32 to a Android/iOS App (Cordova). It can transfer large files, but the rate is pretty slow, limited by the BLE bandwidth. It works with MTU sizes from 20~600B, but performance is much better at higher MTU.

https://github.com/eagi223/esp-idf_Bluetooth_Multi-Service/blob/master/main/wireless/ble_services/ble_service_ftp.c

(The containing project builds to a working example.)

I also could post the Cordova app client-side code in JS which talks to this BLE-FTP service if you're interested.

phatpaul
  • 166
  • 7
  • Legend! I really need some reference on how to do this. Could share your client-side code as well? – coyodha Feb 12 '21 at 03:05
  • 2
    OK, give it a try: https://github.com/phatpaul/ble-ftp-cordova-example Please open an issue on that repo if something doesn't work for you. – phatpaul Feb 13 '21 at 05:12
0

frames of up to 517 bytes can be received by increasing the mtu, in the event handler when the BLE_GATT_OP_WRITE_CHR operation is executed, the buffer size must be checked and based on that, program what is required, the transmission can be done with long frames, from your android device you must request an mtu change, in the gag_event in the type BLE_GAT_EVENT_MTU you can consult it

If you send the packets in 20 byte chunks you need to put a delay between the sends, I suggest you use freertos. vTaskDelay that does not block the micro

Leandro
  • 26
  • 3