Hi all,
this is a code snippet but even an help request to improve it, so I post here before move on code snippets section.
For my 3D printing app host I had necessity to transfer files from Android to ESP8266-ESP32 micro sd card (over network).
Because I don't wanted to use an FTP library on ESP side to just upload a file, I wrote a raw code that read a file in chunks and then
send one by one using a TCP socket.
Because I even want to pass some infos from Android to ESP before send a file I send an info string that contain some variables I want to pass,
it even contain a file name, size etc... and other variables I've put here just as an example, you can put yours.
Here is how it works....
- B4A code send a request to ESP with a file size
- ESP check for a space in the SD Card, if there is space to save a file send a string SPACEOK and B4A will continue the upload, if there is no space it send a string NOSPACE and B4A stop the upload
- If there is a space to save a file on ESP SD Card, then B4A send the info string containing the file name, size and other stuff (variables) not used here. The info string is a splited delimiter string and ESP split it to extract all infos
- after this B4A start read byte chunks (buffer) from file and send to ESP that collect it and append chunk by chunk to a file on micro sdcard.
This worked well for a long time in my app, now I've changed something and sometime the transfer fails,
sometime Android (TCP CLIENT) send info string and ESP (TCP SERVER) do not receive it or receive but then do not receive file chunks,
when this happen sometime Android app completely stall, no errors, completely hang, the only way is to use Android menu to close it.
Because I need to make it always working I've decided to reproduce it in a small project and post it so maybe someone can help to improve this piece of code.
I've attached a working B4A (client) and C++ (server) code, errors only happen on my real app where I have other stuffs in the ESP loop() function.
Note that here there is a sort of data encryption (just for string commands) that I just disabled on this test.
Note that here in the B4A code I open the socket connection before send all data, then send all data, finally I close it. In my app I cannot do this, just I open the socket and mantain it always open, there is a button to connect/disconnect.
Note that I cannot convert ESP side to B4R because it is a big project I started in 2018, so I cannot use socket stream in prefix mode.
I've used a timer to send file chunks, probably this is not good, I noticed that when Android send a chunk of bytes, then wait ESP to download it, if ESP do not read bytes from the stream, Android just wait until ESP read it, so probably using a Timer is not a good option here ?
Maybe it is best send chunks in a Do While loop awaiting ESP that read a chunk before send another one ?
If you see B4A code, I set the first timer interval to 100 ms, send info string, then decrease the timer interval to send file chunks.
Probably it should be wtitten in a different way.....
Actually I still test it on ESP32, but the code already adapted to ESP8266.
Note that C++ code can easlly managed to use other file systems, eg upload a file permanently on the ESP flash using SPIFFS or better LittleFS, FatFS etc.
It already support (but not tested) SDMMC eg on ESP32CAM, it can reach a transfer speed up 3MB sec.
Please help to make it always working (it always should work.... it is TCP, not UDP, it shouldn't miss packets, any file upload should complete successfully) .
Even please help to increase the upload speed, my results are around 250-300-350 Kbps, but sometime I've seen 500-600 and more Kbps on the log, so it can, it depends on many factors like a transmitter and receiver buffer size and a timer interval and a sd card write speed that increase tuning a buffer size. In 3D printing sometime there are relatively big files, like max 100 MB so I need to speed up a bit.
Many thanks
this is a code snippet but even an help request to improve it, so I post here before move on code snippets section.
For my 3D printing app host I had necessity to transfer files from Android to ESP8266-ESP32 micro sd card (over network).
Because I don't wanted to use an FTP library on ESP side to just upload a file, I wrote a raw code that read a file in chunks and then
send one by one using a TCP socket.
Because I even want to pass some infos from Android to ESP before send a file I send an info string that contain some variables I want to pass,
it even contain a file name, size etc... and other variables I've put here just as an example, you can put yours.
Here is how it works....
- B4A code send a request to ESP with a file size
- ESP check for a space in the SD Card, if there is space to save a file send a string SPACEOK and B4A will continue the upload, if there is no space it send a string NOSPACE and B4A stop the upload
- If there is a space to save a file on ESP SD Card, then B4A send the info string containing the file name, size and other stuff (variables) not used here. The info string is a splited delimiter string and ESP split it to extract all infos
- after this B4A start read byte chunks (buffer) from file and send to ESP that collect it and append chunk by chunk to a file on micro sdcard.
This worked well for a long time in my app, now I've changed something and sometime the transfer fails,
sometime Android (TCP CLIENT) send info string and ESP (TCP SERVER) do not receive it or receive but then do not receive file chunks,
when this happen sometime Android app completely stall, no errors, completely hang, the only way is to use Android menu to close it.
Because I need to make it always working I've decided to reproduce it in a small project and post it so maybe someone can help to improve this piece of code.
I've attached a working B4A (client) and C++ (server) code, errors only happen on my real app where I have other stuffs in the ESP loop() function.
Note that here there is a sort of data encryption (just for string commands) that I just disabled on this test.
Note that here in the B4A code I open the socket connection before send all data, then send all data, finally I close it. In my app I cannot do this, just I open the socket and mantain it always open, there is a button to connect/disconnect.
Note that I cannot convert ESP side to B4R because it is a big project I started in 2018, so I cannot use socket stream in prefix mode.
I've used a timer to send file chunks, probably this is not good, I noticed that when Android send a chunk of bytes, then wait ESP to download it, if ESP do not read bytes from the stream, Android just wait until ESP read it, so probably using a Timer is not a good option here ?
Maybe it is best send chunks in a Do While loop awaiting ESP that read a chunk before send another one ?
If you see B4A code, I set the first timer interval to 100 ms, send info string, then decrease the timer interval to send file chunks.
Probably it should be wtitten in a different way.....
Actually I still test it on ESP32, but the code already adapted to ESP8266.
Note that C++ code can easlly managed to use other file systems, eg upload a file permanently on the ESP flash using SPIFFS or better LittleFS, FatFS etc.
It already support (but not tested) SDMMC eg on ESP32CAM, it can reach a transfer speed up 3MB sec.
Please help to make it always working (it always should work.... it is TCP, not UDP, it shouldn't miss packets, any file upload should complete successfully) .
Even please help to increase the upload speed, my results are around 250-300-350 Kbps, but sometime I've seen 500-600 and more Kbps on the log, so it can, it depends on many factors like a transmitter and receiver buffer size and a timer interval and a sd card write speed that increase tuning a buffer size. In 3D printing sometime there are relatively big files, like max 100 MB so I need to speed up a bit.
Many thanks
Attachments
Last edited: