TMC5160.py hard sets CS to 31 causing chopper hysteresis issues

MCU / Printerboard: tmc5160, all versions

Describe your issue:

The current TMC5160.py code hard sets the current sense values to 31. The datasheet for this driver is less than forthcoming on how to calculate the CS values. This issue may exist on other Trinamic drivers, but I have not investigated this.

The current code leaves CS out of the initial calculation of Globalscaler which has the result of effectively setting the CS value to 31 per page 74 of the datasheet, where (1+CS)/32 = 1.

The implications of this are that on some motor, driver, voltage combos, the correct hysteresis values can not be set in the driver. LDO 2804 motors particularly come to mind as many people implementing these motors at higher voltages find that they donā€™t run well, create VFAs at low speeds, are noisy, overheatā€¦

Trinamic is not forthcoming with the fact that there is a tuning spreadsheet which gives us the CS value. The CS value needs to be set where the Rsense in cell C47 is +/-3% of the Rsense value. Once this is implemented, the rest of the spreadsheet can be used to effectively tune the chopper parameters.

For now I have created this code, which auto calculates the CS value based on Rsense.

There are likely to be negative consequences to implementing the code to auto calculate the CS value, after everyone has already tuned their drivers. Exposing the CS value as a user input would likely be the best option.

I would like feedback as to whether the code works as expected. Itā€™s working on my machine, but I am using the drivers slightly outside of their recommendations. Please understand that drivers will need to be retuned when implementing this code. Failing to follow the tuning spreadsheet may result in device failure.

Spreadsheet here:

https://www.analog.com/media/en/engineering-tools/design-tools/TMC220x_TMC222x_Calculations.xlsx

Wasnā€™t the consensus among Trinamic and Klipper that it is enough to set the run currents only?
I was dealing with the spreadsheets for the TMC2209 and TMC5160 but canā€™t remember whether the CS changed when setting different currents and other parameters.

In most cases TMC5160 are overkill for the used motors. But yeah I use them as well. :smiley:

I have not seen anything on this in my research. According to the spreadsheet CS is used in the chopper hysteresis calculations though, so not defining it according to the spreadsheet can and does cause hysteresis issues.

I wanted them because theyā€™re the only driver that can run 60V. Iā€™m also running paralleled 2804ā€™s off a single driver, which I understand is less than ideal, but presents an issue where Iā€™m pushing the driver to the edges of what itā€™s capable of. So I absolutely have to drop the CS value to get the motors to work correctly. And it makes a massive difference.

I donā€™t think CS changes for either 2209 or 5160, but I havenā€™t confirmed this.

1 Like

The issue in my opinion is that the step-sticks manufacturers value marketing blabla higher than solid technical reasons.

The chosen R-Sense of all TMC5150 driver that I know are completely off reality WRT their usage in 3D printers. And with every generation, e.g. this it gets worse and worse.

In the end, the users think that ā€œmore is betterā€ but exactly the opposite is the case: Running a stepper with the required IRMS of 0.6A off a TMC5160 with an IRMS of 3A or more is just bad.

You automatically degrade the driversā€™ ability to control the current in fine steps as the driver only is able to offer its control range between 0 A and 3 A where a control range of 0 A to 0.6 A is needed.

This is like trying to fly a Saturn V rocket at walking pace in a pedestrian zone.

Regarding the CS topic here:
Did anyone with the needed knowledge compare it to the reference implementation that Analog Devices is providing (Code search results Ā· GitHub) or their IDE or other implementations like the GitHub - teemuatlut/TMCStepper implementation that Marlin uses?

The chosen R-Sense of all TMC5150 driver that I know are completely off reality WRT their usage in 3D printers.

Agreed, but there are circumstances in which changing the CS to a lower value exposes adequate hysteresis settings that were not available before, while changing the Rsense to a more reasonable value would not help. Itā€™s my understanding from reading the datasheet that Rsense, CS, and globalscaler are all used to scale Irms internally.

Take the LDO 2804, which Iā€™m using. If I were using one motor per driver, I kept the CS at 31 (which is the ideal situation) and changed the Rsense to match the 0.094ohm output in C47, the value in cell C30 HystStart_MIN is 30, and results in inadequate hysteresis for the chopper.

When we drop the CS value to somewhere around 22-23, and use a 0.066ohm resistor, this results in an adequate hysteresis.

