Hello, I've been looking around but I can't find a solution for this problem.
I have a tcm2209 motor drivers and I want to move a stepper motor with it.
I found this code with the tmc library but when I try to compile I get a SoftwareSerial error. 'SoftwareSerial' does not name a type.
Not sure what I'm missing. I changed some of the Gpio to match my wiring and this is the code I'm using.
Thanks in advance.
#include <TMCStepper.h> // TMCstepper - https://github.com/teemuatlut/TMCStepper
#include <SoftwareSerial.h> // Software serial for the UART to TMC2209 - https://www.arduino.cc/en/Reference/softwareSerial
#include <Streaming.h> // For serial debugging output - https://www.arduino.cc/reference/en/libraries/streaming/
#define EN_PIN 20 // Enable - PURPLE
#define DIR_PIN 21 // Direction - WHITE
#define STEP_PIN 22 // Step - ORANGE
#define SW_SCK 28 // Software Slave Clock (SCK) - BLUE
#define SW_TX 6 // SoftwareSerial receive pin - BROWN
#define SW_RX 7 // SoftwareSerial transmit pin - YELLOW
#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2
#define R_SENSE 0.11f // SilentStepStick series use 0.11 ...and so does my fysetc TMC2209 (?)
SoftwareSerial SoftSerial(SW_RX, SW_TX); // Be sure to connect RX to TX and TX to RX between both devices
TMC2209Stepper TMCdriver(&SoftSerial, R_SENSE, DRIVER_ADDRESS); // Create TMC driver
int accel;
long maxSpeed;
int speedChangeDelay;
bool dir = false;
//== Setup ===============================================================================
void setup() {
Serial.begin(11520); // initialize hardware serial for debugging
SoftSerial.begin(11520); // initialize software serial for UART motor control
TMCdriver.beginSerial(11520); // Initialize UART
pinMode(EN_PIN, OUTPUT); // Set pinmodes
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
digitalWrite(EN_PIN, LOW); // Enable TMC2209 board
TMCdriver.begin(); // UART: Init SW UART (if selected) with default 115200 baudrate
TMCdriver.toff(5); // Enables driver in software
TMCdriver.rms_current(500); // Set motor RMS current
TMCdriver.microsteps(256); // Set microsteps
TMCdriver.en_spreadCycle(false);
TMCdriver.pwm_autoscale(true); // Needed for stealthChop
}
//== Loop =================================================================================
void loop() {
accel = 10000; // Speed increase/decrease amount
maxSpeed = 50000; // Maximum speed to be reached
speedChangeDelay = 100; // Delay between speed changes
for (long i = 0; i <= maxSpeed; i = i + accel) { // Speed up to maxSpeed
TMCdriver.VACTUAL(i); // Set motor speed
Serial << TMCdriver.VACTUAL() << endl;
delay(100);
}
for (long i = maxSpeed; i >= 0; i = i - accel) { // Decrease speed to zero
TMCdriver.VACTUAL(i);
Serial << TMCdriver.VACTUAL() << endl;
delay(100);
}
dir = !dir; // REVERSE DIRECTION
TMCdriver.shaft(dir); // SET DIRECTION
}
If you only need to transmit to the stepper controller, you can try my Dumb TX-only SoftwareSerial
It should work on boards where delayMicroseconds is accurate.
Um. "11520" is almost certainly not correct. The common bitrate is "115200", and I don't think softwareSerial is expected to work that fast...
Yeah, that baud rate is not correct. You might want to check the original post, it has more information.
The code you posted was heavily modified from my original example. For example it only used the VACTUAL command to move the stepper, and its not particularly useful if you want to count steps.
And i had SpeedyStepper library included for the actual stepper controlling. Currently i would recommend using FastAccelStepper library for the actual stepper controlling. And i did not use software serial, as i'm using ESP32 boards.
This also seems weird to me:
Serial.begin(11520); // initialize hardware serial for debugging
SoftSerial.begin(11520); // initialize software serial for UART motor control
TMCdriver.beginSerial(11520); // Initialize UART
I think it initializes the software serial twice.
I think its taken from this example, where the software serial is only initialized once. But i don't use software serial so i don't know much about it.
Hello, yeah not sure what happened with that 11520 britate. Most likely I copied it wrong. Thanks for your help. I will check what option I have then and check that dumb tx you are mentioning.
Oh I see. I went thru the original post but because of my lack of knowledge I just missed all the important parts haha! Thanks for pointing that out and I will try that fastaccelstepper you are mentioning.
Did you check the UART connection and the 1k resistor?
After that, if you are using software serial.. probably best to just first set the TMC library.. check that you have proper connection. That you can set & read the microstep. Set any other microstep than 256, as that's what i reads when you do not have a connection.
Here is the basic setup of FastAccelStepper, all you need is the TMCStepper librabry & this.
#include <TMCStepper.h>
#define EN_PIN 38 // Enable
#define DIR_PIN 55 // Direction
#define STEP_PIN 54 // Step
#define SW_RX 63 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX 40 // TMC2208/TMC2224 SoftwareSerial transmit pin
#define DRIVER_ADDRESS 0b00
#define R_SENSE 0.11f
TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);
using namespace TMC2209_n;
#include "FastAccelStepper.h"
FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *stepper = NULL;
void setup() {
//ENABLE LOW IF CONNECTED
digitalWrite(EN_PIN, LOW); // Enable TMC2209 board
//SERIAL INIT
Serial.begin(115200);
//TMC LIBRARY
driver.beginSerial(115200); // SW UART drivers
driver.begin(); // SPI: Init CS pins and possible SW SPI pins
driver.toff(5); // Enables driver in software
driver.rms_current(600); // Set motor RMS current
driver.microsteps(16); // Set microsteps to 1/16th
//driver.en_pwm_mode(true); // Toggle stealthChop on TMC2130/2160/5130/5160
//driver.en_spreadCycle(false); // Toggle spreadCycle on TMC2208/2209/2224
driver.pwm_autoscale(true); // Needed for stealthChop
//ACCELL STEPPER SPEED & ACCELERATION
engine.init();
stepper = engine.stepperConnectToPin(STEP_PIN);
stepper->setDirectionPin(DIR_PIN);
stepper->setEnablePin(EN_PIN, true);
stepper->setCurrentPosition(0);
stepper->setSpeedInHz(1000); // STEPS PER SECOND
stepper->setAcceleration(1000);
}
void loop() {
Serial.print(F("Read microsteps via UART to test UART receive : "));
Serial.println(driver.microsteps()); // POST MICROSTEPS TO SERIAL
stepper->moveTo(2000);
delay(1000);
stepper->setSpeedInHz(100); // STEPS PER SECOND
stepper->setAcceleration(100); // YOU CAN CHANGE SPEED & ACCELERATION BEFORE THE MOVE COMMAND
stepper->moveTo(0,true); // ADD true FOR BLOCKING MOVEMENT ( STOPS THE CODE UNTIL MOVEMENT IS COMPLETED)
delay(1000);
}
I have not tested this code, but these are the basics you should have. And now you have way to move the motor based on steps & adjust its speed & acceleration.
You also do not need to connect the EN pin, you can just use a jump wire on the driver and connect it to ground. One less wire to worry about, and if you need to ever shut down the driver.. you can do it via UART.
Sorry for asking a dumb question, but which "Pico" ? Can you give a link to your board ? I can think of 5 boards with something Pico-ish in the name and a new one seems to appear every month. I'm thinking in the direction of the Raspberry Pi Pico, but I want to know which board. I think that the Raspberry Pi Pico has three serial ports, so I don't understand talking about the SoftwareSerial library.
If you are using the Raspberry Pi Pico, it has 2 hardware UARTs. Serial1 TX is labeled on the board GP0. Serial1 RX is labeled GP1. For other RP2040 boards, check the schematics or pin out diagram. The serial console (Serial) is actually a USB port so does not use a hardware UART.
If you are using an ESP32 Pico, it has 3 hardware UARTs but 1 is used for the serial console (Serial).
Hey Koepel, I have a raspberry pico, and now aware I don't need to use softwareserial. Thanks for pointing that out. I'm still pretty new in this world.
Thanks for your code. I will take a look at it and kee in mind that I don't need to use softwareserial as I'm using a raspberry pico. Lots to learn still.
Yes I'm using a raspberry pico. I got confused reding thru some other post I guess and thought I needed to use softwareserial, most likely I got mixed information from different posts.
I made it work following TMC library example at the end. I was really interested in the fastaccelstepper library but seems to not be compatible with raspberry pico unfortunately. I ended up just wiring the enable pin, to ground as per @monkeyfist suggested.
I will keep digging into and see if I can find a similar solution for me.
hey i have the same problem at the softwareserial library for raspberry pico and by your statement above so you don't need to include softwareserial in raspberry pico? sorry, im new to raspberry pico.