Greetings
I use an Arduino Mega, a stepper motor with an ABN differential encoder as well as the driver TMC5130-BOB.
I started using the library TMCStepper.h as it should be easy to use, but i'm also able to get the data direct from the driver by accessing the registers.
Currently, my setup works (it turns when it should turn), but I'm unable to get the value from the encoder, which is important for my application.
Additional info: the TMC5130-BOB only has the connections ENCA, ENB and ENCN, therefore I ignore the differential inverted signal wires from the encoder.
Can you help me to get the encoder signal? I'm totally stuck and don't know where the issue could be.
Thank you kindly.
Here would be a part of my code so far:
// Libraries
#include <SPI.h>
#include <TMCStepper.h>
// varia parameter
const word rtMainRate = 2500; // in ms
const word rtCheckRate = 1250; // in ms
unsigned long rtMainLast = 0; // 0-4'294'967'295 -> ca. 49 days, last runtime
unsigned long rtCheckLast = 0; // 0-4'294'967'295 -> ca. 49 days, last runtime
// ====================================
// stepper motor stuff
// ====================================
#define motEN_pin 49 // Enable
#define motCS_pin 53 // Chip select
#define motMOSI_pin 51 // Software Master Out Slave In (MOSI)
#define motMISO_pin 50 // Software Master In Slave Out (MISO)
#define motSCK_pin 52 // Software Slave Clock (SCK)
#define motRSENSE 0.15f // acc. to the datasheet...?
//TMC5130Stepper motDriver = TMC5130Stepper(motCS_pin, motRSENSE, motMOSI_pin, motMISO_pin, motSCK_pin);
TMC5130Stepper motDriver = TMC5130Stepper(motCS_pin, motRSENSE);
int motContrCount = 5; // counter for the circular buffer. It makes the control of the motor slow, it will only compare to the threshold if the whole circular buffer is renewed
bool motBackwardFlag = false;
int motTarget = 0;
bool motMoving = false;
/************************
Motor: send the commands via SPI to the driver
************************/
void motSendData(unsigned long address, unsigned long datagram) {
delay(50);
uint8_t stat;
unsigned long i_datagram;
digitalWrite(motCS_pin,LOW);
delay(15);
delayMicroseconds(10);
stat = SPI.transfer(address);
i_datagram |= SPI.transfer((datagram >> 24) & 0xff);
i_datagram <<= 8;
i_datagram |= SPI.transfer((datagram >> 16) & 0xff);
i_datagram <<= 8;
i_datagram |= SPI.transfer((datagram >> 8) & 0xff);
i_datagram <<= 8;
i_datagram |= SPI.transfer((datagram) & 0xff);
digitalWrite(motCS_pin,HIGH);
delay(15);
Serial.print("Received: ");
PrintHex40(stat, i_datagram);
Serial.print("\n");
Serial.print(" from register: ");
Serial.println(address,HEX);
Serial.println();
}
int32_t motReadData(unsigned long address) {
delay(50);
uint8_t stat;
int32_t i_datagram = 0; // Store the response data here
digitalWrite(motCS_pin,LOW);
delay(15);
// Send address for read operation (0x21 becomes 0x21 for reading XACTUAL, no write flag)
stat = SPI.transfer(address & 0x7F); // Ensure the MSB is 0 for reading
// Send dummy data (0x00) to initiate the read and capture the response
i_datagram |= SPI.transfer(0x00) << 24;
i_datagram |= SPI.transfer(0x00) << 16;
i_datagram |= SPI.transfer(0x00) << 8;
i_datagram |= SPI.transfer(0x00);
digitalWrite(motCS_pin,HIGH);
delay(15);
/*
Serial.print("Received: ");
PrintHex40(stat, i_datagram); // Helper function to print the status and data
Serial.print("\n");
Serial.print(" from register: ");
Serial.println(address, HEX);
*/
return i_datagram; // Return the data received
}
/************************
print the Hex40 code
************************/
void PrintHex40(uint8_t stat, uint32_t data) // prints 40-bit data in hex with leading zeroes
{
char tmp[16];
uint16_t LSB = data & 0xffff;
uint16_t MSB = data >> 16;
sprintf(tmp, "0x%.2X%.4X%.4X", stat, MSB, LSB);
Serial.print(tmp);
}
void setup() {
Serial.begin(115200); //open the serial port for communication with the PC
while (!Serial) {}
SPI.begin();
pinMode(motEN_pin, OUTPUT); // motor enable
pinMode(motCS_pin, OUTPUT); // motor chipselect
digitalWrite(motCS_pin, HIGH); // Motor CS disabled at start
/*
//digitalWrite(motEN_pin, motEnableFlag); // disable motor
SPI.begin();
SPI.setDataMode(SPI_MODE3); // TMC5130 uses SPI mode 3
SPI.setBitOrder(MSBFIRST); // Most significant bit first
SPI.setClockDivider(SPI_CLOCK_DIV16); // Adjust clock speed as needed
*/
// Initialize the motDriver
motDriver.begin();
delay(500);
motDriver.toff(5); // Off-time setting (adjust if needed)
motDriver.rms_current(800); // Set motor RMS current
motDriver.microsteps(0); // Set microsteps to 1/16
motDriver.en_pwm_mode(false); // disable stealthChop
motDriver.pwm_autoscale(true); // Enable auto PWM scaling
// Set CoolStep parameters
motDriver.TCOOLTHRS(0); // Set the CoolStep lower threshold, this is the lowest velocity when CoolStep starts to regulate
motDriver.THIGH(0); // Set the upper threshold velocity for switching off CoolStep
// Optional: Fine-tune SpreadCycle parameters
motDriver.hend(2); // Hysteresis end value
motDriver.hstrt(3); // Hysteresis start
// Set other motion parameters
motDriver.a1(100); // Initial acceleration
motDriver.v1(500); // Acceleration threshold velocity V1
motDriver.AMAX(50); // Acceleration above V1
motDriver.VMAX(1500); // Maximum speed
motDriver.DMAX(70); // Deceleration above V1
motDriver.d1(140); // Deceleration below V1
motDriver.VSTOP(10); // Stop velocity
motDriver.RAMPMODE(0); // Positioning mode
/* Some default values, not sure if neccessary...
sendData(0xA4,0x000003E8); //A1=1000
sendData(0xA5,0x000186A0); //V1=100000
sendData(0xA6,0x0000C350); //AMAX=50000
sendData(0xA7,0x000186A0); //VMAX=100000
sendData(0xAA,0x00000578); //D1=1400
sendData(0xAB,0x00000064); //VSTOP=100
*/
motSendData(0xB8, 0x00000000); // Set ENCODER_MODE to quadrature mode
//motReadData(0x38); // Set ENCODER_MODE to quadrature mode
Serial.println("Motor initialized.");
digitalWrite(motEN_pin, HIGH); // enable motor
}
void loop() {
unsigned long rt = millis();
if(motMoving == false && rt-rtMainLast >= rtMainRate){
rtMainLast = rt;
if(motBackwardFlag == false) motTarget += 50;
else motTarget -= 50;
if(motContrCount >= 10){
motContrCount = 0;
motBackwardFlag = !motBackwardFlag;
}
//Serial.print("Motor moves to target: ");
//Serial.println(motTarget);
//Serial.println();
motContrCount++;
digitalWrite(motEN_pin, LOW); // enable motor
delay(30);
motDriver.XTARGET(motTarget);
motMoving = true;
}
if(rt - rtCheckLast > rtCheckRate){
rtCheckLast = rt;
int32_t motEncVal_Lib = motDriver.X_ENC();
Serial.print("Encoder Value via Library motDriver.X_ENC(): ");
Serial.println(motEncVal_Lib);
int32_t motEncVal_Reg2 = motReadData(0x39);
Serial.print("Encoder Value via motReadData(0x39): ");
Serial.println(motEncVal_Reg2);
Serial.print("step Value via Library motDriver.XACTUAL: ");
Serial.println(motDriver.XACTUAL());
int32_t motPosVal_Reg = motReadData(0x21);
Serial.print("step Value via motReadData(0x21): ");
Serial.println(motPosVal_Reg);
//int32_t motStatus = motReadData(0x00);
//Serial.print("GCONF status: ");
//Serial.println(motStatus);
//uint32_t drv_status = motDriver.DRV_STATUS();
//Serial.print("DRV_STATUS: ");
//Serial.println(drv_status, HEX);
//uint32_t mtLostSteps = motDriver.LOST_STEPS();
//Serial.print("Lost steps: ");
//Serial.println(mtLostSteps);
Serial.println();
}
if(motMoving == true && motDriver.XACTUAL() == motTarget){
delay(30);
digitalWrite(motEN_pin, HIGH); // disable the motor
// Serial.println("Motor target reached --> mot disabled.");
motMoving = false;
}
}
The output on the Serial is as follows:
Encoder Value via Library motDriver.X_ENC(): 0
Encoder Value via motReadData(39): 0
step Value via Library motDriver.XACTUAL: 150
step Value via motReadData(0x21): 150
edit 1: changed motReadData(39); to motReadData(0x39);, but result still the same.