TMCStepper icon indicating copy to clipboard operation
TMCStepper copied to clipboard

cs_actual()

Open cranefist opened this issue 3 years ago • 13 comments

Hello

Im simply printing this out :

Serial.print(driver.cs_actual());

Am i doing something wrong, as I was using a tiny motor first and the values seemed to be correct. It had max current set to 200ma. It was showing values in the range of 30-185, depending of my semin/semax etc settings. Everything seemed correct.

Now i'm using a larger motor, with max current set to 1000ma, but the values i'm seeing are in the range of 15-30.

Based on my power supply, its still operating correctly and my semin/semax settings seem to apply.

I tested both on the same platform, esp32 + tmc2209. Different motor voltage though.

Is there something i'm missing?

cranefist avatar Jun 16 '21 16:06 cranefist

cs_actual() returns the raw Current Selection value from the driver. This value is always between 0-31 and there should be no way for it be any higher as it can only occupy 5 bits.

If however you based your code on the example, then it's possible that before you were actually reading the raw value and then passing it to cs2rms function which returns you an rms value.

https://github.com/teemuatlut/TMCStepper/blob/ddc0c121af9117c14c173427f1dae165d8409ea5/examples/StallGuard_TMC2209/StallGuard_TMC2209.ino#L117

teemuatlut avatar Jun 16 '21 16:06 teemuatlut

Thanks for the quick reply.

Yes, you are correct. I made this test code based on something i had worked on for a long time and had forgotten that i indeed read it into a variable in that manner.

But now when i use this, i get really high values. It tops at bit over 1700 and bottoms at around 450, while my max current is set to 1000. While on the power source, its between 160-800ma, and that seems to be about what i expect based on my settings.

cranefist avatar Jun 16 '21 17:06 cranefist

Can you post your code that you're using for reading the values?

teemuatlut avatar Jun 16 '21 18:06 teemuatlut

Serial.print(driver.cs2rms(driver.cs_actual()),DEC);Serial.println(" MA MOTOR CURRENT");

Just this now. On the smaller motor, i just read that into a INT variable and printed it.

cranefist avatar Jun 16 '21 18:06 cranefist

No I mean the rest of it as otherwise I can only throw guesses. Perhaps you're making a call to irun or maybe there's a communication error when the cs2rms tries to read vsense bit.

teemuatlut avatar Jun 16 '21 18:06 teemuatlut

//STEPPER
#include <FlexyStepper.h>
#include <TMCStepper.h>

#define DIR_PIN          15 // Direction
#define STEP_PIN          2 // Step

#define STALL_VALUE       0 // [0..255]
#define SERIAL_PORT Serial2 // HardwareSerial port
#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2
#define R_SENSE       0.11f // 0.11 for MKS TMC2209
#define AMPS           1000 // MAX CURRENT

int micro = 0; //MICROSTEPS
unsigned long Timer;

TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);
using namespace TMC2209_n;
FlexyStepper stepper;

//TASKS
TaskHandle_t Motor;
TaskHandle_t Print;
TaskHandle_t Plotter;

void setup() {

//SERIALPORTS 
Serial.begin(115200);           // INTITIALIZE SERIAL0 ITERFACE
Serial.println(F("--------------------------------------------------"));
while(!Serial);   
Serial.println(F("Serial intitialized"));
SERIAL_PORT.begin(115200);      // INITIALIZE SERIAL2 UART FOR TMC2209
while(!SERIAL_PORT);
Serial.println(F("UART intitialized"));
Serial.println(F("--------------------------------------------------"));


//TMCSTEPPER SETTINGS
driver.begin();                                               
driver.toff(3);                  // enable driver in software
driver.rms_current(AMPS);        // motor RMS current
driver.seimin(1);                // minimum current for smart current control 0: 1/2 of IRUN 1: 1/4 of IRUN
driver.semin(5);                 // [0... 15] If the StallGuard4 result falls below SEMIN*32, the motor current becomes increased to reduce motor load angle.
driver.semax(4);                 // [0... 15]  If the StallGuard4 result is equal to or above (SEMIN+SEMAX+1)*32, the motor current becomes decreased to save energy.
driver.sedn(2);                  // current down step speed 0-11%
driver.seup(2);                  // Current increment steps per measured StallGuard2 value 5 seup0 %00 … %11: 1, 2, 4, 8
driver.blank_time(24);
driver.TCOOLTHRS(0xFFFFF);       // FFFFF
driver.microsteps(micro);       // microsteps
driver.en_spreadCycle(false);   // spreadCycle
driver.shaft(false);             // direction
driver.ihold(2);                // hold current  0=1/32 … 31=32/32
driver.iholddelay(3);           // 0 - 15 smooth current drop
driver.irun(31);  
driver.SGTHRS(STALL_VALUE);
         

       
//driver.I_scale_analog(0);   // if 5v vdd


//FLEXYSTEPPER SPEED & ACCELERATION
stepper.connectToPins(STEP_PIN, DIR_PIN); // INITIALIZE FLEXYSTEPPER
stepper.setSpeedInStepsPerSecond(2000);
stepper.setAccelerationInStepsPerSecondPerSecond(2000); 


xTaskCreatePinnedToCore(MotorTask,"Motor",5000,NULL,5,&Motor,1);
//xTaskCreatePinnedToCore(SerialPlotter,"Plotter",2000,NULL,1,&Plotter,0);
xTaskCreatePinnedToCore(PrintTask,"Print",2000,NULL,1,&Print,0);

}

