Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Maintain a spindle running after a motion script has finished
I am running RS274 part programs as motion scripts on a Power PMAC. I have a rotary axis that can be controlled either as a positioning axis or as a spindle. If I start the axis moving as a spindle (an M03 or M04) when the motion script ends, the spindle also stops. Can you advise on a method of leaving the spindle running on exit of the motion script ?
Usually we get the opposite question -- "How do I make sure my spindle stops when my part program ends?"

To move the axis as a spindle, it cannot be set up at that time as a positioning axis in the same coordinate system as the (remaining) positioning axes. When this is the case, there is nothing that automatically stops the spindle when the motion program ends. So we need to understand exactly how you are commanding your spindle axis here, because it seems that you would need to take explicit action to stop the spindle at the end of the motion program.

Many users embed the functionality of the M05 spindle-stop code inside their M01 or M30 end-of-program code to ensure that the spindle stops when the motion program does, even if an M05 is "forgotten". Has this been done in your case?

There are several strategies people use for setting up the spindle axis when it can also be a positioning axis.

One strategy is to assign the motor to an axis into a separate coordinate system, where it can be commanded by a separate motion program. For example, if as a positioning axis in C.S. 1 it had the definition #4->C, you would first give it the "null" definition in C.S. 1: #4->0. Then you could assign it to an axis in another coordinate system, e.g. &2 #4->C. This is somewhat cumbersome, but having it as an axis in a separate coordinate system capable of running its own motion program facilitates features such as constant surface speed.

A second strategy is just to give the motor the null definition in the same coordinate system as the positioning axes. This permits the motor to be jogged or commanded in open loop mode while the positioning axes are executing the part program. Having it in the same coordinate system provides automatic fault sharing (which most users want), and shared time-base (%) values (which some do not want).

A third strategy, new in the V1.4 firmware released this past summer, is to assign the motor explicitly as a spindle axis in the same coordinate system as the positioning axes. This is similar the the null-definition strategy in that you can command the motor in closed-loop (jog) or open-loop mode even while the positioning axes are executing a motion program, but it has a couple of important advantages. First, it gives you several choices as to the % override value. If you define it as #x->S, it uses the same % value as the positioning axes. If you define it as #x->S0, it uses C.S.0's % value. If you define it as #x->S1, it uses a fixed 100% override.

The second advantage of this feature comes if you are using the buffered lookahead function. The buffer is structured based on the number of motors assigned to axes in the coordinate system when the buffer is defined -- there is one "column" in the buffer for each such motor. If you change the number of motors assigned to axes in the C.S., as when you go between a null definition or a definition in another C.S. and a positioning axis in this C.S., you must delete and redefine the lookahead buffer, which can be cumbersome. However, a motor assigned as a spindle axis in the C.S. retains a column in the lookahead buffer, but it is not used for this definition.

Note that in all of these strategies, there is nothing that automatically stops the spindle motion when the part program for the positioning axes ends.
Curt, since we intend to use buffer lookahead, we are using the ->s mechanism for controlling spindles.

At the start of an RS274 part program the C axis (motor 1) is set to a positioning in the CS used for RS274 i.e. &1#1->200c.

If I try the following RS274 part program:

M03 -> Here we turn the motor to spindle mode i.e. &1#1->s0 as we use CS0 for Spindle Speed Override.
G04 X5
M02 -> Here we perform an abort to end the program
G04 X2

The abort in the M02 also stops the spindle. We need to be able to potentially load a new part program so we need the CS to be put in a state by the M02 so that this can happen, but I can't find a way of doing this while leaving the spindle moving.

Any pointers much appreciated.

The "abort" command is intended for abnormal program terminations, as in fault conditions. That is why it stops every motor in the coordinate system, including those not assigned to positioning axes.

