Hi. I'm making a simple 4-axis vacuum sealed robot on scara kinematics to perform simple pick&place operations. The pick&place position is controlled by three stepper motors, orientation is controlled by servo. Now I need to write the firmware for Arduino. I would like all three stepper motors to start and end their movement to the desired position at the same time. They will need to go through different number of steps accordingly. Are there any libraries designed for this? I know about MultiStepper, but as far as I understand it doesn't support acceleration.
define what you mean by same time. exact nanosecond or a few milliseconds difference is fine ?
AccelStepper supports acceleration.
MultiStepper works in conjunction with that library to operate multiple AccelSteppers in a coordinated fashion but indeed is constant speed only.
You could look at MobaTools. I think it supports synchronized operation of multiple steppers.
The mechanical speed (millis) of servo's is another order of magnitude than a processor (micros), and there might even be different physical tolerances per servo.
So just setting them (in code) in a sequence should meet most requirements.
Did you try that, did it work or what problems did you encounter?
I mean few milliseconds difference is fine. Thank you for reply.
I asked about stepper motor control not servo.
oops sorry
what do you mean "controlled by servo"?
presumably you want the 3 stepper motors to arrive at their destination at the same time. One approach is to determine which had the largest # of steps, the master and calculate the fraction of step for the others. accumulate the fraction of the steps for the other and step when when the accumulated step > 1 and subtract 1 from the accumulated value
I mean that gripper is rotated by servo.
Some folks try computing the speeds and accelerations to synchronize the travel times, but it is very complicated to keep synchonization through the transitions from accelerations to cruising and back.
One trick to handle acceleration and coordinated movement is to control the acceleration of the fastest axis and schedule the slower axes to step in strict ratios to the fast axis. That's how CNCs and 3d printers solve the problem--separate it into coordination with the Bresenham algorithm, and once you've identified the fast axis, do the acceleration on the fast axis.
It can be done but is it worth the work?
Which? The sychronized recomputing of the travel times?
I don't think it is worth the work. For each axis you have to scale the accelerations and maximum speeds to the fast axis, and it takes several (imprecise) floating point math operations with squares and square roots. And then (assuming AccelStepper) it has to recalculate motion based on those imprecise values.
It's better to do one acceleration/decel timing calculation and then step the slower axes as needed. Or that's what all the 3DP and CNC developers think.
I'd start by changing angle to slope, which can be tabled.
Knowing slope, accel and decel can be scaled one to the other.
It's worth it if someone pays for the work. I lived by that for many years.
Unfortunately not (yet) .
[OffTopic] I'm planning to add synchronized movement with acceleration in one of the next releases. I have a rough imagination how to implement it, but have to check if it really works that way. There is no code so far, only the idea (and little time ). The main challenge is not to place an additional load on the ISR, especially for the slower MCUs. So it will definitely still last some time until this will be released. Also support for the pi pico is at the ToDo list. Let's see what will come first.
[/OffTopic]
A wrist rotates. A gripper squeezes.
Here's simultaneous start and stop motion of 32 motors using the Bresenham algorithm (the starting and stopping position vectors are randomly generated by the red channel of a FastLED animation):
The speeds are a constant-speed set by the constant msPerStep=3
. Adding acceleration would need management of the interval.
And a 6-axis GCODE interpreter simulation:
Here's a substitute to Accelstepper's stepper.step() function that indicates if a stepper actually made a step so it could be used for triggering steps on other axes:
class myAccelStepper : public AccelStepper
{
public:
boolean myAccelStepper::stepAsNeeded()
{
// step as needed and return whether or not it stepped
bool stepped = false;
if (stepped = runSpeed())
computeNewSpeed();
return stepped;
}
using AccelStepper::AccelStepper;
using AccelStepper::setMaxSpeed;
using AccelStepper::moveTo;
};
And a demo of using it to slave a second stepper to half-speed:
If you can know when the one fast axis does a step, you can slave a lot of cheap bresenham-ratio-controlled axes to the fast axis for coordinated motions.
The FastLED/32 stepper motion in the top simulation sets up a synthetic dummy axis with the fastest motion, and then uses that to drive motion of all the rest.
I forgot about the TeenyStep library.
It advertises synchronous movement of 10 axes with acceleration. It uses Bresenham under the hood. I haven't played with it.
Ah damned - I thought it would…
Its actually not trivial since you can’t have various accelerations/deceleration and max speed for each stepper and at the same time have synchronized arrival.
You have to relax some expectations or add some constraints to the accelerations.
LOL. By that criterion nothing I do is worth it.
a7
In MobaTools, it might be less trivial / more not-trivial, because accelerations are handled by ramping in space/steps rather than in time. If your fast axis ramps up to cruising speed in 100 steps, then your 1/7th speed axis has to ramp up in 14+ steps.
Ratio is scaling.
A 16-bit sine lookup table assumes radius=10000 to 60000 and sine is value that divides by R. Cosine is sin(90-angle).
Those give Y and X to inverse scale time per step to get angle. That way, integer math works as long as your units are small enough.
Take a look at that TeensyStep library & its 160000steps/sec video synchronizing two different speed. Bresenham's integer math with successive additions and subtractions works to synchronize a 1:160000 angle/ratio (or even a 2^31:1 ratio) precisely.
How precise does the sine table need to be/how small would the units need to be to make 160000 time intervals add up precisely to 1?