//MOTOR--------------------------------------------------------

void MotorTask(void*) {
  
for(;;) {
Timer=millis();

stepper.moveToPositionInSteps(1000);
stepper.moveToPositionInSteps(0);
  
vTaskDelay(1);

}
}

//SERIAL PLOTTER--------------------------------------------------

void SerialPlotter(void*) {
for(;;) {
//Serial.println(driver.SG_RESULT());
Serial.println(driver.cs2rms(driver.cs_actual()),DEC);

}
}

//PRINT SERIAL--------------------------------------------------

void PrintTask(void*) {
float RAM;
int MA;
for(;;) {
//MA=driver.cs2rms(driver.cs_actual());
 

Serial.print(driver.SG_RESULT());Serial.println(" STALLGUARD"); 
Serial.print(driver.cs2rms(driver.cs_actual()),DEC);Serial.println(" MA MOTOR CURRENT"); 
Serial.print(driver.microsteps());Serial.println(F(" MICROSTEPS"));
Serial.print(getCpuFrequencyMhz());Serial.println(F("/240 MHZ CPU"));
RAM=ESP.getFreeHeap();
Serial.print(RAM,0);Serial.println(F(" RAM LEFT"));
//Serial.print(100 - ((RAM / 327680) * 100),0);Serial.println(F("% RAM USAGE"));
Serial.print(Timer/1000);Serial.println(F(" S UPTIME"));
Serial.println("------------------------------------------------------");
vTaskDelay(500);
}
}

void loop() {
vTaskDelete(NULL);
}

cranefist avatar Jun 16 '21 18:06 cranefist

driver.rms_current(AMPS);        // motor RMS current
...
driver.ihold(2);                // hold current  0=1/32 … 31=32/32
driver.iholddelay(3);           // 0 - 15 smooth current drop
driver.irun(31);  

You're overriding whatever rms_current does with calls to irun and ihold. Since irun cs = 31 and with rsense of 0.11, the current is 1700mA.

teemuatlut avatar Jun 16 '21 18:06 teemuatlut

Great! Thanks for pointing that out.

I was not actually using irun on the smaller motor, i did use ihold.. and it seemed to do what i expected it to do. I remember testing irun at some point though.

I thought irun defined percentage of the max current. Still trying to learn all these values. Extremely happy about this library, having all this control is amazing. Especially on battery powered projects.

And now as we are on the subject of RSENSE... why is the an "f" behind the 0.11? I just kept it from the examples.. but it bothers me because i dont know why its there.

cranefist avatar Jun 16 '21 18:06 cranefist

irun and ihold write directly to the driver while rms_current is helper function that converts a current value into these register values. The driver itself doesn't know anything about milliamps or the sense resistor values.

The f is a literal suffix to denote that the value is a float. It's not really necessary unless the compiler defaults to doubles.

For battery powered projects you might find the TMC2300 interesting.

teemuatlut avatar Jun 16 '21 18:06 teemuatlut

Seems interesting, i'm actually using this exact same motor on my other project. Its amazing little motor. Seems there are not many ready made solutions for TMC2300. That's why i have been using TMC2209 as its easy to get started with. But on that tiny motor the stall guard is a bit erratic. Its good for current control, but as a limit switch it sometimes works and sometimes doesn't.

https://twitter.com/jipraus/status/1370077477977083907/photo/1

cranefist avatar Jun 16 '21 19:06 cranefist

Is it pointless to use ihold without the irun? Or does irun get values from the rms_current and thus simply using ihold works? This would keep it simple for me, as i only need to define a hold current anyhow.

cranefist avatar Jun 16 '21 19:06 cranefist

The TMC2300 is supported on the v1 release branch.

rms_current will by default set ihold to 50% of irun but you can set your own ratio with additional second argument; rms_current(1000, 0.3).

teemuatlut avatar Jun 16 '21 19:06 teemuatlut

Ok, thanks a lot! This is good, the other benefit for me is that i can run that tiny motor way over its intended current and still keep it cool thanks to being able to regulate its current, and almost shut it off in hold mode.

I have no further questions :) Really appreciate your work.

cranefist avatar Jun 16 '21 19:06 cranefist