janelia-arduino/TMC2209

Program for getting the settings and status from two drivers?

adamaero opened this issue · 9 comments

Original:
https://github.com/janelia-arduino/TMC2209/blob/main/examples/BidirectionalCommunication/SettingsAndStatus/SettingsAndStatus.ino

My attempt:

#include <TMC2209.h>

HardwareSerial &serial_stream_1 = Serial3; // Connect to the first TMC2209
HardwareSerial &serial_stream_2 = Serial2; // Connect to the second TMC2209

const int DELAY = 2000;

// Instantiate TMC2209 for the first motor driver
TMC2209 stepper_driver_1;

// Instantiate TMC2209 for the second motor driver
TMC2209 stepper_driver_2;

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

  // Initialize the first TMC2209 motor driver
  stepper_driver_1.setup(serial_stream_1);

  // Initialize the second TMC2209 motor driver
  stepper_driver_2.setup(serial_stream_2);

  // Perform initial setup for both motor drivers
  setupMotorDriver(stepper_driver_1);
  setupMotorDriver(stepper_driver_2);
}

void loop()
{
  // Control the first motor driver (stepper_driver_1)
  Serial.println("First Motor Driver:");
  moveMotor(stepper_driver_1, 1000); // Move the first motor
  // Add more control code for the first motor driver here

  // Control the second motor driver (stepper_driver_2)
  Serial.println("Second Motor Driver:");
  moveMotor(stepper_driver_2, -1000); // Move the second motor
  // Add more control code for the second motor driver here

  // Query and print the status and settings for both motor drivers
  queryStatusAndSettings(stepper_driver_1, "First Motor Driver");
  queryStatusAndSettings(stepper_driver_2, "Second Motor Driver");

  delay(DELAY);
}

void setupMotorDriver(TMC2209 &driver)
{
  // Configure motor driver settings for each driver here
  TMC2209::Settings settings;

  // Example configuration (you can customize these settings)
  settings.stealth_chop_enabled = true;
  settings.microsteps_per_step = 64;
  settings.ihold_register_value = 0x0F; // Adjust current settings as needed
  settings.automatic_current_scaling_enabled = true;
  settings.automatic_gradient_adaptation_enabled = true;
  settings.pwm_offset = 4;
  settings.pwm_gradient = 3;
  settings.cool_step_enabled = true;
  settings.analog_current_scaling_enabled = false;
  settings.internal_sense_resistors_enabled = false;

  // Set the motor driver settings
  driver.setStealthChopEnabled(settings.stealth_chop_enabled);
  driver.setMicrostepsPerStep(settings.microsteps_per_step);
  driver.setIHoldRegisterValue(settings.ihold_register_value);
  driver.setAutomaticCurrentScalingEnabled(settings.automatic_current_scaling_enabled);
  driver.setAutomaticGradientAdaptationEnabled(settings.automatic_gradient_adaptation_enabled);
  driver.setPWMOffset(settings.pwm_offset);
  driver.setPWMGradient(settings.pwm_gradient);
  driver.setCoolStepEnabled(settings.cool_step_enabled);
  driver.setAnalogCurrentScalingEnabled(settings.analog_current_scaling_enabled);
  driver.setInternalSenseResistorsEnabled(settings.internal_sense_resistors_enabled);

  // Print the updated settings
  printSettings(settings);
}

void moveMotor(TMC2209 &driver, long steps)
{
  // Move the motor with the specified number of steps
  driver.setTargetPosition(driver.getPosition() + steps);
  while (!driver.isStandstill())
  {
    // Wait for the motor to reach the target position
  }
}

void queryStatusAndSettings(TMC2209 &driver, const char *driverName)
{
  Serial.println("*************************");
  Serial.println(driverName);

  // Query and print the motor driver settings
  TMC2209::Settings settings;
  driver.copyTo(settings);
  printSettings(settings);

  Serial.println("*************************");
  Serial.println("hardwareDisabled()");
  bool hardware_disabled = driver.hardwareDisabled();
  Serial.print("hardware_disabled = ");
  Serial.println(hardware_disabled);
  Serial.println("*************************");
  Serial.println();

  Serial.println("*************************");
  Serial.println("getStatus()");
  TMC2209::Status status = driver.getStatus();
  printStatus(status);
  Serial.println("*************************");
  Serial.println();
}

