teemuatlut / TMCStepper

MIT License
502 stars 196 forks source link

TMC5160 Global Scaler #4

Closed kAdonis closed 5 years ago

kAdonis commented 6 years ago

Hi First of all: thank you for this great work! Is there a reason you dont use Globalscaler for setting the current on TMC5160? Trinamic states in the Datasheet:

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.

it could be:

/*
  Requested current = mA = I_rms/1000
  Equation for current:
  I_rms = GLOBALSCALER/256 * (CS+1)/32 * V_fs/R_sense * 1/sqrt(2)
  Solve for GLOBALSCALER ->

                 32 * 256 * sqrt(2) * I_rms * R_sense    |
  GLOBALSCALER = ------------------------------------    |
                           (CS + 1) * V_fs               | V_fs = 0.325

*/
void TMC2160Stepper::rms_current(uint16_t mA) {
  uint32_t V_fs = 325; // x1000
  uint8_t CS = 31;
  uint32_t numerator = 1414UL * mA;
  numerator *= Rsense*1000UL;
  uint32_t scaler = numerator / V_fs; // (CS+1) is always 32
  scaler <<= (8); // Multiply by 256
  scaler /= 1000UL;
  scaler /= 1000UL;
  if (scaler < 32) scaler = 32; // Not allowed for operation
  if (scaler > 255) scaler = 0; // Maximum
  GLOBAL_SCALER(scaler);
  irun(CS);
  ihold(CS*holdMultiplier);
  //val_mA = mA;

This code is untested, I have two modified TMC5160BOB with a selfmade adapter-board on my 3D Printer, currently in standalone mode. I am waiting for a new adapter-board with SPI-support beeing etched. It should be ready next week. The TMC5160 are amazing, they ( and the mosfets) dont get even warm, with currents my TMC2130 overheat in 2 minutes.

Edit: Tested an my printer (CoreXY with RAMPS/Re-Arm and TMC5160for X/Y)

teemuatlut commented 6 years ago

It's simply because the current goal is still just to get it working. And it should work but there hasn't been much testing to prove it. It does make sense that we could/should use GLOBAL_SCALER for better granularity but I don't know if there are any other major advantages. This way we can also forego setting the irun and ihold values on each call. Unless of course the user calls the overloaded method with a hold scaler specified.

kAdonis commented 5 years ago

...but I don't know if there are any other major advantages.

Trinamic states in the datasheet:

For high precision motor operation, work with a current scaling factor in the range 16 to 31, because scaling down the current values reduces the effective microstep resolution by making microsteps coarser

Now as the Watterott TMC5160 are available, probably more people will use them in their 3d printers. Most stepper motors there need RMS current settings between 700 and 1000mA. The Watterott drivers have 0.075Ω sense resistors, which leads to CS values between 7 an 10, and therefore to low microstep resolution. To keep CS >= 16 Globalscaler is needed. Trinamic also recommends Globalscaler values above 128, so the best would be a combination of setting Globalscaler and CS for the rms_current method

Edit: I asked Trinamic Support and they answered, that setting the current with Globalscaler is recommended. It is like adjusting the current by means of an analog signal, like with TMC2208 drivers

I opened a PR with the above code for easy testing