When a motion program or one of its subprograms executes a "stop" command, program execution is halted and the program counter is to the beginning of the top level program, as if it had gotten to the end of the program. At this point, if you want to open the part program to replace it, you can either force the program counter to a different program (e.g. "&1b2") or effectively reset the pointer with a "cpx return" command. Now in either case, you can open the program buffer you were running to download a new part program. Of course, you could also load the new part program into a program buffer with a different number, then set the program counter to it with the b command. Some users do this so they can download the next part program while the present program is still executing, saving a little time.
Thanks, that certainly improves matter, although there is still an issue. Using stop rather than abort in M02 certainly leaves the part program running. I think, however, we started using "abort" to be consistent with controlling the part program from a background C program. I didn't write this code and the engineer concerned is on his Christmas holiday already, so I can't provide all the details. However we have a requirement that we can stop a part program on user interaction at any point in the program. This is currently done by sending an "a" on-line command. In looking at the manual, I can't find an on-line equivalent of "stop". Is there such a command to perform this type of function.
Once again, I emphasize that the "abort" command is intended for abnormal program termination, as with a fault. In general, it will not stop at a programmed point, and will not decelerate to a stop along the programmed path.

The on-line "q" command stops any further program calculations, and allows the already calculated moves to proceed. Motion will stop at a programmed point, and along the programmed path. In this state, it is possible to resume program calculation and move execution at this point, so it is not (yet) possible to open the program buffer. For those who want to open the program buffer now instead of resuming, we usually recommend issuing the "a" [abort] command. In your case, this would stop the spindle axis, so you could use the "cpx return" command, as recommended above.

From the training slides, an overview of the different stopping commands:

* q [pause] – No new program calculations, finish executing already calculated moves
- Does not begin to stop immediately (in general)
- Decel rate specified by programmed move rules
- Stays on programmed path (but no blend at stopped point)
- Stops at programmed point
- Can resume from stopped point with r [run] or s [step]
* s [step] – One additional move calculation, finish executing calculated moves
* h [hold] – Feed hold: Ramp time base to zero (%0) starting immediately
- Decel rate specified by Coord[x].FeedHoldSlew
- Stays on programmed path
- Does not stop at programmed point (in general)
- Can resume from stopped point with r [run] or s [step]
* %0 – Set time base value to zero, starting immediately
- Decel rate specified by Coord[x].TimeBaseSlew
- Stays on programmed path
- Does not stop at programmed point (in general)
- Can resume from stopped point with % value > 0
* \ [lh\] – Quick stop in segmented lookahead, starting immediately
- Decel rate specified by Motor[x].InvAmax (one motor controls)
- Stays on programmed path
- Does not stop at programmed point (in general)
- Acts as “feed hold” outside of segmented lookahead
- Can resume from stopped point with > [lh>], < [lh<], r [run], or s [step]
* a [abort] – Abort program execution and moves, starting immediately
- Decel rates specified by Motor[x].AbortTa and AbortTs (per motor)
- Does not stay on programmed path (in general)
- Does not stop at programmed point (in general)
- Cannot resume from stopped point

I guess I'm still having a degree of confusion here, and this is why we have struggled to resolve this issue so far. To my mind the fundamental issue is that there is no on-line "stop" command. You can have a part program stop itself and run the stop command in the motion script, but for external control there is no "stop" equivalent. We are aware of the online "q" command but hit issues when trying to use a "q" and then reload a new part program, which is why we thought the only option was an "a". The "cpx return" is new information. However from your earlier post, I read the comment that "cpx return" was just setting the PC for the motion script. I assumed that the script itself remained in its "paused" state and therefore a new motion script can't be loaded into that CS. Can you confirm that the "cpx return" approach will allow this ?

Have you also considered adding an on-line command version of the "stop" command ? It would seem like a simpler approach.
Most of these commands -- on-line and buffered program -- are intended to come from outside of the motion program itself, either from the host computer (on-line) or from a PLC program (buffered). They are not part of the program sequence. Also, most of the commands are intended to give the operator the choice, once stopped, of either resuming program operation or ending it. For everyone else I have encountered in 20 years of doing this, the "abort" command issued when stopped is a satsifactory way of choosing to end program execution and permit the buffer to be reused.

