TMCStepper icon indicating copy to clipboard operation
TMCStepper copied to clipboard

No pulses when index__step = 1

Open jarataraj opened this issue 4 years ago • 1 comments
trafficstars

From page 20 of the TMC2209 datasheet the INDEX output should pulse for every step when index_step = 1. I cannot get this to work. When index_step = 0 and index_otpw = 0 I get a pulse for every 1024 microsteps as expected; however, when I change index_step to 1 there are no pulses. I checked with an oscilloscope to confirm that there are no pulses. I am using an ESP32 and the arduino framework within platformio IDE in vscode. At one point index_step = 1 seemed to halfway work for a moment but I haven't been able to reproduce it since. Below is some code to reproduce the issue:

#include <Arduino.h>
#include <TMCStepper.h>

// ------movement and position bindings------
volatile uint32_t count = 0;
uint16_t start = 0;
int8_t stepPinValue = 0;
uint16_t end = 0;

//------TMC2209------
#define RXD2 16             // HWUART recieve
#define TXD2 17             // HWUART transmit
#define EN_PIN 32           // Enable
#define DIR_PIN 25          // Direction
#define STEP_PIN 33         // Step
#define SERIAL_PORT Serial2 // HardwareSerial port
#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2
#define R_SENSE 0.11f       // SilentStepStick sense resistor
#define INDEX_PIN 26        // Index

TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);

//------index interrupt inits------
void IRAM_ATTR onIndex();
portMUX_TYPE synch = portMUX_INITIALIZER_UNLOCKED;

void setup()
{
  //====== Stepper Driver Setup ======
  pinMode(EN_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  digitalWrite(EN_PIN, HIGH); // Disable driver in hardware
  digitalWrite(STEP_PIN, stepPinValue);
  pinMode(INDEX_PIN, INPUT);

  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); // begin hardware Serial2
  driver.begin();                                //  SPI: Init CS pins and possible SW SPI pins
                                                 // UART: Init SW UART (if selected) with default 115200 baudrate
  driver.en_spreadCycle(false);                  // spreadCycle off
  driver.pwm_autoscale(true);                    // enable stealthChop
  driver.toff(5);                                // enable driver via software
  driver.rms_current(200, .7);                   // Set motor RMS current, the 1 sets holding current to equal run current (IHOLD/IRUN = 1)
  driver.microsteps(256);                        // Set microsteps to 1/256
  driver.I_scale_analog(false);                  // do no use external trimpot for current scaling
  driver.TPOWERDOWN(255);                        // ~5 sec before lowering to IHOLD current
  driver.iholddelay(15);                         // slow decay of IRUN to IHOLD
  digitalWrite(EN_PIN, LOW);                     // Enable driver in hardware

  attachInterrupt(INDEX_PIN, onIndex, RISING);

  Serial.begin(115200);
}

void loop()
{
  // ======INDEX for each microstep test======
  Serial.println("INDEX for each microstep test");
  driver.index_step(1);
  Serial.printf("index_step = %i\n", driver.index_step());
  count = 0;
  for (uint16_t i = 0; i < 10000; i++)
  {
    stepPinValue = 1 - stepPinValue;
    digitalWrite(STEP_PIN, stepPinValue);
    delayMicroseconds(30);
  }
  Serial.printf("step count = %i\n\n", count);
  delay(1000);

  //======MSCNT Test======
  Serial.println("MSCNT Test");
  Serial.printf("shaft = %i\n", driver.shaft());
  start = driver.MSCNT();
  Serial.printf("start = %i\n", start);
  for (uint16_t i = 0; i < 10; i++)
  {
    stepPinValue = 1 - stepPinValue;
    digitalWrite(STEP_PIN, stepPinValue);
    delayMicroseconds(100);
  }
  Serial.printf("end = %i\n", driver.MSCNT());
  driver.shaft(true); // reverse direction
  Serial.printf("shaft = %i\n", driver.shaft());
  for (uint16_t i = 0; i < 10; i++)
  {
    stepPinValue = 1 - stepPinValue;
    digitalWrite(STEP_PIN, stepPinValue);
    delayMicroseconds(100);
  }
  start = driver.MSCNT();
  Serial.printf("new start = %i\n\n", start);
  driver.shaft(false);
  delay(1000);

  //======INDEX for every 1024 microsteps test======
  Serial.println("INDEX for every 1024 microsteps test");
  count = 0;
  driver.index_step(0);
  Serial.printf("index_step = %i\n", driver.index_step());
  start = driver.MSCNT();
  Serial.printf("start = %i\n", start);
  for (uint16_t i = 0; i < 10000; i++)
  {
    stepPinValue = 1 - stepPinValue;
    digitalWrite(STEP_PIN, stepPinValue);
    delayMicroseconds(30);
  }
  end = driver.MSCNT();
  Serial.printf("end = %i\n", end);
  Serial.printf("cycle count = %i\n", count);
  uint32_t distance = (1024 * count) + end - start;
  Serial.printf("Calculated distance = %i\n\n", distance);
  delay(1000);
}

void IRAM_ATTR onIndex()
{
  portENTER_CRITICAL(&synch);
  count++;
  portEXIT_CRITICAL(&synch);
}

jarataraj avatar Nov 11 '21 16:11 jarataraj

image

I believe the intention of this setting is to be able to control a secondary driver as a slave when you are using the TMC2209 Internal Step Pulse Generator (see chapter 14) with .VACTUAL.

teemuatlut avatar Dec 02 '21 19:12 teemuatlut