Some time ago I wrote a small Arduino program to control 3 stepper motors on my small lathe in a coordinated way. By coordinated I mean that if the three motors are required to move, say, 500, 322 and 18 steps respectively then there would be significant differences in the intervals between steps so that each motor completes its move in exactly the same time. For example if the total time for the move is 500 millisecs then the first motor will make a step every millisec; the second motor will make a step every 1.552 millisecs; and the third motor will make a step every 27 millisecs.
That Arduino program operated all the motors at constant speed without any acceleration.
One shortcoming with the arrangement is that some of the range of movement of the lathe cross-slide must be excluded because the friction in that area causes the motor to miss steps. I proved to my satisfaction that acceleration would get around this problem by writing a short program just using AccelStepper on the cross-slide axis.
However the AccelStepper library is not designed for coordinated movements. And while the MultiStepper variant of the library is designed for coordinated movements, it does not use acceleration.
While wondering how I could manage acceleration on all three axes (possibly with my own acceleration code) it occurred to me that one axis will always have the fastest (or equal fastest) step rate and it would be sufficient to apply acceleration to that axis if the movements of the other axes could be “slaved” from the movements of the fastest (or master) axis. For example, using the above figures, the second motor needs to take a step after every 1.552 steps of the first motor, and the third motor needs to take a step after every 27 steps of the first motor.
If I only need to calculate acceleration for one axis then I can use the AccelStepper library.
To make the maths easy for the Arduino I decided to calculate the lowest common multiple for the moves. Using the above figures this gives 500 * 322 * 18 or 288,000 and, from that calculate an increment-per-step for each motor. The values are 576, 894 and 16000.
I can use the AccelStepper distanceToGo() function to identify whenever a step is taken by the master motor and when that happens I increment a master counter by (in this case) 576. By checking the value of the master counter I can tell when to make the other motors step. For example when it exceeds 894 it is time to make the second motor step and when it exceeds 1788 it will be time to make the second motor take another step.
The code in the next Reply is a simple demonstration of this which works very nicely for me.
(Please keep in mind that this is my rough development code with a minimum of tidying up).
Comments etc are welcome