teemuatlut / TMC2130Stepper

Arduino library for Trinamic TMC2130 Stepper driver
MIT License
158 stars 50 forks source link

TMC2130 Stallguard not working with Arduino UNO #94

Closed Patrick-Yao-SRE closed 3 years ago

Patrick-Yao-SRE commented 4 years ago

Hello,

I have a problem making the StallGuard feature of the TMC2130 to work with my Arduino UNO. I was able to get the stepper motor working, but I wasn't able to read the updates through the SG_Results. I am only reading 1023

Here is the code I used

/*
  Trinamic TMC2130 Example
*/

#include <SPI.h>

// Note: You also have to connect GND, 5V and VM.
//       A connection diagram can be found in the schematics.
#define EN_PIN    18  // Nano v3:  16 Mega:  38  //enable (CFG6)
#define DIR_PIN   15  //           19        55  //direction
#define STEP_PIN  14  //           18        54  //step

#define CS_PIN    17  //           17        64  //chip select
#define MOSI_PIN 11 //51 //SDI/MOSI (ICSP: 4, Uno: 11, Mega: 51)
#define MISO_PIN 12 //50 //SDO/MISO (ICSP: 1, Uno: 12, Mega: 50)
#define SCK_PIN  13 //52 //CLK/SCK  (ICSP: 3, Uno: 13, Mega: 52)

//TMC2130 registers
#define _WRITE          0x80 //write flag
#define REG_GCONF      0x00
#define REG_GSTAT      0x01
#define REG_IHOLD_IRUN 0x10
#define REG_CHOPCONF   0x6C
#define REG_COOLCONF   0x6D
#define REG_DCCTRL     0x6E
#define REG_DRVSTATUS  0x6F
#define REG_TCOOLTHRS  0x14
#define REG_TPWMTHRS   0x13
#define REG_TSTEP      0x12

constexpr uint8_t SG_RESULT_bp    = 0;
constexpr uint8_t FSACTIVE_bp   = 15;
constexpr uint8_t CS_ACTUAL_bp    = 16;
constexpr uint8_t STALLGUARD_bp   = 24;
constexpr uint8_t OT_bp       = 25;
constexpr uint8_t OTPW_bp     = 26;
constexpr uint8_t S2GA_bp     = 27;
constexpr uint8_t S2GB_bp     = 28;
constexpr uint8_t OLA_bp      = 29;
constexpr uint8_t OLB_bp      = 30;
constexpr uint8_t STST_bp     = 31;
constexpr uint32_t DRV_STATUS_bm  = 0xFFFFFFFFUL;
constexpr uint32_t SG_RESULT_bm   = 0x3FFUL;
constexpr uint32_t FSACTIVE_bm    = 0x8000UL;
constexpr uint32_t CS_ACTUAL_bm   = 0x1F0000UL;
constexpr uint32_t STALLGUARD_bm  = 0x1000000UL;
constexpr uint32_t OT_bm      = 0x2000000UL;
constexpr uint32_t OTPW_bm      = 0x4000000UL;
constexpr uint32_t S2GA_bm      = 0x8000000UL;
constexpr uint32_t S2GB_bm      = 0x10000000UL;
constexpr uint32_t OLA_bm     = 0x20000000UL;
constexpr uint32_t OLB_bm     = 0x40000000UL;
constexpr uint32_t STST_bm      = 0x80000000UL;

#define NUMBER_OF_STEPS 14000
int stepCount = 0;

#include <TMC2130Stepper.h>

TMC2130Stepper TMC2130 = TMC2130Stepper(EN_PIN, DIR_PIN, STEP_PIN, CS_PIN);

uint8_t tmc_write(uint8_t cmd, uint32_t data)
{
  uint8_t s;

  digitalWrite(CS_PIN, LOW);

  s = SPI.transfer(cmd);
  SPI.transfer((data>>24UL)&0xFF)&0xFF;
  SPI.transfer((data>>16UL)&0xFF)&0xFF;
  SPI.transfer((data>> 8UL)&0xFF)&0xFF;
  SPI.transfer((data>> 0UL)&0xFF)&0xFF;

  digitalWrite(CS_PIN, HIGH);

  return s;
}

uint8_t tmc_read(uint8_t cmd, uint32_t *data)
{
  uint8_t s;

  tmc_write(cmd, 0UL); //set read address

  digitalWrite(CS_PIN, LOW);

  s = SPI.transfer(cmd);
  *data  = SPI.transfer(0x00)&0xFF;
  *data <<=8;
  *data |= SPI.transfer(0x00)&0xFF;
  *data <<=8;
  *data |= SPI.transfer(0x00)&0xFF;
  *data <<=8;
  *data |= SPI.transfer(0x00)&0xFF;

  digitalWrite(CS_PIN, HIGH);

  return s;
}

