ESP32 mit 2 TMC2209 Stepper Treiber über UART

Hallo zusammen.
Ich habe an meinem ESP32 - 2 Schrittmotoren über TMC2209 Treiber angeschlossen.
Die Kommunikation zwischen ESP32 und TMC2209 läuft über PDN/UART verbindung.

Jetzt zu meinem Problem:
Wenn ich einen von den zwei Treibern etwas anders einstellen möchte, dann bekommt der 2te Treiber auch die gleiche Einstellungen.
Ich komme einfach nicht mehr Weiter und habe auch schon sehr viel versucht.
Ich möchte die 2 Treiber unterschiedlich Einstellen, nur klappt das leider nicht.

#include <TMCStepper.h>
#include <AccelStepper.h>

#define SW_RX             17 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX             16 // TMC2208/TMC2224 SoftwareSerial transmit pin
#define EN_PIN            32  // LOW: Driver enabled. HIGH: Driver disabled
#define STEP_PIN          12  // Step on rising edge
#define DIR_PIN           13  // Step on rising edge
#define SERIAL_PORT       Serial2 // TMC2208/TMC2224 HardwareSerial port
#define R_SENSE           0.11  // SilentStepStick series use 0.11     Watterott TMC5160 uses 0.075
#define DRIVER_ADDRESS    0b00 // TMC2209 Driver address according to MS1 and MS2
TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);
AccelStepper stepper = AccelStepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);

#define EN_PIN_2          26  // LOW: Driver enabled. HIGH: Driver disabled
#define STEP_PIN_2        27  // Step on rising edge
#define DIR_PIN_2         14  // Step on rising edge
#define SERIAL_PORT_2     Serial2 // TMC2208/TMC2224 HardwareSerial port
#define R_SENSE_2         0.11  // SilentStepStick series use 0.11     Watterott TMC5160 uses 0.075
#define DRIVER_ADDRESS_2  0b00 // TMC2209 Driver address according to MS1 and MS2
TMC2209Stepper driver_2(&SERIAL_PORT_2, R_SENSE_2, DRIVER_ADDRESS_2);
AccelStepper stepper_2 = AccelStepper(AccelStepper::DRIVER, STEP_PIN_2, DIR_PIN_2);

