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
183 stars 29 forks source link

Cannot make the UART Serial communication work with ESP32-S3 DevKit and BIGTREETECH TMC2209 1.3 UART drivers #49

Open astorun opened 10 months ago

astorun commented 10 months ago

Hello,

I am trying to make this library work with ESP32-S3 and BIGTREETECH TMC2209 1.3 UART drivers. https://www.amazon.com/BIGTREETECH-Printer-Stepstick-TMC2209-Heatsink/dp/B07YW7BM68/ref=cm_cr_arp_d_product_top?ie=UTF8&th=1

These new drivers does not have updated documentation so it is difficult how to set them properly for UART connection.

Anyone else here is successful doing it so? It does not make a UART Serial communication. I also tried included examples to test.

Drivers are working fine with simple STEP/DIR code. So they are all good.

Thanks.

astorun commented 10 months ago

I am using the following code included with the library.

#include <Arduino.h>
#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/

  /**
   * Four TMC2209 drivers can use the same HW/SW serial port with hardware configured addresses.
   * Set the address using jumpers on pins MS1 and MS2.
   * Address | MS1  | MS2
   *       0 | LOW  | LOW
   *       1 | HIGH | LOW
   *       2 | LOW  | HIGH
   *       3 | HIGH | HIGH
   */

const int RX_PIN = 17;
const int TX_PIN = 18;

HardwareSerial & serial_stream = Serial1;

const long SERIAL_BAUD_RATE = 115200;
const int DELAY = 3000;

// Instantiate TMC2209
TMC2209 stepper_driver;

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

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

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);
}

However I constantly get: "Stepper driver is not communicating! Try turning driver power on to see what happens." message.

TiddlyWiddly commented 10 months ago

I'm experiencing the same thing. I've hooked in the 1k resistor as specified but still having issues with the same ESP32-S3 and v1.3 Big Tree board.

astorun commented 10 months ago

Ok I solved the issue and it is an easy one related with power wiring.

I was using a separate 3V power supply for TMC logic and apparently it was the culprit. ESP32-S3 was powered from computer over USB.

Then I decided to power TMC logic over ESP32 3V pins to see if that is gonna make some difference.

And VOILA! It works!.

Not sure what is the issue here since my separate 3V power supply working fine. Tested it with multimeter.

I suspect it is related with both ESP32 and TMC driver needs to be on the same GND line or both required to be on exact same voltage I/O for UART wiring works.

So, how the way both ESP32 and TMC logic powered seems really important.

astorun commented 10 months ago

Also please note that TMC motor power (VS) pin also needs to supplied as well with separete GND. I am using an external 24V power supply to power the motors. If VS is not powered, TMC wont connect to ESP32.

TiddlyWiddly commented 10 months ago

I was powering the TMC from the 3.3 pin on the ESP32, but I wasn't providing VS power. I'll give this a shot tomorrow. Thank you for posting your fix.

On the TMC are you connected to the "RX" or the "TX"?

astorun commented 10 months ago

I connected both to ESP32. The trick is you need to also bridge the RX and TX jumpers on the TMC stepper itself like below and adding a 1k resistor to TX line between TMC to ESP32.

IMG_0146

Since TX pin on the TMC itself is not connected to anything, you need to wire them together with RX pin using a jumper pin or dupont wire.

TiddlyWiddly commented 10 months ago

Thank you for your help. I was able to get it to communicate without jumpering the pins. My connection is a little flakey, sometimes I have to reset it a few times, I don't have an explanation for that, but at least it's working.

Alternatively I guess you could probably just run a 1k resistor jumpering the two pins together to accomplish the same thing.

peterpolidoro commented 10 months ago

Is there anything I could add to the documentation to make this clearer for anyone else running into this issue in the future?

TiddlyWiddly commented 10 months ago

I think the documentation is clear, but maybe an ESP32 section would help. I had wired the 1k resistor as specified but for me the light bulb moment was the requirement for VS power being applied and I don't remember reading that anywhere in the docs. It simply doesn't work without VS power.

G-glop commented 9 months ago

It's also worth mentioning that ESP-IDF automatically enables a ~56K ohm pullup on UART RX pins: https://github.com/espressif/esp-idf/issues/1477

I was using a level shifter to transmit at 5V through a 1K resistor and receive through a 10K resistor, but then I found I was actually getting 0.7V on the RX pin due to the pullup.

astorun commented 7 months ago

I have some additional updates.

For esp32, keep the baud rate at 115200. Higher baud rate with multiple steppers over UART causes some steppers not detected. const long SERIAL_BAUD_RATE = 115200;

additionally adding a very short delay before and after stallguard detection is necessary for properly reading the values, otherwise you might get "zero" results.

  delay(5);
  uint16_t stall_guard_result0 = stepper_driver0.getStallGuardResult();
  delay(5);
  uint16_t stall_guard_result1 = stepper_driver1.getStallGuardResult();
  delay(5);
  uint16_t stall_guard_result2 = stepper_driver2.getStallGuardResult();
  delay(5);

I am using a my own designed PCB with directly soldered TMC2209 ICs, so far it works perfectly with this library. I will go ahead and implement Accelstepper as well to control it with DIR/STEP.