void printSettings(const TMC2209::Settings &settings)
{
  Serial.println("*************************");
  Serial.println("Current Motor Driver Settings:");
  Serial.print("settings.stealth_chop_enabled = ");
  Serial.println(settings.stealth_chop_enabled);
  Serial.print("settings.microsteps_per_step = ");
  Serial.println(settings.microsteps_per_step);
  Serial.print("settings.ihold_register_value = ");
  Serial.println(settings.ihold_register_value);
  Serial.print("settings.automatic_current_scaling_enabled = ");
  Serial.println(settings.automatic_current_scaling_enabled);
  Serial.print("settings.automatic_gradient_adaptation_enabled = ");
  Serial.println(settings.automatic_gradient_adaptation_enabled);
  Serial.print("settings.pwm_offset = ");
  Serial.println(settings.pwm_offset);
  Serial.print("settings.pwm_gradient = ");
  Serial.println(settings.pwm_gradient);
  Serial.print("settings.cool_step_enabled = ");
  Serial.println(settings.cool_step_enabled);
  Serial.print("settings.analog_current_scaling_enabled = ");
  Serial.println(settings.analog_current_scaling_enabled);
  Serial.print("settings.internal_sense_resistors_enabled = ");
  Serial.println(settings.internal_sense_resistors_enabled);
  Serial.println("*************************");
}

void printStatus(const TMC2209::Status &status)
{
  Serial.println("Current Motor Driver Status:");
  Serial.print("status.over_temperature_warning = ");
  Serial.println(status.over_temperature_warning);
  Serial.print("status.over_temperature_shutdown = ");
  Serial.println(status.over_temperature_shutdown);
  Serial.print("status.short_to_ground_a = ");
  Serial.println(status.short_to_ground_a);
  Serial.print("status.short_to_ground_b = ");
  Serial.println(status.short_to_ground_b);
  Serial.print("status.low_side_short_a = ");
  Serial.println(status.low_side_short_a);
  Serial.print("status.low_side_short_b = ");
  Serial.println(status.low_side_short_b);
  Serial.print("status.open_load_a = ");
  Serial.println(status.open_load_a);
  Serial.print("status.open_load_b = ");
  Serial.println(status.open_load_b);
  Serial.print("status.over_temperature_120c = ");
  Serial.println(status.over_temperature_120c);
  Serial.print("status.over_temperature_143c = ");
  Serial.println(status.over_temperature_143c);
  Serial.print("status.over_temperature_150c = ");
  Serial.println(status.over_temperature_150c);
  Serial.print("status.over_temperature_157c = ");
  Serial.println(status.over_temperature_157c);
  Serial.print("status.current_scaling = ");
  Serial.println(status.current_scaling);
  Serial.print("status.stealth_chop_mode = ");
  Serial.println(status.stealth_chop_mode);
  Serial.print("status.standstill = ");
  Serial.println(status.standstill);
  Serial.println("*************************");
}

Hi,

Is your code working or are you running into problems?

At a quick glance it looks like your approach should work fine.

There was some issue with the settings. I attempted to change the settings. So instead, I just left the default settings:

/*
https://github.com/janelia-arduino/TMC2209/blob/main/examples/BidirectionalCommunication/SettingsAndStatus/SettingsAndStatus.ino

Pintout:
 Mega   TMC2099
 17RX2 ↔ TX (X stepper driver)
 15RX3 ↔ TX (Y stepper driver)


*/

#include <TMC2209.h>

const int dirPinX = 13;
const int stepPinX = 12;

const int dirPinY = 8;
const int stepPinY = 7;


