Open the file in rb
mode in your Python code.
Since the Arduino SoftSerial RX buffer is 64 bytes in size, sending 60 bytes per packet to the Arduino is okay. You basically call out = file.read(60)
in python to read 60 bytes from the file and then write these bytes to the Arduino with ser.write(out)
. You can have the python program wait for acknowledgement from the Arduino, perhaps indicating how many bytes it actually received (after a given timeout period) or what byte was last received. This is just very minor error detection.
The Arduino saves the 60-byte packet to an array and writes everything at once to a file on the SD card, that you've already opened.
After receiving acknowledgement from the Arduino, the Python program reads the next 60 bytes and forwards to the Arduino like before. Continue till the file is exhausted. You could send some sort of signature byte to inform the Arduino that no more bytes are coming and to close the file. Alternatively, a timeout period can be used.
Note: It'll be more efficient if you wrote to the SD card in chunks, where the chunk size is a factor of the card's sector size. 64 bytes is the highest you can do with the default RX buffer size, but thats living dangerously as you risk buffer overflow if anything goes bump.
This can be avoided though, by reading bytes from the RX buffer and into your own array, as soon as they arrive.
Chunks of 32 bytes is safer but it will naturally take longer to send the whole file. Test and judge for yourself.