Ever since I designed and built my own DIY 3D printer, followed by rebuilding my Anet A8 with the AM8 frame and the E3D v6 bowden hotend/extruder, I moved to Marlin firmware (as opposed to Repetier Firmware), and started printing much faster, with high accelerations and jerk.
There was one issue that became obvious from the very beginning: often when I printed some object with a lot of short & fast movements via Octoprint (running on a Pi Zero), the movements were jerky, and the print quality was BAD. Like this:
Note: before you jump to any conclusions – this is not my usual print quality. This is an extreme case, designed specifically for making the issue more visible.
It was nothing new to me – “everyone knows” that printing via USB / Serial link has it’s limitations, and “everyone knows” that the Pi Zero is not very powerful.
So initially, I blamed the “slow” Pi Zero and/or serial link.
I use the dedicated serial pins on the Pi Zero, connected directly to the serial pins on the Anet mainboard, so at least I don’t have to worry about crappy USB to Serial conversion.
I decided to do some systematic tests, so I can find out what exactly was happening.
The results were quite interesting.
For the tests, I created a small cylinder model – 10mm radius, 5mm height, 256 sides. The high number of sides (segments) was needed, because I wanted to have a small object with a lot of short movements.
So here’s the first round of tests I did:
- Printing from Octoprint, running on my PC. The issue is there, although not as bad as on the initial picture.
- Printing from SD card – perfect result. As expected.
- Printing from Octoprint, running on the Pi Zero, with disabled LCD display support in Marlin. Hmm… that’s better. But impractical. I NEED the LCD.
- Printing from Octoprint, running on the Pi Zero, with my tweaks. Not as good as the SD print, but quite close. Read on…
So, what did I do in image 4? Well, it turned out that the default Marling configuration, and the example configuration for Anet A8 and A6, share one thing in common: very small serial and path planner buffers. The serial input buffer size was just 4! For comparison, it was 32 when I used Repetier, and is 16 on the stock Anet firmware (which is also Repetier).
Which means that if the printer prints enough number of moves fast enough, the buffer gets empty, because the data, coming from the serial link can’t keep up. This results in jerky motion while the printer is waiting for the next gcode command to arrive.
So, I opened the Configuration_adv.h and changed BLOCK_BUFFER_SIZE to 128, and BUFSIZE to 32:
#define BLOCK_BUFFER_SIZE 128 // SD,LCD,Buttons take more memory, block buffer needs to be smaller
#define BLOCK_BUFFER_SIZE 128 // maximize block buffer
// @section serial
// The ASCII buffer for serial input
#define MAX_CMD_SIZE 96
#define BUFSIZE 32
You might have noticed that BLOCK_BUFFER_SIZE is present on 2 places. The first place is taken into account when you have enabled SD card support (this is the default configuration).
The second place is used when SD card support is disabled.
Yes, I know – the BLOCK_BUFFER_SIZE seems rather high – especially if you read the comments in the code.
But it works quite well with my configuration – the Anet mainboard + 2004 LCD display (i.e. the stock Anet A8 electronics).
If your printer starts acting strange (e.g. showing garbage on the LCD) or constantly reboots, this means there is not enough RAM for a buffer this big. Just lower the value, re-flash the firmware and try again. Just keep in mind that it needs to be a power of 2, e.g. 8,16,32 etc.
It’s likely that you won’t be able to use buffers that big if you use graphics LCD (like on the Anet A6) or some of the other “advanced” features that require more RAM – like the ABL_BILINEAR_SUBDIVISION etc.
Update 2018-06-16: It seems the current Marlin-bugfix-1.1.x branch gets very unstable when I use these buffer settings… And Octoprint still prints far worse than Repetier Server when printing high-poly models. Not much of a progress here…
Side note: that’s why I like the “dumb” 2004 displays – they leave room for other, more useful stuff.
I also changed the DEFAULT_MINSEGMENTTIME parameter to 50000:
#define DEFAULT_MINSEGMENTTIME 50000
What is DEFAULT_MINSEGMENTTIME?
It’s taken into account when the path planner buffer gets half-empty, and makes the firmware ensure that each “move” does not take less than 50ms, by reducing the speed, instead of just waiting for new data to arrive on the serial link.
This allows the link to keep up.
I have discovered that the default value of 20000 is too short.
For comparison, it’s 25000 in Repetier Firmware.
So, after a couple of experiments, I found that 50000 works best for me.
Anyway, with these three changes, the results were much better – almost as good, as when printing from SD card.
Unfortunately it’s closed source, so it’s a no-go for me. I don’t support closed-source projects.
I’d rather help improve Octoprint.