int resetXcount = 0, resetYcount = 0, stepXcount = 0, stepYcount = 0;

//float deltaTheta = PI/8000;             // Original
float deltaTheta = PI / 8000;             // Adjust this when gear ratio changes
float A = 80;       // Amplitude - scaling (stretching/shifting)
float deltaX = 0, deltaY = 0, theta = 0;
float x_1 = 0, x_2 = 0, y_1 = 0, y_2 = 0;

HardwareSerial &serial_stream_1 = Serial3; // Connect to the first TMC2209
HardwareSerial &serial_stream_2 = Serial2; // Connect to the second TMC2209

const int DELAY = 2000;

// Instantiate TMC2209 for the first motor driver
TMC2209 stepper_driver_1;

// Instantiate TMC2209 for the second motor driver
TMC2209 stepper_driver_2;

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

  // Initialize the first TMC2209 motor driver
  stepper_driver_1.setup(serial_stream_1);

  // Initialize the second TMC2209 motor driver
  stepper_driver_2.setup(serial_stream_2);

  pinMode(stepPinX, OUTPUT);
  pinMode(dirPinX, OUTPUT);
  pinMode(stepPinY, OUTPUT);
  pinMode(dirPinY, OUTPUT);

  deltaX  = 0;   //(dirPinX, LOW);  // right
  deltaY  = 0;   //(dirPinY, LOW);  // away
  for (int i = 0; i < 22000; i++)
  {
    stepX();
    stepY();

    digitalWrite(stepPinX, LOW);
    digitalWrite(stepPinY, LOW);
    delayMicroseconds(200);
  }  
}

void loop()
{

  /*
   *  Move motors function calls
   */



  // Query and print the status and settings for both motor drivers
  queryStatusAndSettings(stepper_driver_1, "First Motor Driver");
  queryStatusAndSettings(stepper_driver_2, "Second Motor Driver");

  delay(DELAY);
}




void queryStatusAndSettings(TMC2209 &driver, const char *driverName)
{
  Serial.println("*************************");
  Serial.println(driverName);

  // Query and print the motor driver settings
  TMC2209::Settings settings;
//  driver.copyTo(settings);
//  printSettings(settings);

  Serial.println("*************************");
  Serial.println("hardwareDisabled()");
  bool hardware_disabled = driver.hardwareDisabled();
  Serial.print("hardware_disabled = ");
  Serial.println(hardware_disabled);
  Serial.println("*************************");
  Serial.println();

  Serial.println("*************************");
  Serial.println("getStatus()");
  TMC2209::Status status = driver.getStatus();
  printStatus(status);
  Serial.println("*************************");
  Serial.println();
}

void printSettings(const TMC2209::Settings &settings)
{
  Serial.println("*************************");
  Serial.println("Current Motor Driver Settings:");
  Serial.print("settings.stealth_chop_enabled = ");
  Serial.println(settings.stealth_chop_enabled);
  Serial.print("settings.microsteps_per_step = ");
  Serial.println(settings.microsteps_per_step);
  Serial.print("settings.ihold_register_value = ");
  Serial.println(settings.ihold_register_value);
  Serial.print("settings.automatic_current_scaling_enabled = ");
  Serial.println(settings.automatic_current_scaling_enabled);
  Serial.print("settings.automatic_gradient_adaptation_enabled = ");
  Serial.println(settings.automatic_gradient_adaptation_enabled);
  Serial.print("settings.pwm_offset = ");
  Serial.println(settings.pwm_offset);
  Serial.print("settings.pwm_gradient = ");
  Serial.println(settings.pwm_gradient);
  Serial.print("settings.cool_step_enabled = ");
  Serial.println(settings.cool_step_enabled);
  Serial.print("settings.analog_current_scaling_enabled = ");
  Serial.println(settings.analog_current_scaling_enabled);
  Serial.print("settings.internal_sense_resistors_enabled = ");
  Serial.println(settings.internal_sense_resistors_enabled);
  Serial.println("*************************");
}