..............
void setup() {
  Serial.begin(115200); 
  //Serial2.begin(115200); // SW UART drivers
  SERIAL_PORT.begin(115200, SERIAL_8N1, SW_RX, SW_TX);
  SERIAL_PORT_2.begin(115200, SERIAL_8N1, SW_RX, SW_TX);

  driver.begin();                // Initialize driver                   
  driver.toff(5);                 // Enables driver in software
  driver.pdn_disable(true);     // Use PDN/UART pin for communication
  driver.I_scale_analog(false); // Use internal voltage reference
  driver.rms_current(400);       // Set motor RMS current
  driver.microsteps(8);           // Set microsteps to 1/8     <<----------------------------
  driver.pwm_autoscale(true);   // Needed for stealthChop
  driver.shaft(0);
  stepper.setSpeed(80*80);
  stepper.setMaxSpeed(80*80);
  stepper.setAcceleration(200*80);

  driver_2.begin();                // Initialize driver                   
  driver_2.toff(5);                 // Enables driver in software
  driver_2.pdn_disable(true);     // Use PDN/UART pin for communication
  driver_2.I_scale_analog(false); // Use internal voltage reference
  driver_2.rms_current(800);       // Set motor RMS current
  driver_2.microsteps(16);           // Set microsteps to 1/16  <<----------------------------
  driver_2.pwm_autoscale(true);   // Needed for stealthChop
  driver_2.shaft(0);
  stepper_2.setSpeed(80*80);
  stepper_2.setMaxSpeed(80*80);
  stepper_2.setAcceleration(200*80);
................

Hier im Code habe ich die 2 Treiber jetzt auf den gleichen RX und TX Pin gelegt.
Ich habe auch andere RX und TX Pin versucht, aber anscheinend mache ich irgendetwas falsch.
Wenn ich z.B. bei dem ersten Treiber die Schrittauflösung ändere, dann wird es auch bei dem 2ten Treiber aktiv.

Ich bedanke mich im Voraus für die Hilfe und wünsche euch ein Frohes neues Jahr.

Gruss

äh
Jetzt verstehe ich Deine Probleme nicht.
Wenn Du beide Treiber an die gleiche serielle Schnittstelle anschließt wieso sollen die dann verschiedene Einstellungen bekommen?

Grüße Uwe

Frohes Neue Jahr.

Nur bloede Frage zum Nachdenken (oder Nachfragen):

  • sind das zwei separate, aber identische boards, wobei jedes ein UART Interface hat?
    dann musst Du auch zwei UARTs an MCU haben, jede separat
  • wenn beide das gleiche Kommando bekommen, klingt das eher wie: "beide sind an der GLEICHEN UART angekoppelt". Deshalb machen sie beides gleich (HW schematics?)

Wenn Du also zwei UARTs konfigurierst, dann sollte das total separat sein: fuer jede eine Einstellung und jede UART hat ihre eigenen Pins.
(Nicht klar ob moeglich): wenn Du zwar zwei UARTs konfigurierst, aber die kommen beide an gleichen Pins raus (Tx, Rx) und Du greiffst fuer beide Boards nur einem Paar Tx/Rx gemeinsam ab: dann bekommen beide das gleiche Kommando (na klar).

Klingt so, als ob EINE UART beide boards in parallel treibt, deshalb das gleiche Kommando.
Zwei board, zwei UARTs - meint auch separate pins und Kabel zu den Boards. Irgendwo ist ein "Kurzschluss" so dass beide boards das gleiche bekommen (kann ja auch in SW/FW sein).

Viele Gruesse und Erfolgreiches Neues Jahr.

Danke @Uwe.
Habe ja extra geschrieben, das ich jetzt beide Treiber auf den gleichen Pin gelegt habe und es vorher auch nicht auf einen anderen RX und TX Pin funktioniert hatte.

Ich werde es aber nochmal testen, den 2ten Treiber auf einen anderen RX und TX Pin zu legen, vielleicht hatte ich etwas übersehen.

Gruss

Vielen Dank und ein Frohes neues Jahr.
Ich habe da eventuell etwas durcheinander gebracht und werde es nochmal versuchen, den 2ten Treiber auf einen anderen RX und TX Pin zu legen.

Gruss

Viel Erfolg.
Einfach mal "schematics": was ist mit was verbunden?, was wird von SW/FW als separater Kanal gesehen (oder als den gleichen)...?
Ich glaube, Du hast einfach nur ein "Kurzschluss" in der Signal-Verbindung (warum beide das gleiche Kommando sehen).
"Kurschluss" kann auch in der FW sitzen, nicht nur in HW.

Viel Erfolg.

"Kurzschluss" in FW kann auch durch folgendes passieren:

  • Du erzeugst zwar zwei separate UARTs
  • die haben auch separate pins und HW-wise alles ist OK (die sind wirklich getrennt voneinander, nichts gemeinsames, an der Aussenseite)

==> aber in der FW benutzt Du fuer beide UARTs die gleichen Puffer: so, beide senden von Tx Buffer, selbst wenn alles getrennt (HW-wise), in SW senden die vom gleichen Puffer. Damit bekommen beide das gleiche Kommando.

Wirklich auch in SW/FW nach "shared" buffers suchen, selbst wenn zwei UART Devices kreiert - kann immer noch sein, dass beide nicht auf ihrem EIGENEM Buffer arbeiten, sondern einen gemeinsamen verwenden (ist dann "SW-Kurzschluss").

Viel Erfolg.

Vielen Dank.
Ich habe den anderen Treiber jetzt nochmal auf RX0 und TX0 gelegt und den Code nochmal angepasst und nun funktioniert es.
Das hatte ich vorhin auch schon so getestet aber im Code eventuell was übersehen.

#define SW_RX             17 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX             16 // TMC2208/TMC2224 SoftwareSerial transmit pin
#define EN_PIN            32  // LOW: Driver enabled. HIGH: Driver disabled
#define STEP_PIN          12  // Step on rising edge
#define DIR_PIN           13  // Step on rising edge
#define SERIAL_PORT       Serial2 // TMC2208/TMC2224 HardwareSerial port
#define R_SENSE           0.11  // SilentStepStick series use 0.11     Watterott TMC5160 uses 0.075
#define DRIVER_ADDRESS    0b00 // TMC2209 Driver address according to MS1 and MS2
TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);
AccelStepper stepper = AccelStepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);

