TMCStepper icon indicating copy to clipboard operation
TMCStepper copied to clipboard

TMC2209 DIAG toggles (Stallguard)

Open TiSpace opened this issue 2 years ago • 3 comments

Hi there, I'm trying to run stallguard for homeing and tried several methodes, however #191 helped me most. Anyway I got a strange behaviour. Simply running 5000 pulses (@ 16 Microsteps), the DIAG signal toggles (without any load.) On the scope plot you can clearly see, after STEP clocks ends, DIAG goes HIGH and comes back to LOW once the next STEP clocks appear, stay LOW until next STEP clocks ans so on. for debugging purpose I print driver.SG_RESULT() and also can see, the value jumps between 200 and 40 (which makes sense compared to the DIAG - but not with the existing hardware conditions) DS1Z_QuickPrint1

Is someone able to expain the behaviour

/* Hardware:
 *  - Arduino Nano
 *  - Bigtreetech TMC2209
 */


 
#include <TMCStepper.h>

#define STALL_VALUE      60
#define TOFF_VALUE        5

#define STALL_PIN         3
#define DIR_PIN           5
#define STEP_PIN          6
#define EN_PIN            4
#define SW_RX             10
#define SW_TX             11
#define DRIVER_ADDRESS 0b00
#define R_SENSE 0.11f

TMC2209Stepper driver(SW_RX, SW_TX, R_SENSE, DRIVER_ADDRESS);
bool shaft = false;
bool myINT1 = false;

void setup()
{
  Serial.begin(115200);
  pinMode(EN_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  pinMode(STALL_PIN, INPUT_PULLUP);
  digitalWrite(EN_PIN, LOW);


  driver.begin();
  driver.toff(TOFF_VALUE);
  driver.blank_time(24);
  driver.rms_current(1000);
  driver.microsteps(16);
  driver.TCOOLTHRS(0xFFFFF);
  driver.SGTHRS(STALL_VALUE);

  // Interrupt Register
  EICRA = (1 << ISC11) | (1 << ISC10);  // rising edge triggers Interrupt
  EIMSK = (1 << INT1);                  // enable INT1
}

void loop()
{
  
  
  delay(4000);
  sei();
  runX(5000);
  Serial.print("Stall detect ");
  Serial.println(myINT1);
  Serial.print("Status: ");
  Serial.print(driver.SG_RESULT(), DEC);
  Serial.println(" ");
  myINT1 = false;
}

void runX(int turns) {
  for (uint16_t i = turns; i > 0; i--)
  {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(200);
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(200);
  }
}

TiSpace avatar Mar 18 '22 22:03 TiSpace

Hi. As far as I can see, you fully stop the stepper for 4 seconds and then run it for 2 seconds (equal to 5000 steps) and then check if any stall detections have happened while the stepper was running. So while the stepper is starting from stationary condition, you're checking for stall detection. As it has been mentioned in the answer to the issue that you based your program upon; When you start a stepper from stationary condition without using a controlled acceleration curve, you get a very large acceleration for short period of time which cases a momentarily stall detection and turns myINT1 true until you set it to false at the end of the loop. Like starting a stepper without controlled acceleration, stopping it without a controlled acceleration can also cause a stall detection. But based on the order of operations in your script, I suspect it's the starting that's causing the stall detection (but the stopping could also be problematic). And sometimes SGT makes errors, so in general checking it every two seconds is not a good idea and your should be using a higher time resolution. Also, if you're using stall detection for homing; you should not use a blocking movement function. you should use an interrupt based movement function so that you can stop the movement whenever you hit the HOME location. And it also has the benefit that your step timings won't be affected by the monitoring operations that you do which gives you a smoother stepper operation and a lower chance of false stall detection. Best of luck.

SobhanAbedi avatar Mar 19 '22 06:03 SobhanAbedi

Thanks SobhanAbedi for your thoughts. As I understand, the main issue is probably caused by start/stop procedure. I wonder what is the best practice for acceleration/deceleration of the stepper? I tried to avoid the AccelStepper-Library - maybe the wrong decision? Btw: As I still struggle with some basic functions of stallguard, I tried to keep the program as simple as possible - hence also not interrupt driven movement (as in my main program will be !)

TiSpace avatar Mar 20 '22 19:03 TiSpace

Hi. AccelStepper isn't perfect but for testing, it's not bad. I personally prefer the FastAccelStepper Library. AccelStepper is floating point based but FastAccelStepper is integer based. It's also fully interrupt driven which makes it good for your use case. Also It's not a very complicated library. Great source for learning interrupt based programming. I would suggest you also download the Manual for the chipset that your controller uses to understand the values better. Since TMC's Stall Guard isn't perfect, feeding on-time signals to the driver gives you less chance of unexpected stall detections. I suggest going with interrupt driven program from the beginning. If anything, it makes the rest of your program simpler. Good Luck.

SobhanAbedi avatar Mar 22 '22 22:03 SobhanAbedi