Open lukemm1979 opened 2 years ago
I have 10x TMC5160s running on SPI right now (mostly reliably). I do have an issue with getting the BOBs initialized where I have to initialize them twice for some reason. The really goofy part is that they work perfectly when the Teensy is rebooted after a reprogram. But a regular cold startup needs the redundant initialization. Still trying to track this one down.
BUT, there is a known issue with timing on the Teensy 4.0/4.1, and possibly others. The chip select line is switched too fast and communication fails. A fix for this is to put the following code at the bottom of your main program:
void TMC2130Stepper::switchCSpin(bool state) {
delayNanoseconds(100);
digitalWrite(_pinCS, state);
delayNanoseconds(100);
}
This overrides the chip select switching function to slow it down a bit. It may or may not work for your issue but it's worth a try.
C|
Hi @cbaugher
Thanks for the CS tip. In fact I solved my initial issue - some of the silkscreen labels on my (commercially produced) PCB were incorrect.
However I am now having some strange behaviour with the driver which I think may be SPI related. I tried implementing the switchCSpin() function you provided, but in the Release_V1 version of the library which I'm using, that function doesn't seem to be used. I'm only using that version of the library because I was under the impression it was the only one that supported trajectory generation on the TMC5160, and all the demo code I found for the 5160 used it. If you have working code which uses the master branch, I'd be grateful if you could share it.
Thanks,
Luke
Hi Luke,
I'm using version 0.7.3, which is the one available from the Arduino library manager. I don't know which code branch that is, but I don't think the usage differences are all that much.
All the code for running the motors is contained in various other functions besides the main loop, but my setup code looks like this:
` // Setup SPI channel SPI.begin();
// Make sure chip select pins for motor drivers are set high first pinMode(MCS1_PIN, OUTPUT); digitalWrite(MCS1_PIN, HIGH); pinMode(MCS2_PIN, OUTPUT); digitalWrite(MCS2_PIN, HIGH); pinMode(MCS3_PIN, OUTPUT); digitalWrite(MCS3_PIN, HIGH); pinMode(MCS4_PIN, OUTPUT); digitalWrite(MCS4_PIN, HIGH); pinMode(MCS5_PIN, OUTPUT); digitalWrite(MCS5_PIN, HIGH); pinMode(MCS6_PIN, OUTPUT); digitalWrite(MCS6_PIN, HIGH); pinMode(MCS7_PIN, OUTPUT); digitalWrite(MCS7_PIN, HIGH); pinMode(MCS8_PIN, OUTPUT); digitalWrite(MCS8_PIN, HIGH); pinMode(MCS9_PIN, OUTPUT); digitalWrite(MCS9_PIN, HIGH); pinMode(MCS10_PIN, OUTPUT); digitalWrite(MCS10_PIN, HIGH);
for(i=0; i<10; i++) { delay(200); driver[i].begin(); ver = driver[i].version(); if(ver>0) { Serial.print("Found Driver version: "); Serial.print(ver); Serial.print(" on channel: "); Serial.println(i+1);
driver[i].toff(0); // "0" Disables driver in software
driver[i].rms_current(MOTOR_DEFAULT_CURRENT, MOTOR_IHOLD); // Set motor RMS current
driver[i].microsteps(MOTOR_DEFAULT_MICROSTEPS); // Set default microsteps
driver[i].en_pwm_mode(true); // Toggle stealthChop on TMC2130/2160/5130/5160
driver[i].pwm_autoscale(true);
driver[i].TPOWERDOWN(DRIVER_TPOWERDOWN);
driver[i].TPWMTHRS(DRIVER_TPWMTHRS);
driver[i].TCOOLTHRS(DRIVER_TCOOLTHRS);
driver[i].semin(DRIVER_SEMIN);
driver[i].sgt(DRIVER_SGT);
driver[i].pwm_ampl(DRIVER_PWM_AMPL);
driver[i].pwm_grad(DRIVER_PWM_GRAD);
driver[i].pwm_freq(DRIVER_PWM_FREQ);
driver[i].VSTART(0); // Set starting velocity
driver[i].v1(0); // Set second velocity point
driver[i].AMAX(MOTOR_DEFAULT_AMAX); // Set acceleration
driver[i].VMAX(0); // Set maximum velocity
driver[i].DMAX(MOTOR_DEFAULT_AMAX); // Set maximum deceleration
driver[i].VSTOP(10); // Set maximum velocity before stopping
driver[i].RAMPMODE(1); // Set internal pulse generator ramping mode
//driver[i].sfilt(1); // Set filter
} else {
Serial.print("Couldn't find driver channel: ");
Serial.println(i+1);
}
} `
C|
Hi! Trying this code to give a lot of same the parameters to many motors suggested above but I'm not sure how to it.
`#include
int i = 0; TMC5160Stepper driver1 = TMC5160Stepper(CS_PIN1, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); TMC5160Stepper driver2 = TMC5160Stepper(CS_PIN2, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); TMC5160Stepper driver3 = TMC5160Stepper(CS_PIN3, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); TMC5160Stepper driver4 = TMC5160Stepper(CS_PIN4, R_SENSE, SW_MOSI, SW_MISO, SW_SCK);
void setup() {
int ver = 0; SPI.begin(); pinMode(CS_PIN1, OUTPUT); digitalWrite(CS_PIN1, HIGH); pinMode(CS_PIN2, OUTPUT); digitalWrite(CS_PIN2, HIGH); pinMode(CS_PIN3, OUTPUT); digitalWrite(CS_PIN3, HIGH); pinMode(CS_PIN4, OUTPUT); digitalWrite(CS_PIN4, HIGH); //Set HIGH first..?
for (i = 0; i < 4; i++) { delay(200); driver[i].begin(); ver = driver[i].version(); if (ver > 0) { Serial.print("Found Driver version: "); Serial.print(ver); Serial.print(" on channel: "); Serial.println(i + 1);
SPI.begin();
driver[i].begin(); // Initiate pins and registeries
driver[i].ihold(16);
driver[i].irun(31);
driver[i].iholddelay(5);
driver[i].TPOWERDOWN(10);
driver[i].GLOBAL_SCALER(80);
driver[i].microsteps(32);
driver[i].en_pwm_mode(1);
driver[i].pwm_autoscale(1);
driver[i].pwm_autograd(1);
driver[i].toff(5);
driver[i].tbl(2);
driver[i].hstrt(4);
driver[i].hend(0);
driver[i].RAMPMODE(0); // Set internal pulse generator ramping mode
driver[i].VSTART(0); // Set starting velocity
driver[i].v1(0); // 0 = disable A1 and D1 phase, use AMAX DMAX only
driver[i].AMAX(1000); // Set acceleration
driver[i].VMAX(6000); // Set maximum velocity
driver[i].DMAX(1000); // Set maximum deceleration
driver[i].VSTOP(10); // Set maximum velocity before stopping
} else {
Serial.print("Couldn't find driver channel: ");
Serial.println(i + 1);
}
} pinMode(EN_PIN, OUTPUT); digitalWrite(EN_PIN, LOW); // Enable driver in hardware
delay(1000); }
void loop() { if (driver1.XACTUAL() == 0) { //Go back and fourth driver1.XTARGET(50000); }
if (driver1.XACTUAL() == 50000) { driver1.XTARGET(0); } }`
Hi @artmekab ,
The problem is you've defined your drivers as individual objects and not as a single array of objects. You need to replace this chunk here:
TMC5160Stepper driver1 = TMC5160Stepper(CS_PIN1, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); TMC5160Stepper driver2 = TMC5160Stepper(CS_PIN2, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); TMC5160Stepper driver3 = TMC5160Stepper(CS_PIN3, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); TMC5160Stepper driver4 = TMC5160Stepper(CS_PIN4, R_SENSE, SW_MOSI, SW_MISO, SW_SCK);
With this:
TMC5160Stepper driver[4]; // This creates an array of 4 driver objects for(i=0;i<4;i++) { // This loop instantiates the driver objects TMC5160Stepper driver[i] = TMC5160Stepper(CS_PIN1, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); }
That should get you going.
C|
Hi! @cbaugher Thanks for your help! Did not work but I learned some about arrays I think. Also they would all get the same CS_PIN1 right?
This one compiled and worked:
TMC5160Stepper driver[4] = { TMC5160Stepper(CS_PIN1, R_SENSE, SW_MOSI, SW_MISO, SW_SCK), TMC5160Stepper(CS_PIN2, R_SENSE, SW_MOSI, SW_MISO, SW_SCK), TMC5160Stepper(CS_PIN3, R_SENSE, SW_MOSI, SW_MISO, SW_SCK), TMC5160Stepper(CS_PIN4, R_SENSE, SW_MOSI, SW_MISO, SW_SCK) };
Not a beauty..
I would have preferred your code though.
I tried the code you provided and got lots of errors:
`#include
int ver = 0; int i = 0;
TMC5160Stepper driver[4]; // This creates an array of 4 driver objects for(i=0;i<4;i++) { // This loop instantiates the driver objects TMC5160Stepper driver[i] = TMC5160Stepper(CS_PIN1, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); }
void setup() {
SPI.begin(); pinMode(CS_PIN1, OUTPUT); digitalWrite(CS_PIN1, HIGH); pinMode(CS_PIN2, OUTPUT); digitalWrite(CS_PIN2, HIGH); pinMode(CS_PIN3, OUTPUT); digitalWrite(CS_PIN3, HIGH); pinMode(CS_PIN4, OUTPUT); digitalWrite(CS_PIN4, HIGH); //Set HIGH first..?
for (i = 0; i < 4; i++) { delay(200); driver[i].begin(); ver = driver[i].version(); if (ver > 0) { Serial.print("Found Driver version: "); Serial.print(ver); Serial.print(" on channel: "); Serial.println(i + 1);
SPI.begin();
driver[i].begin(); // Initiate pins and registeries
driver[i].ihold(16);
-------- //removed some settings to keep the code shorter here on the forum
driver[i].VSTOP(10); // Set maximum velocity before stopping
} else {
Serial.print("Couldn't find driver channel: ");
Serial.println(i + 1);
}
} pinMode(EN_PIN, OUTPUT); digitalWrite(EN_PIN, LOW); // Enable driver in hardware
delay(1000); }
void loop() { if (driver[0].XACTUAL() == 0) { driver[0].XTARGET(50000); }
if (driver[0].XACTUAL() == 50000) { driver[0].XTARGET(0); } }`
C:\Users\norde\Dropbox\ARDUINO KOD\TMC5160_stepstick\Software_SPI\Software_SPI.ino:21:24: error: no matching function for call to 'TMC5160Stepper::TMC5160Stepper()'
TMC5160Stepper driver[4]; // This creates an array of 4 driver objects
^
In file included from C:\Users\norde\Dropbox\ARDUINO KOD\TMC5160_stepstick\Software_SPI\Software_SPI.ino:6:0:
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:726:3: note: candidate: TMC5160Stepper::TMC5160Stepper(uint16_t, float, uint16_t, uint16_t, uint16_t, int8_t)
TMC5160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1);
^~~~~~
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:726:3: note: candidate expects 6 arguments, 0 provided
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:725:3: note: candidate: TMC5160Stepper::TMC5160Stepper(uint16_t, uint16_t, uint16_t, uint16_t, int8_t)
TMC5160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1);
^~~~~~
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:725:3: note: candidate expects 5 arguments, 0 provided
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:724:3: note: candidate: TMC5160Stepper::TMC5160Stepper(uint16_t, float, int8_t)
TMC5160Stepper(uint16_t pinCS, float RS = default_RS, int8_t link_index = -1);
^~~~~~
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:724:3: note: candidate expects 3 arguments, 0 provided
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:722:7: note: candidate: constexpr TMC5160Stepper::TMC5160Stepper(const TMC5160Stepper&)
class TMC5160Stepper : public TMC5130Stepper {
^~~~~~
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:722:7: note: candidate expects 1 argument, 0 provided
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:722:7: note: candidate: constexpr TMC5160Stepper::TMC5160Stepper(TMC5160Stepper&&)
c:\Users\norde\OneDrive\Documents\Arduino\libraries\TMCStepper-master\src/TMCStepper.h:722:7: note: candidate expects 1 argument, 0 provided
C:\Users\norde\Dropbox\ARDUINO KOD\TMC5160_stepstick\Software_SPI\Software_SPI.ino:22:1: error: expected unqualified-id before 'for'
for(i=0;i<4;i++) { // This loop instantiates the driver objects
^~~
C:\Users\norde\Dropbox\ARDUINO KOD\TMC5160_stepstick\Software_SPI\Software_SPI.ino:22:9: error: 'i' does not name a type
for(i=0;i<4;i++) { // This loop instantiates the driver objects
^
C:\Users\norde\Dropbox\ARDUINO KOD\TMC5160_stepstick\Software_SPI\Software_SPI.ino:22:13: error: 'i' does not name a type
for(i=0;i<4;i++) { // This loop instantiates the driver objects
^
exit status 1
Compilation error: no matching function for call to 'TMC5160Stepper::TMC5160Stepper()'
Hi! @cbaugher Thanks for your help! Did not work but I learned some about arrays I think. Also they would all get the same CS_PIN1 right?
This one compiled and worked:
TMC5160Stepper driver[4] = { TMC5160Stepper(CS_PIN1, R_SENSE, SW_MOSI, SW_MISO, SW_SCK), TMC5160Stepper(CS_PIN2, R_SENSE, SW_MOSI, SW_MISO, SW_SCK), TMC5160Stepper(CS_PIN3, R_SENSE, SW_MOSI, SW_MISO, SW_SCK), TMC5160Stepper(CS_PIN4, R_SENSE, SW_MOSI, SW_MISO, SW_SCK) };
Not a beauty..I would have preferred your code though.
I tried the code you provided and got lots of errors:
@artmekab
Oh yes, that's right. You do have to initialize the objects in the array declaration. I did do it that way in my own code and had forgotten. It doesn't look the best but you can play around with the formatting to make it a bit less clunky.
You will need to use separate chip select lines for each chip, like you've done.
C|
Hi,
I want to control 5 TMC5160 BOBs over SPI using a Teensy 4.0. I've managed to get the library (Release_v1) working with one 5160 using the code below (a modified version of some example code I found posted here). However if I change CS pin (in hardware and software) to anything other than pin 10 it doesn't work. I thought maybe I could get round this using the software SPI library, as follows:
// SW_SPIClass swSPI(TMC_MOSI, TMC_MISO, TMC_SCK); // TMC5160Stepper driver(swSPI, csPin, r_sense);
But this doesn't work at all. Any pointers would be greatly appreciated.
Full code (working using hardware SPI with chip select on pin 10 only):