janelia-arduino / TMC2209

The TMC2209 is an ultra-silent motor driver IC for two phase stepper motors with both UART serial and step and direction interfaces.
Other
171 stars 26 forks source link

Weird UART problem with ESP32 #60

Open Angelo13C opened 5 months ago

Angelo13C commented 5 months ago

Hi! I have a TMC2209 silentstepstick driver connected to a custom PCB that I made. I am using this library to communicate with my driver, this is the code (it's a slightly modified example present in this repo):

#include <TMC2209.h>

// This example will not work on Arduino boards without HardwareSerial ports,
// such as the Uno, Nano, and Mini.
//
// See this reference for more details:
// https://www.arduino.cc/reference/en/language/functions/communication/serial/

HardwareSerial & serial_stream = Serial1;

const long SERIAL_BAUD_RATE = 115200;
const int DELAY = 1000;
const int RX_PIN = 17;
const int TX_PIN = 18;

// Instantiate TMC2209
TMC2209 stepper_driver;

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

  stepper_driver.setup(serial_stream,SERIAL_BAUD_RATE,TMC2209::SERIAL_ADDRESS_0, RX_PIN, TX_PIN);
  stepper_driver.setReplyDelay(10);
}

void loop()
{
  if (stepper_driver.isSetupAndCommunicating())
  {
    Serial.println("Stepper driver is setup and communicating!");
    Serial.println("Try turning driver power off to see what happens.");
  }
  else if (stepper_driver.isCommunicatingButNotSetup())
  {
    Serial.println("Stepper driver is communicating but not setup!");
    Serial.println("Running setup again...");
    stepper_driver.setup(serial_stream);
  }
  else
  {
    Serial.println("Stepper driver is not communicating!");
    Serial.println("Try turning driver power on to see what happens.");
  }
  Serial.println();
  delay(DELAY);
}

Now it always prints "Stepper driver is not communicating!"... The weird thing is that I attached my oscilloscope to the PDN_UART pin of the driver and this is what I see

Not working

As you can see the ESP32 sends the data to the driver, the driver replies but the 0 bits of the reply don't go all the way down to 0V but stay around 2.4V.. which is really weird, and probably my ESP32 doesn't recognize 2.4V as a low value (because it's too high voltage).

Do you have any idea what the problem could be?

Angelo13C commented 5 months ago

I connected my driver like in this image: https://github.com/makerbase-mks/MKS-StepStick-Driver/issues/6#issuecomment-1296336860

The only different thing is that the I/O voltage is 3.3V and not 5V (because I am not using an Arduino but I am using an ESP32) and the Vm voltage is 24V and not 12V

Angelo13C commented 5 months ago

I think it's related to this problem: https://community.particle.io/t/p2-module-tmc2209-driver-tx-rx-pullup-issue-possibly-preventing-bidirectional-comms/64194

But I can't understand how to solve it (I am using an ESP32-S3-WROOM-1 and not the one in the link.. but the problem is similar, probably a pull up resistor?)

peterpolidoro commented 5 months ago

That does seem like an electrical issue, although I am not sure what could be causing it. The silentstepstick does not have a pull up or pull down resister on the uart line does it? Maybe the uart line inside your microcontroller has a pull up? Maybe you can disable that in your firmware?

Angelo13C commented 5 months ago

This is my driver

image

As you can see it has a 20K pull down resistor on the PDN_UART. I don't know how to check if the microcontroller has a pull up resistor, I am going to check

peterpolidoro commented 5 months ago

Which driver board is that, one you made or one you purchased from somewhere? Can you try removing that pull down resister to see what happens?

Angelo13C commented 5 months ago

I bought it, it's an MKS TMC2209 V2.0. I could try removing the pull down resistor, it's weird, why is it there?

Angelo13C commented 5 months ago

Ok actually even some others boards (like this one seem to have that pull down resistor

peterpolidoro commented 5 months ago

I have used the Trinamic silenstepstick many times without a problem, so you are probably running into sone other problem. Can you try another microcontroller or different pin settings in your microcontroller?

Luro02 commented 3 months ago

Do you really have an ESP32-S3 and not an ESP32-C3? The code has the TX1/RX1 pins for an ESP32-C3 and not an ESP32-S3.

You are using Serial1, so the RX1/TX1 are these pins:

#elif CONFIG_IDF_TARGET_ESP32S3
#define RX1 (gpio_num_t)15

https://github.com/espressif/arduino-esp32/blob/c39683469605dc4bf1f8effe774c80f72d6825a9/cores/esp32/HardwareSerial.h#L159-L160

#elif CONFIG_IDF_TARGET_ESP32S3
#define TX1 (gpio_num_t)16

https://github.com/espressif/arduino-esp32/blob/c39683469605dc4bf1f8effe774c80f72d6825a9/cores/esp32/HardwareSerial.h#L177-L178

I have the same Stepper Driver (MKS V2.0) and for me bidirectional communication is working (I don't have an ESP32-S3, only an ESP32-C6 and ESP32-H2, they both work). Note: The stepper driver is only communicating when the power supply for the stepper is on.

I designed a PCB for the ESP32-C6 and the TMC2209, this is the schematic for it (maybe it helps with the wiring?): image (The R is like mentioned in the readme, a 1k resistor)

For reference this is the sketch I used to test communication:

#include <TMC2209.h>

const uint8_t STEP_PIN = 10;
const uint8_t DIR_PIN = 11;
#define RX_PIN 4 // = RX1
#define TX_PIN 5 // = TX1
//ESP32-H2:
//#define RX_PIN 0 // = RX1
//#define TX_PIN 1 // = TX1

HardwareSerial & serial_stream = Serial1;
TMC2209 stepper_driver;

void setup() {
  Serial.begin(115200);
  stepper_driver.setup(serial_stream);
  delay(2000);

  stepper_driver.enableCoolStep();
  stepper_driver.moveUsingStepDirInterface();

  //stepper_driver.useInternalSenseResistors();

  stepper_driver.enableAutomaticCurrentScaling();
  stepper_driver.enableAutomaticGradientAdaptation();

  stepper_driver.enableStealthChop();
  stepper_driver.enable();
}

void loop() {
  // put your main code here, to run repeatedly:

  //stepper_driver.moveAtVelocity(100000);
  if (stepper_driver.isSetupAndCommunicating())
  {
    Serial.println("Stepper driver is setup and communicating!");
    Serial.println("Try turning driver power off to see what happens.");
  }
  else if (stepper_driver.isCommunicatingButNotSetup())
  {
    Serial.println("Stepper driver is communicating but not setup!");
    Serial.println("Running setup again...");
    stepper_driver.setup(serial_stream);
  }
  else
  {
    Serial.println("Stepper driver is not communicating!");
    Serial.println("Try turning driver power on to see what happens.");
  }
  Serial.println();
  delay(1000);
}
Luro02 commented 3 months ago

A few days ago, my custom PCB arrived that is based on the above schematic. Paid about 7€ including shipping for the PCB and I am always able to get a reliable bidirectional communication. If you are interested, you can find it here https://github.com/Luro02/pcb-esp32-tmc2209 (uploading the output.zip found here https://github.com/Luro02/pcb-esp32-tmc2209/actions/runs/9041802105) should work.

The only problem is that you must buy a nanoESP32-C6 (other boards/pins will not fit).