I want to drive up to 10 stepper motors at the same. All with a constant but individual speed. Meanwhile other calculations and data transfer is to be done.
All Steppers have their own driver with dir/step pin. I use AccelStepper for non blocking functions to run the steppers. It is very important that the steppers run as smooth as possible. First I simply put the runSpeed function for every stepper in the main loop, resulting in stuttering when data was written to the serial by the arduino. I now use Timer5 of the Mega to run a function that does nothing but call all runSpeed functions every 200 µs or so. This works very good with the steppers and the rest of the code except for the serial communication. I want to send commands to the arduino but with the interrupt being active some bytes never reach the arduino. Right now I am sending a notification byte that data will be transfered, the arduino answers and stops the interrupt, receives the command and starts the interrupt again. Works like a charm except for the 0.5 s stepper pause inbetween. This is to be solved.
Now I thought about the following: 1. Making the interrupt adoptable. Means: Track alls steps on every motor and calculate when a motor has to do the next step. Make the timer interrupt at exactly that time. Of course the interrupt has to be adjusted after every step of any motor. My fear is that the time demand for the calculations would be quite high, if not too high, so that the arduino gets stuck in interrupts and does not execute other code anymore. 2. Using a second arduino which only runs the steppers in the loop so the timing is no problem and serial data can be received. However, if I want that arduino to confirm the new settings to the main arduino, then I will get short pauses again... Solution would be to switch to interrupts when sending data, else use the main loop (sending data with interrupt works, receiving has the issue).
This is my idea of how to do it. But before I put all the effort in it, I wanted to discuss this with you and ask you, if you have another, better solution that for me.
I attached an exemplary code which with which the arduino cannot receive longer texts without missing bytes.
#include "AccelStepper.h"
#include "TimerFive.h"
AccelStepper m1(AccelStepper::DRIVER, 24, 25);
AccelStepper m2(AccelStepper::DRIVER, 26, 27);
AccelStepper m3(AccelStepper::DRIVER, 28, 29);
void setup() {
m1.setMaxSpeed(1000);
m2.setMaxSpeed(1000);
m3.setMaxSpeed(1000);
m1.setSpeed(50);
m2.setSpeed(70);
m3.setSpeed(90);
Timer5.initialize(250);
Timer5.attachInterrupt(run);
}
void run() {
m1.runSpeed();
m2.runSpeed();
m3.runSpeed();
}
void loop() {} {
//some calculations...
if (Serial.available() > 0) Serial.println(Serial.readString());
delay(1000);
}