void printStatus(const TMC2209::Status &status)
{
  // Current Motor Driver Status If Flag:
  
  if (status.over_temperature_warning == 1) {
    Serial.print("status.over_temperature_warning = ");
    Serial.println(status.over_temperature_warning);
  }

  if (status.over_temperature_shutdown == 1) {
    Serial.print("status.over_temperature_shutdown = ");
    Serial.println(status.over_temperature_shutdown);
  }

  if (status.short_to_ground_a == 1) {
    Serial.print("status.short_to_ground_a = ");
    Serial.println(status.short_to_ground_a);
  }

  if (status.short_to_ground_b == 1) {
    Serial.print("status.short_to_ground_b = ");
    Serial.println(status.short_to_ground_b);
  }

  if (status.low_side_short_a == 1) {
    Serial.print("status.low_side_short_a = ");
    Serial.println(status.low_side_short_a);
  }

  if (status.low_side_short_b == 1) {
    Serial.print("status.low_side_short_b = ");
    Serial.println(status.low_side_short_b);
  }

  if (status.open_load_a == 1) {
    Serial.print("status.open_load_a = ");
    Serial.println(status.open_load_a);
  }

  if (status.open_load_b == 1) {
    Serial.print("status.open_load_b = ");
    Serial.println(status.open_load_b);
  }

  if (status.over_temperature_120c == 1) {
    Serial.print("status.over_temperature_120c = ");
    Serial.println(status.over_temperature_120c);
  }

  if (status.over_temperature_143c == 1) {
    Serial.print("status.over_temperature_143c = ");
    Serial.println(status.over_temperature_143c);
  }

  if (status.over_temperature_150c == 1) {
    Serial.print("status.over_temperature_150c = ");
    Serial.println(status.over_temperature_150c);
  }

  if (status.over_temperature_157c == 1) {
    Serial.print("status.over_temperature_157c = ");
    Serial.println(status.over_temperature_157c);
  }

  if (status.current_scaling == 1) {
    Serial.print("status.current_scaling = ");
    Serial.println(status.current_scaling);
  }

  if (status.stealth_chop_mode == 1) {
    Serial.print("status.stealth_chop_mode = ");
    Serial.println(status.stealth_chop_mode);
  }

  if (status.standstill == 1) {
    Serial.print("status.standstill = ");
    Serial.println(status.standstill);
  }
  Serial.println("*************************");
}
void stepX()
{
  if (deltaX < 0) // Set motor direction clockwise
    digitalWrite(dirPinX, HIGH);
  else
    digitalWrite(dirPinX, LOW);

  digitalWrite(stepPinX, HIGH);
    delayMicroseconds(5);
}


void stepY()
{
  if (deltaY < 0) // Set motor direction clockwise
    digitalWrite(dirPinY, HIGH);
  else
    digitalWrite(dirPinY, LOW);

  digitalWrite(stepPinY, HIGH);
    delayMicroseconds(5);

}

if (status.over_temperature_120c == 1)

Is that right?

Do the settings need to be modified? Or should it work with the commented out sections?

You should be able to use the method getStatus() to get the most recent status regardless of the other settings. Then you can check to see if status.over_temperature_120c is equal to one.

if status.over_temperature_120c is equal to one.

Ok, so that's the right format. I wasn't sure if there was some other conditional criteria (besides "1").

Oh well I think it is cleaner to use:
if (status.over_temperature_120c)
rather than:
if (status.over_temperature_120c == 1)

1 is true and 0 is false so you do not need to add the equal to one check.

Is there a way to test if any status, ideally some lower temperature, is working?

I am not sure what you mean exactly, but yes you can check one of the status bits and then print a message if that bit is true.

if (status.over_temperature_120c) { Serial.println("Warning driver temperature over 120C!"); }

Ok. The main issue was not connecting to the RX pin of the BIGTREETECH dev board.

Now it all works.

I tested the status program out by shorting each coil to ground and opening each motor coil.