void setup()
{
  delay(1500);
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
  delay(500);

  cli();//stop interrupts
  //set timer1 interrupt at 1Hz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 256;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS12 and CS10 bits for 1024 prescaler
  TCCR1B |= (1 << CS11);// | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei();//allow interrupts

  //set pins
  pinMode(EN_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  digitalWrite(EN_PIN, HIGH); //deactivate driver (LOW active)
  digitalWrite(DIR_PIN, HIGH); //LOW or HIGH
  digitalWrite(STEP_PIN, LOW);

  pinMode(CS_PIN, OUTPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, INPUT);
  pinMode(SCK_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH);
  digitalWrite(MOSI_PIN, LOW);
  digitalWrite(MISO_PIN, HIGH);
  digitalWrite(SCK_PIN, LOW);

  //init serial port
  Serial.begin(250000); //init serial port and set baudrate
  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
  Serial.println("\nStart...");

  //init SPI
  SPI.setDataMode(SPI_MODE3);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV128);
  SPI.begin();

  //set TMC2130 config
  tmc_write(_WRITE|REG_IHOLD_IRUN, 0x10UL<<0 | 0x10UL<<8); //IHOLD=0x10, IRUN=0x10
  tmc_write(_WRITE|REG_CHOPCONF,   0x4UL<<24 | 0x1UL<<15 | 0x8UL<<0); //16 microsteps, MRES=0, TBL=1=24, TOFF=8
  TMC2130.coolstep_min_speed(148575);
  TMC2130.diag1_stall(1);
  TMC2130.diag1_active_high(1);
  TMC2130.sg_stall_value(-23);
  TMC2130.sg_filter(1);
  digitalWrite(EN_PIN, LOW);
}

ISR(TIMER1_COMPA_vect){
  digitalWrite(STEP_PIN, !analogRead(STEP_PIN));
  if (++stepCount >= NUMBER_OF_STEPS) {
    //digitalWrite(DIR_PIN, !analogRead(DIR_PIN)); // Change direction
    stepCount = 0;
  }
}
#define MAX_SPEED  40 // In timer value
#define MIN_SPEED  1000

void loop()
{
  static uint32_t last_time=0;
  uint32_t ms = millis();
  uint32_t data;
  uint8_t s;
  int8_t read_byte = Serial.read();
 if (read_byte == '0')      { TIMSK1 &= ~(1 << OCIE1A); digitalWrite( EN_PIN, HIGH ); }
    else if (read_byte == '1') { TIMSK1 |=  (1 << OCIE1A); digitalWrite( EN_PIN,  LOW ); }
    else if (read_byte == '+') if (OCR1A > MAX_SPEED) OCR1A -= 20;
    else if (read_byte == '-') if (OCR1A < MIN_SPEED) OCR1A += 20;
  if((ms-last_time) > 100) //run every 1s
  {
    last_time = ms;
    s = tmc_read(REG_DRVSTATUS, &data);
    Serial.println(data & 0x3FF, DEC);

  }

}

Any advice would be appreciated

teemuatlut commented 4 years ago

Possible reasons could be that the stallGuard threshold value isn't tuned or that you have a communication issue where the SPI reads all high. I suggest you try the example here https://github.com/teemuatlut/TMCStepper/blob/master/examples/StallGuard/StallGuard.ino

Patrick-Yao-SRE commented 4 years ago

I have actually tried using the code you just posted before. The values I am getting are constantly at "0 1023 976" and not changing. I hear that it may be an SPI communication error, but I double-check my connections on the TMC2130 and Arduino UNO. Have seen this problem before and what solution solved this?

teemuatlut commented 4 years ago

Try reading DRV_STATUS and see if the value is valid (not 0xFFFFFFFF or 0x0). First check that your comms are working okey and then start adjusting the stallguard threshold. Try not to make any unnecessary changes.

Patrick-Yao-SRE commented 4 years ago

DRV_STATUS is at 0xFFFFFFFF. I played around with the stallguard threshold and nothing change. I am using the 17HS24-2104S stepper motor. Does the motor type matter?

teemuatlut commented 4 years ago

You need to get your SPI working before anything. Check pins, check voltages, check your lines, etc.

Patrick-Yao-SRE commented 4 years ago

Yes, I believe that could be the issue. I am getting a new controller. I'll post the results when I received it.

Patrick-Yao-SRE commented 3 years ago

I have changed controller and tried running the code you have shared here. I am seeing the same results, as in the serial monitor is only showing 1023 for SG_Result

Patrick-Yao-SRE commented 3 years ago

Ok i have solve the problem. Ultimately it came down to the TMC2130 driver I used. I used the BigTreeTech version of the TMC2130 driver. In their manual, they said we need to short the SPI pin together for STEP/DIR mode. Don't do that. just buy the SPI version of the driver and it will work normally.