What speeds are possible for uploading to SD? (which also means speeds of printing over USB)

prusa mk3s+ here but with own firmware build to speed connection up:

-#define BAUDRATE 115200
+#define BAUDRATE 250000

Uploading 3191102 bytes gcode file (~3MB), via octoprint web interface, took 1015s which is 3143 bytes/s only!

octoprint.util.comm - INFO - Finished in 1015.228 s. Approx. transfer rate of 113.836 lines/s or 8.785 ms per line

(Edit: The same file, upload to repetier 1.0x firmware with 250000: octoprint.util.comm - INFO - Finished in 977.826 s. Approx. transfer rate of 118.190 lines/s or 8.461 ms per line)

That's very, very low throughput, far below serial connection capacity. But 9ms per line - per line handling could be a slow on prusa firmware side.

Did anyone else make such measurements to figure out which component is a major factor in such slowness, octoprint, prusa firmware or both interacting ineffectively?

Numbers from your tests are welcome.

Tests were done on raspberry pi 3 (cpu threads weren't even fully utilised), prusa provided (with printer) sd card.

File I was testing: http://ixion.pld-linux.org/~arekm/extruder-cover_0.2mm_PETG_MK3S_1h24m.gcode

This is not a matter of serial speed - this is a matter of Marlin firmware and how this handles uploaded files to store on the SD card: Line by line.

upload to sd is always slow because it's line by line unless binary file transfer is enabled in Marlin and the appropriate unregistered plugin installed.

1 Like

I have been experimenting with fiberpunk node module that emulates an SD card and has it's own wifi connection for receiving files via API. Have a POC plugin that intercepts the upload to SD and sends it via the API. Still some bugs to work out, but the upload speed is drastically improved.

SD cards seem to be inherently slow, particularly cheap ones. Try an Class 10 SD card. I use SanDisk Extream Pro on my Pi (I've never use the storage on the printer).

The SD transfer speeds don't affect the transfer of files over USB to Marlin much. The biggest bottleneck by far is the protocol, which transfers the file line by line, calculating a checksum for each line and doing a handshake with this checksum for each line.

1 Like

Curious if you ever messed with buffer buddy or serial_xon_xoff with the accompanying plugins?

I have not; I am personally not all that interested in transferring to the SD card.

well, buffer buddy is actually improving the ok checks and making sure the buffer is filling up and not staying partially full if I understand it properly, so improves sending commands over USB. Should only require advanced_ok to be enabled in firmware.

There are a number of issues. First, USB is limited by a number of factors. Unless is a USB 3 interface, you have a limit of 48 megabytes across all devices sharing the host hub. Second, baud rate settings on Serial to USB device is 3 megabits per second max or 300k characters. Then add the overhead of the protocol, latency of Marlin and speed the printer processor and you have all your overhead combined.

Hello @Oliver_Bailey !

You are correct in some points.
But the issue (bottleneck) of slow uploading gcode files via USB to printer's SD card is not the speed of the USB connection. It's the way Marlin handles the uploaded gcode file.
Marlin expects the file line by line with a checksum. A RPi can calculate that quite fast, must most printers run on an 8 bit board. And that takes a while.

where did you get that number from? Usb 1.1 got a max speed of 12mbit and usb 2.0 of 480 mbit - am I missing something?

I guess that depends on the used USB to Serial IC.
While the one on my Creality 4.2.2 board (I think it's a CH340) didn't support higher baudrates than 250000, the one on my SKR 1.4 turbo can handle 500000 just fine.

Looking at prusa Firmware/cmdqueue.cpp get_command() it does so many other things (beside checksum... which is just XOR, so cheap) when parsing each line.

Which thing there exactly is a major contributor to not reaching serial speed capability is a open question (if there is one major thing).

Speed of USB/serial itself is obviously non issue because current octoprint+prusa firmware does only ~3kbytes/s on 11kbytes/s capable (115200 bits/s including start/stop bit) connection.

Even if it would reach 11kbytes/s it would still be slow slow as hell for sd upload but...

What's weird is that I see small quality difference when printing over USB and directly from SD card. I guess slicer calculates everything (moves, accelerations etc) without considering bigger latency on serial. That possibly could be improved with buffering more g-codes than 1 as it is done currently.

Did you try to increase the buffers?

They're in this section in the Configuration_adv.h

// @section motion

// The number of linear moves that can be in the planner at once.
// The value of BLOCK_BUFFER_SIZE must be a power of 2 (e.g., 8, 16, 32)
#if BOTH(SDSUPPORT, DIRECT_STEPPING)
  #define BLOCK_BUFFER_SIZE  8
#elif ENABLED(SDSUPPORT)
  #define BLOCK_BUFFER_SIZE 16
#else
  #define BLOCK_BUFFER_SIZE 16
#endif

// @section serial

// The ASCII buffer for serial input
#define MAX_CMD_SIZE 96
#define BUFSIZE 4

// Transmission to Host Buffer Size
// To save 386 bytes of flash (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0.
// To buffer a simple "ok" you need 4 bytes.
// For ADVANCED_OK (M105) you need 32 bytes.
// For debug-echo: 128 bytes for the optimal speed.
// Other output doesn't need to be that speedy.
// :[0, 2, 4, 8, 16, 32, 64, 128, 256]
#define TX_BUFFER_SIZE 0

// Host Receive Buffer Size
// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough.
// To use flow control, set this buffer size to at least 1024 bytes.
// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]
//#define RX_BUFFER_SIZE 1024

#if RX_BUFFER_SIZE >= 1024
  // Enable to have the controller send XON/XOFF control characters to
  // the host to signal the RX buffer is becoming full.
  //#define SERIAL_XON_XOFF
#endif

I would also recommend to use the Arc Welder plugin either in OctoPrint or in your slicer.

These are from 32-bit firmware for prusa mini. I'm testing on mk3s+ which has 8-bit firmware.

Anyway what's the point of changing these buffers? octoprint still feeds only one g-code and then waits for response, right? If it would push more then buffers probably could make a difference but it doesn't do that.

Introducing yet another variable will only makes it harder to understand the problem.

Actually its the combination of the controller clock and the SPI clock combined with the speed of the SD card. SPI is not the fastest interface for reading and writing but is welll supported by all the controllers used in 3D printers.

Actually, USB to serial is covered in the USB specs, which I have yet to find one in 3D printers that was properly implemented in hardware. And that problem has spilled over into laser engravers as well.

USB 1.1 controllers haven't been used in a number of years. USB 2 replaced them and are backward compatible to support USB 1.1. Unless the controller interface is a 1.1, 48 Megabytes would be the total bandwidth on a current USB 2 controller. But I agree with you that is not likely the problem. I'm not familiar with the Prusa controllers, so I can't really comment on them. I have looked at Marlin and there is a lot of room for improvement in many areas of that firmware.

The BLOCK_BUFFER_SIZE option increases the number of moves that can be in the planner at once, so when the firmware receives a command, it will parse it and then work out what needs to go into the planner from there, and add the move to the queue. The ok doesn't wait for the move to actually be completed, just initially queued up. Similarly with the BUFSIZE option, it allows the printer to keep up at it's own pace a bit better. So increasing the buffers allows the firmware to process commands further ahead of where the printer is actually printing, leading to less likelihood of stuttering issues.
This is a very widely reported successful solution to solving the small stuttering/pausing problem for many people. If you need a better explanation of what all the individual buffers actually do, I am not an expert in the firmware so you will have to ask some of the Marlin people I suspect.

The settings do exist in Prusa's firmware for the 8 bit boards, although with the limited resources I suspect that they are as high as is possible. Prusa-Firmware/Configuration_adv.h at 8e72470afc38115b90058d0568b48961997235be Β· prusa3d/Prusa-Firmware Β· GitHub

With ArcWelder, it reduces the total number of commands that are sent to the printer by making lots of tiny straight segments into one single arc. Logically, the less commands to process the faster the file will be sent to the printer, so it is usually quite beneficial to use it.

You may apply as co-author there...

1 Like