Klipper attempts to calculate the CS value automatically. The problem is the Trinamic datasheet only gives us one formula to calculate both CS and Globalscaler, makes no mention in the datasheet that CS affects Spreadcycle (as far as Iā€™ve found), and doesnā€™t mention that the tuning spreadsheet contains a calculation for CS. Systems of equations say one equation, two unknowns can be solved for zeros, but otherwise results in infinities, if I remember correctly.

So when just referencing the datasheet, itā€™s unclear how to calculate CS. Klipper goes about leaving it out of the globalscaler calculation, which sets it to 31 via pg 74 of the datasheet. (CS+1)/32 = 1, multipying by 1 does nothing.

2 Likes

Iā€™m not sure that I fully follow you here.
The R-Sense value is determined by the resistor soldered on the board and this determines the range of power control the driver offers.

Iā€™m aware of the tuning logic to modify the parameters in such way that you ā€œhitā€ the hardware R-Sense as close as possible while keeping CS, chopper frequency and voltage within the applicable targets.
But this is essentially putting the cart before the horse in the first place and the more the hardware R-Sense and its resulting IRMS deviate from the actual needs of the stepper motor the harder it gets to have halfway decent values.

This becomes especially evident for the pancake type steppers with their very low current requirements.
Here the requirements of

  • Ideally CS=31
  • Hitting the hardware R-Sense value
  • Meeting the stepperā€™s low current requirements

become mutually exclusive and impossible to fulfill.

I have spent a good deal of time hunting for the optimal values, even with an oscilloscope, but meanwhile I have given up on it as I do not see any appreciable real world benefits.

I rather believe that a lot of people do not really know what they are tuning there (me neither - itā€™s black magic) and the danger of making it worse is higher than doing any good.

1 Like

Correct. It would be more correct to say that this is how the driver determines the current in a real world application. This isnā€™t just in stepper drivers, itā€™s pretty much the same in every piece of electronic circuitry that determines current. Voltage drop over a sense resistor. I=(V1-V2)/R

Correct, but what the spreadsheet doesnā€™t tell you explicitly is that the CS value also affects HystStart_Min.

HystStart_Min=MAX(0.5+(Coil_Current_Total)* 2 * 248*(CS+1)/I_peak/32-8,-2)

It does tell you that ((HSTR + HEND) > HystStart_MIN) in order to maintain adequate hysteresis. HSTR can be at max 7, HEND at max 15. If HystStart_MIN is over 22, you have inadequate hysteresis and this will result in your motors overheating because they canā€™t get rid of the charge in the coils.

CS directly scales both Rsense and HystStart. So if HystStart_Min is > 22, you can reduce CS. This will scale Rsense as well, so itā€™s not rent-free, as the value output in C47 still needs to be +/-3% of Rsense. We also need to make sure that CS > 16 and Globalscaler > 128.

CS ideally should be 31, but Globalscaler ideally should also be 256 (and itā€™s not, nor will it ever be it has to scale). If we understand that these are idealizations, and not requirements, we can much more effectively tune our drivers.

One could run an Orbiter V2 at 60V by pushing the limits of a BTT tmc5160t plus (the 10A rms one). I have attached a picture of the tuning spreadsheet with the pancake motor the Orbiter V2 uses prefilled. I understand that we are getting a hysteresis warning, because we are slightly past the edge of what that driver, motor, voltage combo will allow, but I am so confident those settings will work that I plan on putting my Orbiter V2 on 60V myself (if we drop the voltage to 48V we should be comfortably within the hysteresis settings with a 0.022 Rsense). The machine Iā€™m using is about pushing the limits, and Iā€™m finding those limits and trying to fix them to help everyone move forward.

I hope looking at that picture helps you understand Rsense, CS, and the hysteresis settings and how theyā€™re all linked together.

You can call me Voldemort if you want.

-Brandon, BSECE

For the TMC5160, it is my understanding the spreadsheetā€™s CS value actually is I_RUN, which should ideally be 31 at the desired run_current and GLOBALSCALER should be set by Klipper to the value that fulfills this condition.
Then, for optimal precision, I_RUN should scale between 16 and 31 (which corresponds to the TMC2209ā€™s VSENSE=1).

Iā€™d be more worried about the VM_upper_limit[V] warning if you intend to supply it with 48V or 60V. This could be a sure way to cook the stepper.

