How to send a BMP file to the ESP32 file system(SPIFFS) via websocket
No description provided.
Comments (16)
-
reporter -
repo owner Is the sending code sending the BMP file as binary data? What language/system is sending the data? Can you post the code that is sending it?
-
reporter hi John,
here is the sending code(Python)
# pip install pillow websocket-client from PIL import Image from websocket import create_connection # create a test bmp file size = (16, 16) img = Image.new('RGB', size, "black") pixels = img.load() for i in range(img.size[0]): for j in range(img.size[1]): if i == j: pixels[i,j] = (255, 0, 0) else: pixels[i,j] = (0, 255, 0) img.save("image.bmp") # send the file ws = create_connection("ws://172.20.10.2:81") with open('image.bmp', 'rb') as f: # opening a binary file content = f.read() ws.send_binary(bytearray(content))
-
repo owner Thanks! It looks like the MicroBlocks VM (primWebSocketLastEvent) is not correctly handling binary data. (It it reporting it as a string, which means that the first null byte terminates the string.) Will fix.
-
reporter The same problem seems to be present in MQTT library
import paho.mqtt.client as mqtt client = mqtt.Client() client.username_pw_set('public', 'public') client.connect("public.cloud.shiftr.io", 1883, 60) client.loop_start() ... client.publish('bmp', bytearray(content))
-
repo owner MQTT can handle binary data but you need to set the MQTT buffer size to 1024 (or higher) in order to receive the 822 byte BMP test file. (The default MQTT buffer size is only 128 bytes.)
-
reporter hi John , I set the MQTT buffer size to 1024 and 2048, the problem still seems to be the same
-
repo owner Are you sure that paho.mqtt.client can handle binary data?
When I did a test using MicroBlocks to publish the five bytes: 65, 65, 0, 65, 65 I got the expected result. That is, when receiving it as a string I got "AA" because the 0 is the string terminator:
When I received in binary, I got five bytes:
Based on this test, I think MicroBlocks MQTT is handling binary data as expected.
-
repo owner If your goal is simply to save images or other files to the file system of the ESP32/ESP8266, there's an easy way to do that. Using the stand-alone MicroBlocks app (not the webapp), select "show advanced blocks". Then, select "put file on board" from the File menu and select the file you want to save to the board. You can retrieve files from the board using "get file from board".
-
reporter Are you sure that paho.mqtt.client can handle binary data?
I think your test is convincing, the problem may be in
paho.mqtt.client
, but I didn't find it for now. It's okay, I don't need it for now, just a test.If I find the cause afterwards, I'll update here.
-
repo owner FYI, I've pushed a fixed version of netPrims.cpp to Bitbucket, in case you want to compile your own VM.
I'll do a pilot release later today.
-
reporter If your goal is simply to save images or other files to the file system of the ESP32/ESP8266, there's an easy way to do that. Using the stand-alone MicroBlocks app (not the webapp), select "show advanced blocks". Then, select "put file on board" from the File menu and select the file you want to save to the board. You can retrieve files from the board using "get file from board".
It sounds great ! I want to use it to upload some pictures.
But I also want to transfer images dynamically, about this, I will try in using websocket, I noticed that you have fixed it.
Thanks!
-
reporter - changed status to resolved
-
repo owner Note that the current WebSocket buffer size is only 1024 bytes. That means that you'll need to split large files into chunks of that size or smaller. That's not too complicated. You'll probably want to implement messages to indicate the start of a file transfer (including the file name) and the end of the file transfer. Those could be text messages (JSON, perhaps). While the file transfer is in progress, each incoming binary message would just be appended to the file. Make sure that the sending side includes a "sleep" to allow time for each binary chunk to be written to the Flash file system. The time for that can vary as the file grows and, because writing to Flash memory is slow (especially if Flash file system blocks need to be erased), the write times can be surprisingly long.
Actually, now that I think about it, it would be much more robust for the sender waits for an acknowledgement from the sender before sending the next chunk. That way it will adapt to the varying file write speeds.
-
repo owner Note that the current WebSocket buffer size is only 1024 bytes. That means that you'll need to split large files into chunks of that size or smaller. That's not too complicated. You'll probably want to implement messages to indicate the start of a file transfer (including the file name) and the end of the file transfer. Those could be text messages (JSON, perhaps). While the file transfer is in progress, each incoming binary message would just be appended to the file. Make sure that the sending side includes a "sleep" to allow time for each binary chunk to be written to the Flash file system. The time for that can vary as the file grows and, because writing to Flash memory is slow (especially if Flash file system blocks need to be erased), the write times can be surprisingly long.
Actually, now that I think about it, it would be much more robust for the sender to wait for an acknowledgement from the reciver before sending the next chunk. That way it will adapt to the varying file write speeds.
-
reporter Actually, now that I think about it, it would be much more robust for the sender to wait for an acknowledgement from the reciver before sending the next chunk. That way it will adapt to the varying file write speeds.
That's exactly what I did, and it worked fine !
Thank you for your detailed guidance!
- Log in to comment
When I read the payload, I got a string BM6