[Dprglist] motion profiling with stepper motors
Ron Grant
deltagraph at aol.com
Sun Mar 25 10:31:32 PDT 2018
Ahh, there Jose said I assume same thing "Step Scheduling" and with that multiple timers might be required, but at least multiple output compare registers tied to same counter. On many microcontrollers there will be 3 or 4 registers which can toggle and output pin tied to the same timer.
Ahh, and of course, I forget someone else has solved this problem (but where is the fun in that?) ... very good, Jose, did not know about GRBL
-----Original Message-----
From: Jose Quinones <avayanings at gmail.com>
To: markus <markus at bibi.ca>
Cc: Ron Grant <deltagraph at aol.com>; DPRG <dprglist at lists.dprg.org>
Sent: Sun, Mar 25, 2018 6:53 am
Subject: Re: [Dprglist] motion profiling with stepper motors
Hi Markus,
If this is for a CNC machine then you need to make a step scheduler.
I imagine you know of GRBL, right? That is the CNC code pretty much all 3D printers are based from. Basically it has a GCode interpreter which then uses timers to schedule the step profile with acceleration and deceleration curves embedded into them. This is not about a stepper anymore or about a stepper moving at this speed or that other speed. This is about a tool (i.e. a cutter, filament, water jet, laser beam, etc) being in the position XYZ at time T. As you can imagine there is some kinetic math involved.
The point is that when the command is received (say G0 X1.234 Y0.987 Z-0.456), the controller knows where it is and where it needs to go. At that point, math is used to determine the distances each axis needs to traverse and the system imposes the acceleration/deceleration curves into each stepper profile. If I recall from previous discussions (albeit too long ago, I am afraid), then a timer with high resolution is set loose and the STEP/DIR signals bit banged accordingly. The reason why you would use a single timer as opposed to multiple timers (e.g. one per axis) is that in this fashion you can ensure each stepper is where it needs to be at the right time. Like I said, this is not about a stepper anymore. It is about the position of the tool in 4 dimension spatial/time coordinates.
Just stirring the pot even further ;-)
Best regards,
JIQ
On Sat, Mar 24, 2018 at 9:50 PM, markus <markus at bibi.ca> wrote:
Hi Ron,
that makes sense and I see the wisdom behind your approach. The problem
is I need stepper frequencies way beyond 10kHz and I have multiple
steppers which will have to work in concert. Basically controlling
multiple axis of a CNC machine.
Coming to a stop at a specific location with a set deceleration is what
I'm looking for. The important part is that the "stopping" should
happen in a fully controlled manner - aka. smooth. So it doesn't just
matter where I end up, it also matters how I got there.
I had missed your question:
> > >> 1ms later we could/should set the frequency to 10Hz but that's
> > >> not possible because the period of one 5Hz cycle is 200ms.
> > You mean 10ms later... right?
Unfortunately I did mean 200ms - which is the crux of the problem.
Issuing a single 5Hz pulse takes 200ms which means I can't set a new
value before those 200ms are up.
But maybe I'm overthinking the problem.
Markus
On Sat, 24 Mar 2018 21:24:36 -0400
Ron Grant <deltagraph at aol.com> wrote:
> Markus, coming to a stop at a specific point (or count) is the beauty
> of the high frequency interrupt routine approach that I use. The
> routine decides if it is going to take a step and in a final ramp
> down it can ask if it has reached its terminal count. If so, the
> motion is done.
>
> In your case, might get a bit tricky. At a given update you might
> have to ask the question. Where will I be next update and what I need
> to do to insure the correct count? Hmm.
>
> In my step rate world, I can simply apply linear ramp functions to
> like StepRate+=Accel at given time step and also ask questions like
> have I exceeded max velocity, if so clip StepRate or have I passed
> 1/2 way point to terminal count or have I reached count where I need
> to start decelerating step rate to reach correct terminal count at
> about correct time with final fudge near end to drop velocity to zero
> when I have reached final count.
>
> OK, that begs the question, if you setup (or have) an interrupt
> routine fire when counter generates step pulse. You could have that
> routine ask, am I at the final step count. If so, don't allow anymore
> steps. This will eliminate the headache of trying to calculate
> exactly what to do with your deceleration or so I say.
>
> Ron Grant
>
>
>
>
>
>
> -----Original Message-----
> From: markus <markus at bibi.ca>
> To: Ron Grant <deltagraph at aol.com>
> Cc: dprglist <dprglist at lists.dprg.org>
> Sent: Sat, Mar 24, 2018 7:40 pm
> Subject: Re: [Dprglist] motion profiling with stepper motors
>
> Jose, Ron, thanks for your feedback those are great implementation
> pointers.
>
> I did implement both approaches but have trouble with the wall clock
> approach (update the frequency periodically regardless if the
> previous update has ever been applied). Accelerating is fine the
> issue is with deceleration and coming to a halt at a specific point.
>
> In the linear world the distance where I have to start constant
> deceleration is defined by: S = V^2 / (2 * a)
>
> V ... current velocity
> A ... constant deceleration
>
> And again this works fine as long as the update frequency is faster
> than the step frequency, but once the step frequency drops below the
> update frequency I can't reduce the speed fast enough (because the
> timer only updates on overflow).
>
> What happens is that the stepper is still turning quite fast by the
> time the robot reaches its target position.
>
> Does anybody know how the math works here?
>
> Any pointers appreciated, thanks,
> Markus
>
>
>
> On Tue, 20 Mar 2018 16:36:02 -0400
> Ron Grant <deltagraph at aol.com> wrote:
>
> > Markus,
> > I am not a stepper expert by any means...
> >
> > >> 1ms later we could/should set the frequency to 10Hz but that's
> > >> not possible because the period of one 5Hz cycle is 200ms.
> > You mean 10ms later... right?
> >
> > I think you might be having trouble due to (as you realize) trying
> > to vary a speed where number of steps per update interval is very
> > low (less than one in your case).
> >
> > Wonder if you could be helped by using micro-stepping to increase
> > apparent stepper resolution? OR are you already micro-stepping? If
> > not, your 5Hz cycle might become with 16X microstep 80 Hz giving you
> > ability to control slower rates more gracefully even if stepper does
> > not perfectly track the micro step positions -- fancy controllers
> > and encoders help do that as far as I know.
> >
> > Maybe there is an elegant solution to calculate just what your
> > interval needs to be.
> >
> > My first thought would be to linearly ramp your expected pulse
> > timing every 10ms then force a step if need be. That is at time
> > zero you set 100 ms as the width but at update 1 (10ms later) your
> > goal is 50 ms pulse width (with 5Hz/10ms accel. rate), so you force
> > a step and reset timer. At update 2 your goal would be 25ms but
> > only 10 ms elapsed so no intervention...
> >
> > Just for fun (whether right or wrong way to do things) :
> >
> > My preferred way to handle steppers is with a 10 KHz interrupt that
> > can decide what the step frequency is going to be with 1Hz
> > resolution. Grainy when step rates are very low, but seems to work
> > well. 10 KHz might be too much for slower clock speed / 8 bit MCU,
> > not using any fancy timer stuff (just periodic interrupt)
> >
> > code for part of 10KHz interrupt routine - for left motor below
> > Note TimeL is 32 bit int
> >
> > using step and direction driver, e.g. something like DRV8825
> > not show is update that calculated StepRateL(and R) for differential
> > drive robot at say 100 Hz.
> >
> > TimeL += abs(StepRateL);
> > if (TimeL>10000)
> > {
> > TimeL -= 10000;
> > StepMotorDirL = (StepRateL>0); // set DIR pin REVERSE L
> > if (StepRateL<0) MotorL--; else MotorL++; // virtual encoder
> > count (volatile long int) StepMotorStepL =
> > 1; // manually generate a step
> > pulse wait_us(4); StepMotorStepL = 0;
> > }
> >
> > Of course you could use a timer to implement step rate, but take
> > care in adjusting rates where you might shorten an interval to a
> > count that the counter is beyond...
> >
> > Ron Grant
> >
> >
> >
> > -----Original Message-----
> > From: markus <markus at bibi.ca>
> > To: DPRG <dprglist at lists.dprg.org>
> > Sent: Tue, Mar 20, 2018 12:53 pm
> > Subject: [Dprglist] motion profiling with stepper motors
> >
> > I started playing around with motion profiling and thought using a
> > stepper was easier for experimenting. I've implemented "constant
> > acceleration" and started to wonder what the correct implementation
> > is when the stepper frequency is below the update frequency.
> >
> > Let's say motion profiling updates the frequency every 10ms and the
> > acceleration limit is set to 5Hz/10ms. So at the initial update the
> > frequency is set to 5Hz - 1ms later we could/should set the
> > frequency to 10Hz but that's not possible because the period of one
> > 5Hz cycle is 200ms.
> >
> > So the question I have is what is the correct value to update the
> > timer at the end of those 200ms?
> > - 10Hz
> > - 100Hz
> >
> > Both seem wrong, if I set it to 10Hz it's not really "constant
> > accelleration" at low speeds from a wall clock perspective. And if I
> > set it to 100Hz I might exceed the "constant accelleration" from the
> > motors perspective.
> >
> > Comments, thoughts?
> > Markus
> > _______________________________________________
> > DPRGlist mailing list
> > DPRGlist at lists.dprg.org
> > http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org
> >
> >
>
>
_______________________________________________
DPRGlist mailing list
DPRGlist at lists.dprg.org
http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dprg.org/pipermail/dprglist-dprg.org/attachments/20180325/4dafcb7a/attachment.html>
More information about the DPRGlist
mailing list