#define SW_RX_2             1 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX_2             3 // TMC2208/TMC2224 SoftwareSerial transmit pin
#define EN_PIN_2          26  // LOW: Driver enabled. HIGH: Driver disabled
#define STEP_PIN_2        27  // Step on rising edge
#define DIR_PIN_2         14  // Step on rising edge
#define DRIVER_ADDRESS_2  0b00 // TMC2209 Driver address according to MS1 and MS2
#define SERIAL_PORT_2       Serial1 // TMC2208/TMC2224 HardwareSerial port
TMC2209Stepper driver_2(&SERIAL_PORT_2, R_SENSE, DRIVER_ADDRESS_2);
AccelStepper stepper_2 = AccelStepper(AccelStepper::DRIVER, STEP_PIN_2, DIR_PIN_2);

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

  //Serial2.begin(115200); // SW UART drivers
  SERIAL_PORT.begin(115200, SERIAL_8N1, SW_RX, SW_TX);
  SERIAL_PORT_2.begin(115200, SERIAL_8N1, SW_RX_2, SW_TX_2);
.........

Und vielen Dank für die schnelle Hilfe und wünsche euch noch einen schönen Nacht/Morgen.

Gruss

Cool! Well done!
Viele Gruesse aus CA.

Torsten

Ich hätte da allerdings noch eine Frage:
Ist es möglich bei dem ESP32 auch andere Pins als RX und TX für die Serielle Verbindung zu definieren?
Oder sollte man lieber die Standard RX und TX Pins benutzen?

Andernfalls werde ich einen Mega2560 verwenden, wenn ich etwas größeres vor habe.

Gruss

Andere Pins zu definieren ist möglich

Wenn du mit "Standard RX und TX Pins" die IO-pins meinst die von "Serial" (= UART0) benutzt werden.
Das sind die IO-pins Tx = GP-IO 1 und Rx GP-IO 3
Die sollte man nicht benutzen! Auf Standard-Serial wird das Programm geflasht und Daten an den Serial Monitor gesendet.

Hier ist eine Tabelle dazu

Andererseits ist im constructor des TMC2209 von einer driver-adress die Rede.

Das deutet darauf hin dass man den TMC2209 unterschiedliche Adressen geben kann
und man dann beide TMC2209 hardware-mäßig an einen serial port anschliessen kann und das Ansprechen dann über diese driver-adress erfolgt.

Hast du dazu im Datenblatt des TMC2209 nachgelesen?

Sind diese Adress-Eingänge MS1_AD0 und MS1_AD1 auf deinem Board herausgeführt?

Beim Waterott Silent Step-stick scheint das der Fall zu sein
Pins MS1 / MS2


vgs

Super, vielen herzlichen Dank für die Erklärung.
Das habe ich gestern schon so machen wollen über eine Serielle Verbindung, nur habe ich das leider nicht hinbekommen über die Adresse.
Das Datenblatt hatte ich auch hier vorliegen, aber anscheinend hatte ich doch etwas falsch gemacht. Es war ja auch spät und hatte da einfach keinen Kopf mehr dazu. :frowning:

Jetzt habe ich den Pin MS1 vom 2ten Treiber auf 5V gelegt und nun funktioniert es endlich.

#include <TMCStepper.h>
#include <AccelStepper.h>

