Guys on Prusa forum made a great change to improve the quality of prints. All information and the code can be found in the links.
Unfortunately, I can not adopt it to Marlin.
The issue produce artifacts like at photos.
Can I get a summary what was actually done?
@teemuatlut The main thing is switching to 0.9 degree motors. Then there is a huge amount of experimentation with different TMC settings, especially when not in Stealthchop mode, lots of experiments with different custom stepper waveform tables. I'm still reading through the various threads at the moment.
https://github.com/guykuo/Prusa-Firmware/tree/0.9-Degree-Stepper-Support
This is final version
I'm getting these VFA's very prominently on my printer. So the suggestion is to really use 0.9 Deg steppers? Why should the 1.8 Deg steppers not be capable of printing without these artifacts?
Looks like most of it is just another chopper preset.
Or if you want, you can already use custom values, or even tune further driver specific settings with ADV.
Can you give a good method to tune the TMC Drivers and get the best results?
What parameter to set?
How to determine the best settings, regardless of 0.9 Deg Vs 1.8 Deg steppers.
Maybe a test print (something similar to the test pattern in Lin advance)
Finally document it all
I also have VFAs on my printer and switching to a 0.9 stepper has certainly helped reduce them. I think the theory is that the motion of a stepper is not really that smooth (I guess the name "stepper" gives the game away) and that even with microstepping the motion is such that the stepper spends slightly longer at the 1.8 (or 0.9) degree points than it does in between them (think of it as the stepper slowing slightly as the poles of the stepper come into alignment). Various solutions have been tried (different current maps for the microstepping etc.), but it seems that simply having more poles works best. This may be because with the smaller poles there is less "slowing" as the motor moves past, or maybe 0.9 degree motors just have a different/better construction (there is some evidence that some 1.8 motors are better than others). I'm not sure if the current rating of the motor also comes into it, being able to drive the motor closer to the max current being a way to provide smoother motion. A lot of the stepper motors used on 3D printers seem to have a max current of above 1A (often around 1.5A or 1.8A) and TMC2130s are often not happy supplying that level of current. I really don't know for sure but that is my understanding of it. Feel free to correct me!
I'd also like to understand a good way to tune both spreadcycle and especially stealthchop for different motors.
AFAIK it is a pretty well known fact that microstepping accuracy varies greatly between motors (manufacturers). I remember how linengineering always boasts about their microstep accuracy with errors way below "industry standard".
TMC2130 allows you to (partially) adjust for this using a "Sine Wave Lookup Table", if I understood the feature correctly, and I believe Prusa owners have been experimenting with it, though I'm not sure what source data they use for the correction. Surely this has to be mechanical and not electrical, but I'm not aware of such a high-resolution rotary encoder (256 bits for 90deg, so you would need 200*256=51200
pulses per revolution, for a 1.8deg motor).
TMC2130 PDF mentions "... drastically improved microstepping especially with low-cost motors".
edit: Hah, Trinamic wins again, https://www.trinamic.com/fileadmin/assets/Support/Appnotes/AN026-Adaptive_Microsteptable.pdf
If you are interested in the Prussa approach to correcting the microstepping do a search for "prusa linearity correction" for more details.
Prusa has introduced custom messages in the gcode parser specifically for controlling the TMC params via gcode or rather TMC_ codes...
See the following to get the idea:
https://github.com/prusa3d/Prusa-Firmware/search?q=Linearity+correction&type=Code
That's fine and all when you're the one who supplies the motor and know the characteristics of your hardware. Unfortunately we don't have that luxury.
Would it be possible to create and M codes to set wave, set chopper?
See: https://github.com/prusa3d/Prusa-Firmware/commit/771cead291626113a38f2fbfd0ec634fee7376ac
The end goal is to be able to print a gcode file and dynamically update the TMC params on the fly. This will allow for per filament settings (if that even makes any sense) , and allow calibration tests..
What you think?
IMHO it makes no sense to have these runtime-configurable given how upstream Marlin usually handles its configuration (ie. RRF is a different story). They are specific to your motors only, not the kinematics, printer frame, hotend used or filament.
Prusa seems to have mostly mainstreamed this via some close-enough presets (at least for the E motor) that users can seemingly choose from,
https://help.prusa3d.com/article/p2xdpg0ul8-extruder-linearity-correction-calibration
Tuning this for any motor is currently fairly hard for two reasons:
1) The full procedure isn't very well documented
2) It cannot easily be automated
The second point stems from how Trinamic has implemented this (the way I understood it) - it's "easy" for a human to create a correcting waveform using the (up to) four segments (each with custom inclination) and in this low-resolution way fix the motion within bounds of the system, but there's no easy algorithmical way of deciding whether it's better to ie. use a higher W and less incremental correction or remain in current segment and just do a bunch of +1/+2.
One could probably make some crude algorithm, but this is really a job for a human or a trained AI.
As linked above, Trinamic actually proposes how to easily measure the error in the field using a laser pointer and a nearby wall, which is something we could each easily do. The problem is then taking the data and doing something with them.
Trinamic also provides a XLS that demonstrates the calculation, but I don't quite know how to use it with real data.
https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC5130_TMC2130_TMC2100_Calculations.xlsx
@teemuatlut's library seems to have all the necessary registers exposed ... so it shouldn't be that hard to actually use the data in Marlin's TMC_ADV
for testing, though it's a lot of data transformation for the human.
TMC2130's PDF section 5.5.1 nicely shows how to store the W inclinations and the X offsets denoting the inclined segments.
Yes, the registers are exposed through the TMC_ADV settings. However, having these configurable at runtime through gcode means that you don't have to recompile...…...every………..single...……... time...……... you make a change while testing.
My point exactly and probably why prusa took the route to allow setting on the fly...
@comps it is necessary for these to be runtime adjustable, otherwise it is not practical to have any kind of calibration/testing procedure that can fine-tune these settings.
@thinkyhead @Blue-Marlin @Roxy-3D @teemuatlut
Do you guys/gal think you would allow for TMC specific codes for configuration of TMC Drivers drivers.
We currently have:
M569 (Toggle between stealthChop and spreadCycle)
M906 (Set the driver current)
M913 (Set HYBRID_THRESHOLD)
M914 (Set SENSORLESS_HOMING sensitivity)
+Others for monitoring driver status.
The idea is to expose all TMC driver configuration via some set of M codes.
Prusa opted to allow some settings via TMC_ such as the wave table and backlash, stepper, and chop configs.
The idea is to be able to set the TMC (hopefully all) within gcode files which will allow the creation of utilities to allow dynamic testing of configuration with different parameters in a single print.
Think of how the temp towers we print today work, something along those lines.
@teemuatlut I know that prusa controls their own hardware to be able to write functions like this one below, however, do you see the value in what we're proposing, or... ?
else if (strncmp_P(CMDBUFFER_CURRENT_STRING, PSTR("TMC_"), 4) == 0)
{
if (strncmp_P(CMDBUFFER_CURRENT_STRING + 4, PSTR("SET_WAVE_"), 9) == 0) //! TMC_SET_WAVE_
{
uint8_t axis = *(CMDBUFFER_CURRENT_STRING + 13);
axis = (axis == 'E')?3:(axis - 'X');
if (axis < 4)
{
uint8_t fac = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 14, NULL, 10);
tmc2130_set_wave(axis, 247, fac);
}
}
else if (strncmp_P(CMDBUFFER_CURRENT_STRING + 4, PSTR("SET_STEP_"), 9) == 0) //! TMC_SET_STEP_
{
uint8_t axis = *(CMDBUFFER_CURRENT_STRING + 13);
axis = (axis == 'E')?3:(axis - 'X');
if (axis < 4)
{
uint8_t step = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 14, NULL, 10);
uint16_t res = tmc2130_get_res(axis);
tmc2130_goto_step(axis, step & (4*res - 1), 2, 1000, res);
}
}
else if (strncmp_P(CMDBUFFER_CURRENT_STRING + 4, PSTR("SET_CHOP_"), 9) == 0) //! TMC_SET_CHOP_
{
uint8_t axis = *(CMDBUFFER_CURRENT_STRING + 13);
axis = (axis == 'E')?3:(axis - 'X');
if (axis < 4)
{
uint8_t chop0 = tmc2130_chopper_config[axis].toff;
uint8_t chop1 = tmc2130_chopper_config[axis].hstr;
uint8_t chop2 = tmc2130_chopper_config[axis].hend;
uint8_t chop3 = tmc2130_chopper_config[axis].tbl;
char* str_end = 0;
if (CMDBUFFER_CURRENT_STRING[14])
{
chop0 = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 14, &str_end, 10) & 15;
if (str_end && *str_end)
{
chop1 = (uint8_t)strtol(str_end, &str_end, 10) & 7;
if (str_end && *str_end)
{
chop2 = (uint8_t)strtol(str_end, &str_end, 10) & 15;
if (str_end && *str_end)
chop3 = (uint8_t)strtol(str_end, &str_end, 10) & 3;
}
}
}
tmc2130_chopper_config[axis].toff = chop0;
tmc2130_chopper_config[axis].hstr = chop1 & 7;
tmc2130_chopper_config[axis].hend = chop2 & 15;
tmc2130_chopper_config[axis].tbl = chop3 & 3;
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
//printf_P(_N("TMC_SET_CHOP_%c %hhd %hhd %hhd %hhd\n"), "xyze"[axis], chop0, chop1, chop2, chop3);
}
}
}
#ifdef BACKLASH_X
else if (strncmp_P(CMDBUFFER_CURRENT_STRING, PSTR("BACKLASH_X"), 10) == 0)
{
uint8_t bl = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 10, NULL, 10);
st_backlash_x = bl;
printf_P(_N("st_backlash_x = %hhd\n"), st_backlash_x);
}
#endif //BACKLASH_X
#ifdef BACKLASH_Y
else if (strncmp_P(CMDBUFFER_CURRENT_STRING, PSTR("BACKLASH_Y"), 10) == 0)
{
uint8_t bl = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 10, NULL, 10);
st_backlash_y = bl;
printf_P(_N("st_backlash_y = %hhd\n"), st_backlash_y);
}
#endif //BACKLASH_Y
I don't like the Prusa style TMC_
gcode style. I'd rather copy the syntax from ReprapFirmware.
Neither do I fully agree with having these commands available to the user. While I do like that the variables of a software can be tuned, they should hold some meaning to the user and the effects need to be easily understood by the average end user. Try explaining the effects of hysteresis settings and the off time settings and then ask yourself if someone who's just looking to upgrade his Ender3 really needs to know about the theory behind chopper cycles.
But Marlin is nothing if not customizable, so I've been thinking if we should turn TMC_DEBUG
option to something like TMC_DEV_MODE
where certain commands or their specific flags would be available for those who want that level of control. The option never was intended to be enabled for normal use and it's not even necessary anymore for checking the connectivity with M122
.
Based on the distance between the artifacts, is it really possible that this is a microstepping issue?
Off the top of my head, guessing that the pulley is 10mm diameter, shouldn't the distance between the artifacts be 10×pi/200 ~= 0.15mm if this is an issue with microstepping accuracy on the x and y axes? I get that it is a possible issue on the extruder. Bizarre that swapping x and y motors seems to work. I think more experimentation is in order but stepper driver settings are probably a dead end.
Are we concluding to implement the calibration functions, it should we close this ticket?
will close this one as its mostly questions and information back and forth
not a bug or fr as such
we have a discord server for these kind of discussions
Marlin Discord server. Join link: https://discord.gg/n5NJ59y
Guys, is there any chance that this is going to be implemented? Having the problems described here. And my impressions from the discussion is: we don't like the way Prusa does it, so we are not interested. Hope there will be more people interested in this.
Have TMC2209 drivers on my board.
Guys, is there any chance that this is going to be implemented?
Please understand there is no project team here. People contribute what they can figure out. If no one has figured it out and submitted it then it's in limbo. As you can imagine there are a hundred issues with "when is this going to be done?" comments on them, and it's just pointless. Put the call out to the community to bring stuff to the project. Don't harp on the project to go out and solicit from the community.
@sedlacekdavid This would not work with a TMC2209 as it has fixed sine tables built in. The Prusa MX3 uses TMC2130 drivers where you can actually load custom lookup tables that correct for non-linearities.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
I don't like the Prusa style
TMC_
gcode style. I'd rather copy the syntax from ReprapFirmware.Neither do I fully agree with having these commands available to the user. While I do like that the variables of a software can be tuned, they should hold some meaning to the user and the effects need to be easily understood by the average end user. Try explaining the effects of hysteresis settings and the off time settings and then ask yourself if someone who's just looking to upgrade his Ender3 really needs to know about the theory behind chopper cycles.
But Marlin is nothing if not customizable, so I've been thinking if we should turn
TMC_DEBUG
option to something likeTMC_DEV_MODE
where certain commands or their specific flags would be available for those who want that level of control. The option never was intended to be enabled for normal use and it's not even necessary anymore for checking the connectivity withM122
.