Edit:
It is not my goal to be right, it is my goal to better understand this stuff, so I do enjoy such exchanges.
Whenever there are talks about this, I get the feeling that 5 people have 6 opinions how this should work or how the TMC specifications should be interpreted.

Right, this is why itā€™s imperative that I have the correct hysteresis settings, because running the settings correctly is the reason we can use high voltages. The purpose of a chopper is to run higher voltages on the motor. Without exposing CS these motors get above 120C, and melted my motor mounts.

With my code, they run at 65-70C at Irms (not 80%).

I_run does not scale in the current Klipper code. It is unintentionally always set to 31. Globalscaler is the only setting that scales the current.

Thanks for starting this thread! Just to reiterate my feedback from the PR:

  • It seems you have a bit obscure setup that is, according to my understanding, is discouraged by the stepper driver manufacturer. Specifically you are running two stepper motors on a single stepper driver in parallel (my understanding that if you absolutely have to run two stepper motors from one driver, they should be in series).
  • You may have used the wrong TMC spreadsheet to tune the stepper motor parameters (since you have been referencing TMC22xx spreadsheet on multiple occasions, and you have TMC5160 drivers, and I do not know whether they run the same calculations or not).

As such, Iā€™m not sure whether the improvements you got were accidental and just happen to work better for your specific setup or whether this change will provide universal benefits to all users. So, it would be great if other people could test your changes and replicate your improved results. And just to clarify, the correct spreadsheet to use to tune TMC5160 stepper chopper parameters is this one (ā€˜Chopper Parametersā€™ tab):

https://www.analog.com/media/en/designtools/calculators/tmc5160_calculations.xlsx

Oooops, thanks for the correct spreadsheet!

And yes, I am on an odd setup, thatā€™s technically slightly outside of the drivers capabilities. I still believe exposing CS will help everyone.

Also, please note my code may incorrectly calculate CS, as I used the wrong spreadsheet. I will expose CS as a variable that can be set when I get the chance and update the thread.

Code should be updated to use the correct formula from the spreadsheet. Please check the math yourself. I believe current in the code is the current input by the user, and the current in the spreadsheet is max current.

Edit: I updated this. My math was wrong.

cs = 32 * ((self.sense_resistor/.32)*(current*math.sqrt(2))) - 1 #check math

Hereā€™s another application example, in light of Dmitry pointing out I was using the wrong spreadsheet. :rofl:

LDO 2804 specs: 0.6mH, 0.7ohm resistor, 2.8Apeak. If we run these on one of the step sticks at 48V, 3A, 0.075Rsense, keeping CS 31, we get the following with inadequate hysteresis and Rsense out of range:

Change the CS to 20 and we match +/-3% of the installed Rsense at 0.075ohm, green across the board aside from the voltage warning. Iā€™ll attach a picture in another comment because I am too new to have multiple here.

You could probably further tweak my examples with changed CS values, try to get TBL to a more sane number, adjust toff to get the motors quieter/less hot, and so on.

I believe a lot of people are thinking that CS should be set to 31 because of the blue hint box on pg. 75:

ā€œHint
For best precision of current setting, it is advised to measure and fine tune the current in the application. Choose the sense resistors to the next value covering the desired motor current. Set IRUN to 31 corresponding 100% of the desired motor current and fine-tune motor current using GLOBALSCALER.ā€

This would be the ideal situation, but it doesnā€™t work that way. Good engineering practice should leave a little bit of overhead, anyway, which Trinamic recommends later in this section. In order for the above to even work:

  1. The average user would have to understand that they need to chose a driver whose Rsense provides max current matching their motor, so CS can remain set at 31. Rsense wonā€™t match the motor that precisely. There arenā€™t enough sense reistors made to match every motor. Especially considering that Klipper is/should be hardware agnostic.
  2. Even if we match the Rsense values correctly to the motor, the chopper hysteresis may not work as we expect it to as I demonstrated above.
  3. Matching Rsense to the max current would also require the user of these drivers to design their own board, or desolder and resolder a sense resistor. SMT rework is a lot for Klipper to ask of its users.

Updated the code:

I added a field called tmc_cs: which can be called under:

[tmc5160 stepper_*]
tmc_cs: #some number between 16 and 31

Code needs cleaning up. If no tmc_cs is defined, it will default to 31.

Here is the picture from the last comment about using the correct settings for CS.