#define SW_RX             17 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX             16 // TMC2208/TMC2224 SoftwareSerial transmit pin
#define EN_PIN            32  // LOW: Driver enabled. HIGH: Driver disabled
#define STEP_PIN          12  // Step on rising edge
#define DIR_PIN           13  // Step on rising edge
#define SERIAL_PORT       Serial2 // TMC2208/TMC2224 HardwareSerial port
#define R_SENSE           0.11  // SilentStepStick series use 0.11     Watterott TMC5160 uses 0.075
#define DRIVER_ADDRESS    0b00 // TMC2209 Driver address according to MS1 and MS2
TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);
AccelStepper stepper = AccelStepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);

#define EN_PIN_2          26  // LOW: Driver enabled. HIGH: Driver disabled
#define STEP_PIN_2        27  // Step on rising edge
#define DIR_PIN_2         14  // Step on rising edge
#define R_SENSE_2           0.11  // SilentStepStick series use 0.11     Watterott TMC5160 uses 0.075
#define DRIVER_ADDRESS_2  0b10 // TMC2209 Driver address according to MS1 and MS2
TMC2209Stepper driver_2(&SERIAL_PORT, R_SENSE_2, DRIVER_ADDRESS_2);
AccelStepper stepper_2 = AccelStepper(AccelStepper::DRIVER, STEP_PIN_2, DIR_PIN_2);

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

  //Serial2.begin(115200); // SW UART drivers
  SERIAL_PORT.begin(115200, SERIAL_8N1, SW_RX, SW_TX);
.....................

Ich habe soeben mal schnell eine Schaltung erstellt, um es zu Zeigen, wie ich es verbunden habe.

Scheint nun zu Funktionieren und vielen Dank nochmal.

Gruss

Ja, es gibt drei UARTs in Hardware:

  • UART0 mit RXD0=GPIO3 und TXD0=GPIO0; wird auch von USB genutzt
  • UART1 mit RXD1=GPIO9 und TXD1=GPIO10; die Pins sind von Flash blockiert, daher müssen sie auf andere Pins verlegt werden: Serial1.begin(115200, SERIAL_8N1, 15, 2); // ESP32: unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin
  • UART2 mit RXD2=GPIO16 und TXD2=GPIO17; Serial2.begin(115200);

Pinbelegung ESP32:


Quelle

Das ist also eine unnötige Verdrehung:

  //Serial2.begin(115200); // SW UART drivers
  SERIAL_PORT.begin(115200, SERIAL_8N1, SW_RX, SW_TX);

Es genügt mit einem Pintausch 16 ↔ 17:

Serial2.begin(115200); // Hardware UART

Bei einige Beispiele habe ich das so gelesen, aber werde dann diese Variante verwenden:

Serial2.begin(115200); // Hardware UART

Vielen Dank.

Gruss

Ja, ich auch, daher weiß ich auch vom RX/TX-Tausch. Möglicherweise war das bei einer früheren Core-Version mal anders/notwendig/sinnvoll. Oder es hat jemand verbockt und die anderen haben fleißig abgeschrieben.

Da es UART0 und UART2 gibt, habe ich mal angefangen, bei diesem Thema zu forschen. Sonst ist der Mega2560 mit den verschiedenen UARTs im Einsatz, so bildet der ESP32 eine 3,3 V-Alternative. Wäre ja "Verschwendung", vorhandene Möglichkeiten nicht zu nutzen :slightly_smiling_face:

Das interpretiere ich daß Du jetzt beide Treiber auf Pin A uns B angeschlossen hast und vorher beide an den Pins C und D, aber immer beide zusammen.

Das wird das Problem lösen.

Grüße Uwe

Das Problem habe ich ja schon lange gelöst und beide Treiber lassen sich jetzt unterschiedlich einstellen.
Beide sind über dieselbe RX und TX Pin angeschlossen, nur hat der andere Treiber jetzt eine andere Adresse bekommen.

Das kann sein, aber gut, das es auch so funktioniert mit dem RX/TX-Tausch.

Gruss

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.