StallGuard is a sensorless load measurement technology for stepper motors. Implementing StallGuard in a stepper motor driver eliminates the need for reference or limit switches and reduces the complexity and cost where precise referencing is required such as 3D printers and CNC machines. Trinamic Motion Controller like TMC5272 supports StallGuard and CoolStep technology and using those features together we can make a cost effective and power efficient solution. TMC IDE offers tuning and testing StallGuard and CoolStep very effectively and we can take advantage from it during custom firmware design for MCU for controlling TMC5272 like stepper controllers.
StallGuard allows us to stop the motor to a specific load and we can set the sensitivity for the TMC5272. We can also set the upper and lower velocity threshold for enabling the StallGuard. Several registers of TMC5272 are involved with StallGuard and CoolStep and we need to programmatically control those registers from MCU. With the help of TMC IDE and the TMC5272 datasheet I was able to successfully implement StallGuard and CoolStep from Arduino.
Images are captured from TMC5272 datasheet. The sg_stop bit of SW_MODE register is responsible for enabling or disabling of StallGuard2 or 4.
This is the sample test code I wrote for Arduino for controlling StallGuard2.
/******************************************************************************* * Copyright © 2023 Analog Devices Inc. All Rights Reserved. * This software is proprietary to Analog Devices, Inc. and its licensors. *******************************************************************************/ #include <SPI.h> extern "C" { #include "TMC5272_register_map.h" #include "tmc5272.h" } /* * Arduino Pins Eval Board Pins * 51 MOSI 32 SPI1_SDI * 50 MISO 33 SPI1_SDO * 52 SCK 31 SPI1_SCK * 53 SS 30 SPI1_CSN * GND 23 CLK16 -> use internal * 23 DIO 19 nSleep * GND 2 GND * +5V 5 +5V_USB * 27 iRefR2 35 IREF_R2 * 29 iRefR3 36 IRREF_R3 * 31 uartMode 20 USEL/ for uart mode it should be HIGH */ #define IC_ID 0 int nSleep = 23; int iRefR2 = 27; int iRefR3 = 29; int uartMode = 31; void tmc5272_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength) { digitalWrite(PIN_SPI_SS, LOW); delayMicroseconds(10); for (uint32_t i = 0; i < dataLength; i++) { data[i] = SPI.transfer(data[i]); Serial.println(data[i]); } delayMicroseconds(10); digitalWrite(PIN_SPI_SS, HIGH); } void setup() { Serial.begin(115200); // put your setup code here, to run once: pinMode(PIN_SPI_SS, OUTPUT); pinMode(nSleep, OUTPUT); pinMode(iRefR2, OUTPUT); pinMode(iRefR3, OUTPUT); pinMode(uartMode, OUTPUT); digitalWrite(PIN_SPI_SS, HIGH); digitalWrite(nSleep, LOW); // Disabling standby digitalWrite(iRefR2, LOW); digitalWrite(iRefR3, LOW); digitalWrite(uartMode, LOW); SPI.begin(); SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE3)); delay(10); //set resistance to 10K digitalWrite(iRefR2, HIGH); digitalWrite(iRefR3, HIGH); initMotorOne(IC_ID); //tmc5272_rotateMotor(IC_ID, 0, 0x00005000); tmc5272_writeRegister(IC_ID, TMC5272_TPWMTHRS(0), 0x1500000); //this is the upper velocity for StealthChop2 voltage PWM mode, ST2 is enable if TSTEP>=TPWMTHRS tmc5272_writeRegister(IC_ID, TMC5272_TCOOLTHRS(0), 0x50000);//lower velocity threshold for switching CoolStep and StallGuard2/4 features, enable if TCOOLTHRS >= TSTEP tmc5272_writeRegister(IC_ID, TMC5272_THIGH(0), 0x0);//upper velocity threshold for switching CoolStep, disabled if TSTEP <= THIGH tmc5272_writeRegister(IC_ID, TMC5272_SG4_THRS(0), 30); //stall detection threshold //tmc5272_writeRegister(IC_ID, TMC5272_SW_MODE(0), 0x0); field_write(IC_ID, TMC5272_SW_MODE_SG_STOP_FIELD(0), 1); //enable stop by StallGuard2/4 tmc5272_writeRegister(IC_ID, TMC5272_RAMPMODE, 0x0); //set position mode tmc5272_writeRegister(IC_ID, TMC5272_VSTART(0), 0); //set maximum valocity tmc5272_writeRegister(IC_ID, TMC5272_VSTOP(0), 10); //set maximum valocity tmc5272_writeRegister(IC_ID, TMC5272_TVMAX(0), 0); //disable jerk reduction tmc5272_writeRegister(IC_ID, TMC5272_AMAX(0), 50000); //set maximum acceleration tmc5272_writeRegister(IC_ID, TMC5272_VMAX(0), 100000); //set maximum valocity tmc5272_writeRegister(IC_ID, TMC5272_DMAX(0), 1000); //set maximum deacceleration tmc5272_writeRegister(IC_ID, TMC5272_D2(0), 1); tmc5272_writeRegister(IC_ID, TMC5272_XACTUAL(0), 0); //clear actual position tmc5272_writeRegister(IC_ID, TMC5272_XTARGET(0), 500000); //set a target position delay(10000); field_write(IC_ID, TMC5272_RAMP_STAT_STATUS_SG_FIELD(0), 0); //disable stop by StallGuard2/4 field_write(IC_ID, TMC5272_SW_MODE_SG_STOP_FIELD(0), 0); //disable stop by StallGuard2/4 tmc5272_writeRegister(IC_ID, TMC5272_XTARGET(0), 0); //return to home position } void loop() { int32_t value1 = tmc5272_readRegister(IC_ID, TMC5272_RAMP_STAT(0)); int32_t value2 = tmc5272_readRegister(IC_ID, TMC5272_SG4_THRS(0)); Serial.print("Received Data: "); Serial.print(value1, HEX); Serial.print(" "); Serial.println(value1); }
I added some helpful comments in the code which can help you to easily understand the code and operation. In the code the driver is configure to drive the stepper motor in position mode. A target position is set to XTRAGT register. Motor moves clockwise to achieve the position and the StallGuard is enable in this journey. After reaching the target a 10s pause is set. The motor returns to home position again and this time the StallGuard is disable.
Watch the demo video below for the above code: