EEVblog Electronics Community Forum

Computing => Programming => Topic started by: meba on April 09, 2021, 06:50:23 pm

Title: Synchronize stepper motor movement
Post by: meba on April 09, 2021, 06:50:23 pm
Hi,
I am using the AccelStepper Library to control three motors. Now I want to synchronize the movement of these stepper motors.

All of the motors have a fixed acceleration and a maximum speed. The distance they have to travel is always different. Now I want to make sure that all the motors start and stop their movement at the same time. Therefor I want to calculate the time how long each of the motors would need to reach their destination. In the next step I want to increase / decrease the maximum speed of motor 2 and motor 3, so they need the same time to reach their destination as motor 1 does.

At the moment I am ignoring the acceleration and just assume that it moves with a constant velocity, but this is just a rough approximation and causes the motors to stop at a slightly different time.

My idea would be, that I need to calculate how long the motors take to reach their maximum speed, calculate how far they move during the acceleration process, then do the same with the deceleration. Now I can check how much distance is left, where the motor will move with a constant velocity, and calculate this time as well. Now I can compare the times and have a more precise time estimation. However, since this is no linear function, I can not simply use a multiplicator to increase / decrease the speed of the other axes. So this seems like a really inefficient solution with a lot of trial and error to get the desired result.

Is there another solution to my problem? A library or maybe a function I am not aware of?
Title: Re: Synchronize stepper motor movement
Post by: langwadt on April 09, 2021, 07:40:36 pm
https://github.com/gnea/grbl/
Title: Re: Synchronize stepper motor movement
Post by: DiTBho on April 10, 2021, 09:53:33 am
https://github.com/gnea/grbl/

Good find!
Title: Re: Synchronize stepper motor movement
Post by: beanflying on April 10, 2021, 11:05:13 am
Lots of options but all would be best resolved by treating them as separate drives. Also 'TIME' is not a good measure of amount of movement but 'Calibrated Step Count' is. Time to max speed and acceleration is controlled by a bunch of unspecified (by you) variables such as weight (mass of what is moving), direction (with or against gravity), resistance of that mass from the slides/bearings or whatever etc..... so time will never be truly accurate.

So Calibrated counting of steps relies on no skipped or missed steps (correctly sized stepper and adequate current and driver) then calibration for distance of travel against a known number of steps to get this value.

Have a look locally for a 3D Printer board and use a slightly tweaked version of the likely Marlin version of GRBL and it should already have built in a fixed move option. So all you need to do is change it to move all three as one.

Arduino Mega and a Ramps board and Stepper drivers. Now a bit old school but works well.

MKS (combined Arduino and Ramps board more or less) plenty on evilbay for not much.

So unless I have got your plan wrong  ;) (possible) look at these sorts of solutions and if nothing else play lots and learn as you go.
Title: Re: Synchronize stepper motor movement
Post by: DiTBho on April 10, 2021, 11:08:56 am
Better to find something out from the arduino forum regarding the library or funtion of it

In my case I do not like Arduino, but I like to have examples, and I am willing to rewrite that code entirely, so it's a good "get started" material  :D
Title: Re: Synchronize stepper motor movement
Post by: meba on April 10, 2021, 04:55:44 pm
Thanks for all the suggestions so far!

I think I should give you some more information. I made a motorized 3-axis camera slider. It uses a custom PCB with an ESP32, some A4988 motor drivers and an OLED display. It is being operated with a PS4 controller. Therefore using a 3D-printer board is not an option.

Originally I only planned to read the input of two joysticks and move the motors accordingly. Later on I also wanted to program in a start- and end point to move back and forth between these positions two positions.

Since the slider is already up and running, I would prefer to do some improvements to the current firmware, instead of starting again from scratch. If the timing of the axes is not 100% perfect that's fine, I just want to improve the timing by taking the acceleration into account.

If someone wants to have a look at the current firmware, I attached all of the Arduino files. I hope the code is not too messy - this was the most complex project I did so far and I've learned a lot while working on it.
I was not allowed to upload the .ino files, so I had to zip the folder.

_____
edit:
I realised the Accelstepper library also has a class called "Multistepper". I never understood what is different about this class, but this might actually be exactly what I am searching for. I have to take a closer look at it.
Title: Re: Synchronize stepper motor movement
Post by: DiTBho on April 10, 2021, 07:26:23 pm
PS4 controller

PS4? wow, that's a wireless joy-pad. I haven't yet played with it, but many years ago, when there wasn't yet any documentation about the Playstation1 (~1999) I did something similar with the PS1' pad. I still remember when I found it was somehow similar to the SPI protocol, but not exactly the same, but enough similar to be managed with primitive LA to decode the minimal protocol (digital(X,Y), analog(X,Y), and buttons)

Great days  ;D

Good choice, This reminds me I definitively have to play with the PS4' pad. Some day ...
Title: Re: Synchronize stepper motor movement
Post by: beanflying on April 10, 2021, 08:23:26 pm
Take a look at this build from one of my regular youtube watches, bound to be lots more out there and also. Project files https://www.youmagine.com/designs/diy-arduino-based-motorized-dslr-camera-slider-with-lcd-screen#information (https://www.youmagine.com/designs/diy-arduino-based-motorized-dslr-camera-slider-with-lcd-screen#information)

I ran across this Github code you might like to glance at for ideas https://github.com/RJ-Make/OpenSlider (https://github.com/RJ-Make/OpenSlider)

Title: Re: Synchronize stepper motor movement
Post by: meba on April 10, 2021, 08:55:03 pm
PS4? wow, that's a wireless joy-pad. I haven't yet played with it, but many years ago, when there wasn't yet any documentation about the Playstation1 (~1999) I did something similar with the PS1's pad. I still remember when I found it was somehow similar to the SPI protocol, but not exactly the same, but enough similar to be managed with primitive LA to decode the minimal protocol (digital(X,Y), analog(X,Y), and buttons)

Fortunately there is a library called PS4-esp32 which does all the hard work, I wouldn't have been able to figure this out by myself :D

Take a look at this build from one of my regular youtube watches, bound to be lots more out there and also. Project files https://www.youmagine.com/designs/diy-arduino-based-motorized-dslr-camera-slider-with-lcd-screen#information (https://www.youmagine.com/designs/diy-arduino-based-motorized-dslr-camera-slider-with-lcd-screen#information)

I ran across this Github code you might like to glance at for ideas https://github.com/RJ-Make/OpenSlider (https://github.com/RJ-Make/OpenSlider)

Thanks for the video suggestion, I also follow him on youtube. Unfortunately his slider only uses one motor, so there is no need to sync multiple motors.

I changed my software to use "Multistepper" which syncs the motors so they stop at the same time. Unfortunately this library does not work with acceleration - it just jumps straigt to full speed. This causes problems with higher speeds and overall it doesn't look as smooth.
So I am back to my original version, with acceleration, but slightly out of sync movement.
Title: Re: Synchronize stepper motor movement
Post by: beanflying on April 11, 2021, 02:05:26 am
I haven't used that library so I just google'd it for a bit of a look and this turned up https://forum.arduino.cc/index.php?topic=424509.0 (https://forum.arduino.cc/index.php?topic=424509.0) and the link to AccelStepper http://www.airspayce.com/mikem/arduino/AccelStepper/files.html (http://www.airspayce.com/mikem/arduino/AccelStepper/files.html)

If you have a long run on one axis then take a look at this instead of running belts. It will make packdown and transportation so much easier as the rest of the gantry/gimbal could be removable with no tools. https://www.eevblog.com/forum/mechanical-engineering/rack-and-pinion-solution-for-v-slot-aluminium/msg3544565/#msg3544565 (https://www.eevblog.com/forum/mechanical-engineering/rack-and-pinion-solution-for-v-slot-aluminium/msg3544565/#msg3544565) Concept implementation below.
Title: Re: Synchronize stepper motor movement
Post by: meba on April 11, 2021, 12:29:53 pm
I haven't used that library so I just google'd it for a bit of a look and this turned up https://forum.arduino.cc/index.php?topic=424509.0 (https://forum.arduino.cc/index.php?topic=424509.0) and the link to AccelStepper http://www.airspayce.com/mikem/arduino/AccelStepper/files.html (http://www.airspayce.com/mikem/arduino/AccelStepper/files.html)

If you have a long run on one axis then take a look at this instead of running belts. It will make packdown and transportation so much easier as the rest of the gantry/gimbal could be removable with no tools. https://www.eevblog.com/forum/mechanical-engineering/rack-and-pinion-solution-for-v-slot-aluminium/msg3544565/#msg3544565 (https://www.eevblog.com/forum/mechanical-engineering/rack-and-pinion-solution-for-v-slot-aluminium/msg3544565/#msg3544565) Concept implementation below.

The Multistepper class is what I tried in the meantime. While it manages to synchronise the speed of the motors, it does not support acceleration and jumps straigt to full speed, which just causes more problems.

The rack an pinion solution looks nice and I will keep it in mind for future projects. The mechanical design of the slider is already finished and works fine with a belt.
Title: Re: Synchronize stepper motor movement
Post by: beanflying on April 11, 2021, 01:39:24 pm
Having a quick flick through the AccelStepper.h having a good read of the comment lines if nothing else might be worth it for you. So rather than use it as a Library see if there is bits of the Acceleration code in particular to incorporate into the Library you are already using?  Also make http://www.airspayce.com/mikem/arduino/AccelStepper/AccelStepper_8h_source.html (http://www.airspayce.com/mikem/arduino/AccelStepper/AccelStepper_8h_source.html)

While I get the ease of Libraries and I use them a lot sometimes doing it from scratch or hacking them is the right solution too  :)
Title: Re: Synchronize stepper motor movement
Post by: rstofer on April 11, 2021, 08:01:37 pm
Apparently, you don't care about the exact path taken so 2D interpolation isn't required.  This isn't a CNC problem.

I would look at the relative displacements and set the axis with the largest displacement to run at full speed.  I would then calculate the other axis as some percentage of full speed based on its relative displacement.  I'm assuming that the control will eventually get to the proper endpoint.  It would probably be important to run out the small move before the large move.  Getting both axes to the end point simultaneously might not be all that important.

If you care about the exact, step-by-step, motion, then you need some kind of CNC style interpolation and that kind of stuff is all over the Internet.
Title: Re: Synchronize stepper motor movement
Post by: giacy86 on August 06, 2021, 07:50:19 am
Hi,
I am using the AccelStepper Library to control three motors. Now I want to synchronize the movement of these stepper motors.

All of the motors have a fixed acceleration and a maximum speed. The distance they have to travel is always different. Now I want to make sure that all the motors start and stop their movement at the same time. Therefor I want to calculate the time how long each of the motors would need to reach their destination. In the next step I want to increase / decrease the maximum speed of motor 2 and motor 3, so they need the same time to reach their destination as motor 1 does.

At the moment I am ignoring the acceleration and just assume that it moves with a constant velocity, but this is just a rough approximation and causes the motors to stop at a slightly different time.

My idea would be, that I need to calculate how long the motors take to reach their maximum speed, calculate how far they move during the acceleration process, then do the same with the deceleration. Now I can check how much distance is left, where the motor will move with a constant velocity, and calculate this time as well. Now I can compare the times and have a more precise time estimation. However, since this is no linear function, I can not simply use a multiplicator to increase / decrease the speed of the other axes. So this seems like a really inefficient solution with a lot of trial and error to get the desired result.

Is there another solution to my problem? A library or maybe a function I am not aware of?

Hi all, i'm Giacinto from Italy and congratulations for this forum.
I have created a similar project, a 3 axis slider with acceleration/deceleration with the AccelStepper library and i had the same problem as you.
I, however, have complicated my life by adding multiple keyframes and I have yet to finish it also because I have provided also a loop function.
However, if you use a start and an end point and (as AccelStepper works) the acceleration is the same as the deceleration, you have to manipulate the formulas of uniformly accelerated rectilinear motion. Even if it is an approximation (stepper motion is not exactly as uniformly accelerated rectilinear motion) I have tested it and it works very fine.

So, the total time for a steppers with a maximum velocity v (AccelStepper.setMaxSpeed(v)), an acceleration a (AccelStepper.setAcceleration(a)) and a total space of s steps (for example AccelStepper.targetPosition() - AccelStepper.currentPosition() calculated before start the movement) is:

Code: [Select]
`t = (s/v) + (v/a)`
Now you want other steppers to have the same time of one stepper, for example the slider axis, so you use inverse formulas to find the maximum speed and acceleration.
I have simplified a lot using an acceleration twice the maximum speed:

Code: [Select]
`a = 2v`
So the total time become:

Code: [Select]
`t = (s/v) + (1/2)`
the maximum speed of other steppers become

Code: [Select]
`v = s / (t - 1/2)`
and the acceleration of other steppers

Code: [Select]
`a = 2v`
Note that obviously for other steppers you have to calculate the total travel space.