Skip to content

TMC429 Reverse Movement Overshoot Issue (~50-70% overshoot) #12

@ernestasga

Description

@ernestasga

Hardware Setup

  • MCU: Arduino Portenta H7 M7 core
  • Motor Controller: TMC429-BOB (Breakout Board)
  • Motor: DSY RS200 servo motor
  • Configuration: 10,000 pulses per revolution
  • Communication: SPI interface

Issue Description

The TMC429 exhibits consistent reverse movement overshoot when performing bidirectional positioning moves. Forward movements are accurate (~10,000 steps), but reverse movements overshoot by approximately 50-70%, resulting in ~15,000-17,000 steps instead of the expected 10,000 steps. The board reports that steps are correct (cycle 0-10000-0) but the actual motor shaft position goes over the starting point.

Expected Behavior

  • Forward move: 0 → 10,000 steps (should move exactly 10,000 steps)
  • Reverse move: 10,000 → 0 steps (should move exactly -10,000 steps back to origin)
  • Net position change: 0 steps (should return to starting position)

Actual Behavior

  • Forward move: ~10,000 steps ✅ (correct)
  • Reverse move: ~15,000-17,000 steps ❌ (50-70% overshoot)
  • Net position change: -5,000 to -7,000 steps ❌ (significant drift)

Reproduction Code

#include <Arduino.h>
#include "TMC429.h"

// Hardware pins for Portenta H7
#define LAST_ARDUINO_PIN_NUMBER LEDB + 1
int MOTOR_X_EN = LAST_ARDUINO_PIN_NUMBER + PC_13;
int MOTOR_Y_EN = LAST_ARDUINO_PIN_NUMBER + PC_15;
int SPI1_CS = LAST_ARDUINO_PIN_NUMBER + PI_0;

const int CONTROL_MOTOR = 1;
const long TEST_DISTANCE = 10000;  // Full rotation
const long VELOCITY_MAX = 5000;   // 0.5 rev/sec
const long VELOCITY_MIN = 500;
const long ACCELERATION_MAX = 10000; // 1 rev/sec^2

TMC429 tmc429;

void setup() {
  Serial.begin(115200);

  // Initialize TMC429
  tmc429.setup(SPI1_CS, 32); // 32 MHz clock

  // Configure motor pins (active low)
  pinMode(MOTOR_X_EN, OUTPUT);
  pinMode(MOTOR_Y_EN, OUTPUT);
  digitalWrite(MOTOR_X_EN, LOW);
  digitalWrite(MOTOR_Y_EN, LOW);

  // Configure TMC429
  tmc429.disableLeftSwitchStop(CONTROL_MOTOR);
  tmc429.disableRightSwitchStop(CONTROL_MOTOR);
  tmc429.disableRightSwitches();
  tmc429.setSoftMode(CONTROL_MOTOR);
  tmc429.setLimitsInHz(CONTROL_MOTOR, VELOCITY_MIN, VELOCITY_MAX, ACCELERATION_MAX);

  // Set initial position
  tmc429.setActualPosition(CONTROL_MOTOR, 0);
  tmc429.setTargetPosition(CONTROL_MOTOR, 0);
}

void loop() {
  // Reset position
  tmc429.setActualPosition(CONTROL_MOTOR, 0);
  long startPos = tmc429.getActualPosition(CONTROL_MOTOR);

  // Forward movement
  Serial.println("Moving forward 10000 steps...");
  tmc429.setTargetPosition(CONTROL_MOTOR, TEST_DISTANCE);
  while (!tmc429.atTargetPosition(CONTROL_MOTOR)) { delay(100); }

  long forwardPos = tmc429.getActualPosition(CONTROL_MOTOR);
  long forwardMovement = forwardPos - startPos;

  // Reverse movement
  Serial.println("Moving reverse 10000 steps...");
  tmc429.setTargetPosition(CONTROL_MOTOR, 0);
  while (!tmc429.atTargetPosition(CONTROL_MOTOR)) { delay(100); }

  long reversePos = tmc429.getActualPosition(CONTROL_MOTOR);
  long reverseMovement = forwardPos - reversePos;

  // Results
  Serial.print("Forward: "); Serial.print(forwardMovement); Serial.println(" steps");
  Serial.print("Reverse: "); Serial.print(reverseMovement); Serial.println(" steps");
  Serial.print("Ratio: "); Serial.println((float)reverseMovement / forwardMovement);
  Serial.print("Net error: "); Serial.println(reversePos - startPos);
  Serial.println("---");

  delay(5000);
}

Troubleshooting Attempted

  1. Speed Reduction: Tried various velocity/acceleration settings - issue persists
  2. Different Step Sizes: Tested with 1K, 2K, 5K steps - overshoot scales proportionally
  3. Mode Changes: Confirmed soft positioning mode is active
  4. Communication: Verified TMC429 communication is working correctly
  5. Target Confirmation: Confirmed TMC429 receives correct target positions

Technical Details

  • Library: TMC429 Arduino Library
  • Firmware: Arduino framework on Portenta H7
  • SPI Settings: 32 MHz clock, default settings
  • Motor Settings: 10K PPR, conservative velocity limits

Questions

  1. Is this a known issue with the TMC429 library or chip?
  2. Could this be related to pulse divisor or ramp divisor settings in reverse direction?
  3. Are there specific configuration registers that handle directional movement differently?
  4. Is there a recommended approach for accurate bidirectional positioning with TMC429?

Additional Context

This issue is blocking development of a precision positioning system where accurate bidirectional movement is critical. The overshoot is highly consistent (always ~1.5-1.7x in reverse), suggesting a systematic configuration issue rather than mechanical problems.

Any insights or recommendations would be greatly appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions