-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Implement TMC2130 constant torque algorithm for improved stepper motor performance #4871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: MK3
Are you sure you want to change the base?
Implement TMC2130 constant torque algorithm for improved stepper motor performance #4871
Conversation
|
All values in bytes. Δ Delta to base
|
4e1b433 to
73bcafa
Compare
…r performance - Add tmc2130_calc_constant_torque_value() function implementing advanced constant torque algorithm - Maintain |A|² + |B|² = constant throughout microstep cycle for consistent motor torque - Use full range utilization (SIN0=0, AMP=248) with natural mirroring approach - Add EEPROM settings for wave algorithm selection - Include menu integration for runtime algorithm switching - Add complete internationalization support for TMC2130 stepper configuration strings References: - Analog Devices AN-026 application note
73bcafa to
5251bfe
Compare
gudnimg
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for opening a PR! I left some comments with initial thoughts/feedback.
Can you explain a bit why one would choose the constant torque algorithm over the previous one? What is the problem it tackles/solves? Are there any downsides?
I unfortunately don't have a printer to test this on myself.
| // Determine allowed delta range | ||
| // This ensures delta ranges match slope ranges for optimal compression: | ||
| // slope ∈ [0,1) → deltas ∈ [0,1], slope ∈ [1,2) → deltas ∈ [1,2], etc. | ||
| int8_t min_delta = (int8_t)floor(slope); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the floor function required? It treats positive and negative numbers differently.
Would it work for slope to be int8_t instead of float if we are truncating the value anyway? I don't see slope being used anywhere after this line.
| // Phase 1 (positions 0-127): Power-corrected sine curve | ||
| // Calculate theoretical value using sine function with power factor | ||
| // correction and tcorr adjustment for midpoint matching | ||
| float sin_val = sin(M_PI * (float)i / 512.0f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect the compiler doesnt calculate M_PI / 512.f constant at build time.
If I'm right this will consume less memory and drop one division operation:
constexpr float sin_gain = M_PI / 512.f;
float sin_val = sin(sin_gain * i);I may be wrong but I think I have seen this happen before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this is only calculated upon startup or changing of the value, I did not spend too much time optimizing, but I can certainly investigate further.
| if (min_delta < -1) { | ||
| min_delta = -1; | ||
| } else if (min_delta > 2) { | ||
| min_delta = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sometimes we can save some memory by using the constrain macro. https://docs.arduino.cc/language-reference/en/functions/math/constrain/
min_delta = constrain(min_delta, -1, 2);It wouldnt save much but perhaps some.
| #define EEPROM_UVLO_MIN_SEGMENT_TIME_US (EEPROM_UVLO_MIN_TRAVEL_FEEDRATE-4) //uint32_t | ||
| #define EEPROM_UVLO_MAX_JERK (EEPROM_UVLO_MIN_SEGMENT_TIME_US-4*4) // 4 x float | ||
| #define EEPROM_CHECK_FILAMENT (EEPROM_UVLO_MAX_JERK-1) // uint8_t | ||
| #define EEPROM_TMC2130_WAVE_ALGORITHM (EEPROM_CHECK_FILAMENT - 1) // uint8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new variable should also be documented in the large table near the top of this file. Between lines 100-400 :)
|
There are some compiler warnings during the build, these need to be resolved. Examples: See: https://github.com/prusa3d/Prusa-Firmware/actions/runs/15947546512/job/44997438159?pr=4871 |
|
@gudnimg Thanks for looking into the PR! I should have stated that first - this PR is in the realm of very, very subtle optimizations (as the whole linearity correction anyways). The standard current wave is sinus and cosinus for the two respective phases of the stepper. That guarantees constant torque throughout the microstepping positions. However, when the Standard Prusa linearity correction curve is appliad, the torque on the stepper varies throughout microstep position (as the provided curves explain). Now - as long as the torque is sufficient, no issues are observed, but the torque is lower for high values of correction factor. This PR adresses that, and instead provides a curve that very closely resembles the stock one, but calculates the values in the other half in a way that the constant torque is maintained throughout all microstep positions. If there is interest by community for this fuctionality, I am more than happy to apply all the requested changes - personally I even believe this can substitute the default linearity compensation, and no EEPROM changes would be needed, but as. it is, it is easy for anyone to just test the behavior and then go back to stock. |
This PR implements constant torque algorithm which maintains
|A|² + |B|² = constantthroughout the microstep cycle for TMC2130 stepper drivers. The algorithm is inspired by ideas presented in Prusa3d forum, but reimplemented from scratch.User Interface & Configuration
Algorithm Implementation
Testing
Algorithm comparison
The Curve is pretty much identical to the original in the first half, jsut scaled to have correct midpoint value. It still helps with moving the miscrosteps positions almost identically as the original, however it maintains constant torque. Real world results on my steppers show, that the constant torque algorithm needs slightly higher correction factor to achieve the same results on prints, in my case with default value 80, the const torque algorith provided best results at around 100. The differences are so negligible though, that I failed to capture it on camera.