I have successfully set up and used the Acelstepper library to move both motors on a BKA30D-R5/VID28 dual shafted stepper motor via 2 x TMC2208 stepper drivers and an Arduino Nano. I have incorporated a starting speed, acceleration speed and max speed for each motor (it handles deceleration automatically).
Either motor works fine, which is a good start, however, When both motors move at the same time, the max speed is lowered (presumably because commands are going to two motors instead of just one) but ultimately, I want the maxspeed of both motors to be the same regardless of one or two motors moving at the same time.
Is this possible?
For example, in my code, both motors spin at the same speed. However, when one hand stops (at the half way mark) the other hand increases speed, even though the max speed settings apply universally.
#include <AccelStepper.h>
// Define stepper motor pins
#define MOTOR1_STEP_PIN 3
#define MOTOR1_DIR_PIN 2
#define MOTOR2_STEP_PIN 7
#define MOTOR2_DIR_PIN 6
// AccelStepper objects for both motors
AccelStepper motor1(AccelStepper::DRIVER, MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
AccelStepper motor2(AccelStepper::DRIVER, MOTOR2_STEP_PIN, MOTOR2_DIR_PIN);
void setup() {
// Acceleration and speed for both motors
motor1.setMaxSpeed (4000);
motor1.setSpeed (3000);
motor1.setAcceleration(2000);
motor2.setMaxSpeed (4000);
motor2.setSpeed (3000);
motor2.setAcceleration(2000);
}
void loop() {
// Update target positions for both motors
int targetPosition = 30000;
motor1.moveTo(targetPosition);
motor2.moveTo(targetPosition-15000);
// Run both motors
motor1.run();
motor2.run();
// Check if both motors have reached their target positions
if (motor1.distanceToGo() == 0 && motor2.distanceToGo() == 0) {
// Both motors have reached their target positions
}
}
So basically you are exceeding the max speed a nano can handle. Are you using microstepping?
Obviously these modules are designed for clocks, where the hands normally move quite slowly. Faster motion would only be required during setting.
The AccelStepper documebtation says a 16MHz AVR processor cannot generate 4000 steps per second and do much of anything else, let alone 8000 SPS. Read the documentation in the library.
Thanks and apologies, I took out the microstepping for ease of reading the code but I can see it's caused an issue. I am using full one sixteenth microstepping, so the actual steps are much less. I will see what I can see in the library and adjust the figures too, to help get my head around it
Regardless, it always seems to spin slower when moving both hands, which ultimately is where my issue lays.
This happens if you set MaxSpeed too high. In this case the real speed depends on the speed of your processor ( cycle time of loop() limits the speed ). run() takes considerable time if a step is due ( about 200µs on AVR 16MHz ) If no step is due it is much faster. So cycle time is slower when both stepper need to create a step than only one.
You could try the MoTostepper class of my MobaTools library. Out of the box it can drive up to 6 stepper with 2500 steps/sec each ( on AVR/16MHz ). This is independent of the loop cycle time. If you need only 2 stepper this can be tuned by a #define in MobaTools.h to reach 4000 steps/sec for both steppers.
You can install MobaTools via the library manager. There is also pdf documentation file which will also be installed im the library directory.
MoToStepper supports acceleration and deceleration. But it is defined differently from Accelstepper. You will define the length of the acceleration ramp - that is the number of steps from standstill until it reaches the set speed ( and that's the same for deceleration ).
If you want to tune the max speed with only two steppers - this is the related #define in MobaTools.h:
#elif defined ARDUINO_ARCH_AVR ////////////////////////////////////////////////////////
//#define NO_TIMER3 // never use Timer 3
#define CYCLETIME 200 // Min. irq-periode in us ( default is 200 ),
With only 2 steppers you can set CYCLETIME to 120 to reach 4000 steps/sec for each.
I fairly new to Arduino, so struggling with this a little bit. I'm not entirely sure what RampLen does and I'm struggling to convert the loop from the accelstepper example (see below)
I'll keep reading and see what I can find
// Accelstepper Library alternative is called https://github.com/MicroBahner/MobaTools MoTo
// MobaTools (MicroBahner) in Arduino IDE Library Manager
// motor1.setSpeed (3000); - See if I can find equivilent command so that the motors/hands start quickly.
#include <MobaTools.h>
// Define stepper motor pins
#define MOTOR1_STEP_PIN 3
#define MOTOR1_DIR_PIN 2
#define MOTOR2_STEP_PIN 7
#define MOTOR2_DIR_PIN 6
// Define the stepper motor parameters
const byte stepsPerRevolution = 720; // Change this according to your motor specifications
const byte stepMode = 1; // Change this according to your motor driver microstepping setting
// Create MoToStepper objects for both motors
MoToStepper motor1(MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
MoToStepper motor2(MOTOR2_STEP_PIN, MOTOR2_DIR_PIN);
void setup() {
// Set speed for both motors
motor1.setSpeed(3000);
motor2.setSpeed(3000);
// Set acceleration for both motors
motor1.setRampLen(2000);
motor2.setRampLen(2000);
}
void loop() {
// Update target positions for both motors
int targetPosition = 30000;
motor1.moveTo(targetPosition);
motor2.moveTo(targetPosition - 15000);
// Run both motors
motor1.update();
motor2.update();
// Check if both motors have reached their target positions
if (motor1.motionComplete() && motor2.motionComplete()) {
// Both motors have reached their target positions
}
}
Here same changes to your sketch to change it for using MobaTools. It compiles, but I cannot test it at the moment:
// Accelstepper Library alternative is called https://github.com/MicroBahner/MobaTools MoTo
// MobaTools (MicroBahner) in Arduino IDE Library Manager
// motor1.setSpeed (3000); - See if I can find equivilent command so that the motors/hands start quickly.
#include <MobaTools.h>
// Define stepper motor pins
#define MOTOR1_STEP_PIN 3
#define MOTOR1_DIR_PIN 2
#define MOTOR2_STEP_PIN 7
#define MOTOR2_DIR_PIN 6
// Define the stepper motor parameters
const int stepsPerRevolution = 720; // Change this according to your motor specifications
//const byte stepMode = 1; // Change this according to your motor driver microstepping setting
// Create MoToStepper objects for both motors
MoToStepper motor1( stepsPerRevolution, STEPDIR );
MoToStepper motor2( stepsPerRevolution, STEPDIR );
int targetPosition = 30000;
void setup() {
// attach step and dir pins
motor1.attach(MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
motor2.attach(MOTOR2_STEP_PIN, MOTOR2_DIR_PIN);
// Set speed for both motors ( speedSteps is defined in steps/10sec )
motor1.setSpeed(25000); // max without changing CYCLETIME in MobaTools.h
motor2.setSpeed(25000);
// Set acceleration for both motors
motor1.setRampLen( stepsPerRevolution ); // max speed is reached after 1 revolution
motor2.setRampLen( stepsPerRevolution );
// setting target position needs to be done only once
// motors will start immediately
motor1.moveTo(targetPosition);
motor2.moveTo(targetPosition - 15000);
}
void loop() {
// both motors are starting dirctly after moveTo - no additinal calls needed
//motor1.update();
//motor2.update();
// Check if both motors have reached their target positions
if (!motor1.moving() && !motor2.moving()) {
// Both motors have reached their target positions
}
}
I had just finished my version but it wasn't moving the hands at all but yours is amazing, just how I wanted it to work.
I've just realised that I have microstepping switched on (as it's hard wired into my PCB) so the length of time to get to full speed and to slow down from full speed need to be tested more carefully! (that's my task!). I will also study the code and compare to mine, so I can better understand it
What a privilege, speaking to the person that created the library
One thing I have noticed, is that the setSpeed commands do not seem to be working well. For example, if I set:
// Set speed for both motors ( speedSteps is defined in steps/10sec )
motor1.setSpeed(25000); // (25000) is the max without changing CYCLETIME in MobaTools.h
motor2.setSpeed(1000);
... both hands seem to move at exactly the same speed. Am I doing something wrong ?
Oh sorry, I have been to fast when changing the sketch from Accelstepper to MobaTools. Unfortunately setSpeed is interpreted differently by MotoStepper. setSpeed defines the speed in rpm*10. The corresponding method to define the speed in steps is setSpeedSteps:
motor1.setSpeedSteps(25000); // (25000) is the max without changing CYCLETIME in MobaTools.h
motor2.setSpeedSteps(1000);