A "return" command in the top-level motion program points the program counter to the beginning, permitting the program to be restarted from there, or the buffer to be re-used. There is an implicit "return" at the end of every program. (This is what led me to suggest the "cpx return" command to let you open the buffer, and yes it will work after a q/pause command.) Unfortunately, this is not of use to you, because you are executing the command from an M-code subprogram. Right now, we are evaluating whether there would be any problems in changing the internal coordinate system status slightly after a "stop" command so the buffer could be opened. Probably this will be in the next release. We will also consider an on-line version of this command.
(12-22-2011, 12:27 PM)curtwilson Wrote: This is what led me to suggest the "cpx return" command to let you open the buffer, and yes it will work after a q/pause command.

Well it doesn't seem to work for me. I would appreciate some pointers as to what I might be doing wrong. Here's an annotated series of commands sent to GetResponse...


Cmd "open prog 1" --> 0 "NO RESPONSE"
Cmd "N65537 L1=1.000000" --> 0 "NO RESPONSE"
Cmd "N65538 WHILE (L1==1.000000) {" --> 0 "NO RESPONSE"
Cmd "N65539 G0.000000 X20.000000 " --> 0 "NO RESPONSE"
Cmd "N65540 G4.000000 X1.000000 " --> 0 "NO RESPONSE"
Cmd "N65541 G0.000000 X30.000000 " --> 0 "NO RESPONSE"
Cmd "N65542 G4.000000 X1.000000 " --> 0 "NO RESPONSE"
Cmd "N65543 }" --> 0 "NO RESPONSE"
Cmd "N65544 M2.000000 " --> 0 "NO RESPONSE"
Cmd "M2" --> 0 "NO RESPONSE"
Cmd "close" --> 0 "NO RESPONSE"

START PART PROGRAM - we first run a script (10000) to initialise the environment

Cmd "Coord[1].pDesTimeBase=Coord[1].DesTimeBase.a;" --> 0 "NO RESPONSE"
Cmd "&1 start 100000;" --> 0 "NO RESPONSE"
Cmd "&1 b " --> 0 "NO RESPONSE"
Cmd "&1 start 1" --> 0 "NO RESPONSE"

PAUSE PART PROGRAM - what we call pause, which is feed hold

Cmd "&1 h" --> 0 "NO RESPONSE"

STOP PART PROGRAM - now stop the part program, which is the PMAC pause

Cmd "&1 q" --> 0 "NO RESPONSE"

ATTEMPT TO LOAD A NEW PART PROGRAM - this was a "&1 a" which does work but stops the spindle, now replaced with your suggested "cpx return"

Cmd "cpx Ldata.coord=1; return" --> -38 "memory:136:1: error #38: PROGRAM RUNNING: cpx Ldata.coord=1; return
Cmd "open prog 1" --> -33 "memory:137:1: error #33: BUFFER IN USE: open prog 1

...any ideas what I'm doing wrong ?
In earlier posts, we were discussing (I thought) halting program execution and letting the already-calculated moves finish.

A hold command stops execution of an already calculated move in the middle by bringing the "time base" value to 0. The program is technically still running in this mode (Coord[x].ProgRunning = 1), but not doing anything because there are no further move completions to trigger new program calculations (Coord[x].ProgProceeding = 0).

In this state, the reason that the "q" command does not do what you want is that it does not get a chance to finish. The "q" command clears the ProgRunning bit so no further program calculations will be done, but it is not complete until the calculated moves finish executing. With the coordinate system in feed-hold, this does not happen.

I have found an alternate method that works for me whether moves were stopped in the middle or at the end. Once stopped, if you issue the on-line "b{constant}" command (where {constant} is the program number) or the program "begin:{data}" (where {data} evaluates as the program number), the coordinate system is put in a status in which the program buffer can be cleared (Coord[x].ProgActive = 0). All this can be done while letting the spindle axis continue moving.
We'll need to do more testing to make sure that there are no gotchas but so far it seems to work a treat and does what we're looking for. Thanks for your help.

Forum Jump:

Users browsing this thread: 1 Guest(s)