Manufacturing Information Solutions Forum Index Manufacturing Information Solutions
Your Place for Support and Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How a CNC Works

 
Post new topic   Reply to topic    Manufacturing Information Solutions Forum Index -> CNC Controls
View previous topic :: View next topic  
Author Message
mistux
Site Admin


Joined: 25 Jun 2004
Posts: 1042
Location: South Bend, Indiana USA

PostPosted: Mon Dec 05, 2005 10:17 pm    Post subject: How a CNC Works Reply with quote

Exactly How a CNC Works

This document will detail how a CNC operating system
and stepper motor servo loop operate. Although written from
Stepster.exe the document points to the ideal CNC rather
than explaining the compromises sometimes evident in
Stepster.
The readers of this document should be thoroughly
familiar with G-codes, at a minimum they should read the
NCreadme.txt that accompanies Stepster.
The reader may also want to compare the description of
functions here to the actual source code for Stepster, but
would do well not to copy Stepster too closely as it has
many examples of poor programming.

Contents
1 Main Menu
2 Manual
3 Linear Move
4 The Parser
5 Manual Data Input
6 Circular Moves
7 Automatic Operation
8 Canned Cycles


1 Main Menu

The Main Menu is a means of selecting Auto, Manual or
Manual Data Entry modes via "hot keys". If a control panel
is fitted it should also be read by the main menu block when
the selector switch is placed in "Auto".

2 Manual Operation

The block of code for manual operation sets the jog
distance, watches for key presses (and button presses) to
command moves, and resets axis values to zero when
commanded.
When a manual incremental jog is commanded the standard
linear move loop is used. Continuous jogging would require a
separate routine that would watch for the key or button to
be released, then decelerate to a stop.

If the CNC is working with the machine coordinate
system (G53) zeroing an axis sets the "master" position to
zero.
When the Z axis is zeroed in G54 mode and tool #0 is
selected the user is actually setting the basic offset from
G53 Z0. When any other tool number is selected and zeroed
when in the G53 coordinate system an offset from G53 Z0 is
created. If the control is in G54 or G55 mode the offset is
a product of the "base" G54 or G55 offset and the current Z
axis display.
Individually setting the tool lengths in G55 should not
be required, rather the CNC should set a base offset for G55
Z0 from G53 Z0 when tool #0 is selected (and G55 is in
effect). When other tool numbers are selected an offset from
the G53 to G54 planes PLUS that tools G54 offset will be
loaded into the display.
To repeat: The G54 and G55 base Z planes are set with
tool #0, tool offsets are normally loaded with the control
in the G54 mode.
Note: switching between G53, G54 and G55 can only be
done in Auto or MDI mode.
Note: the G-code standard provides for six work
coordinate systems, G54 through G59, but to save complexity
Stepster only used two.


3 The Linear Move

For an example I will use
G1 X1 Y.1 Z.01 F10
For simplicity I will specify that all three axis have
a step distance of .001 per step.

Currently the "move setup" consists of examining each
of the three axis for which one has the most steps to move:
this will be the total times through the "move loop". Each
of the other axis will move proportionately to the longest.
So X moves .001 for every iteration through the move
loop, Y moves .0001 per iteration, and Z moves .00001 step
per iteration.

In the move loop the Actual Positions are compared to
the Calculated Positions, the differences are the Errors.
(this is the definition of ANY servo loop)

When the move loop begins the actual position is zero
(incremental). The calculated positions are based on the
count of the count of cycles through the move loop
(iterations), so for the first iteration this is 1. The
calculated positions for the example are now X= .001, Y=
.0001, Z=.00001. The errors also equal X=.001, Y=.0001,
Z=.00001.
The rule for stepper motors is "If the error is greater
than or equal to one step then command a step and then
update the axis' position" so X moves one step (.001), and
it now has an error of 0, but Y still has an error of .0001
and Z error still equals .00001.

On the second iteration the calculated positions are
X=.002, Y.0002, Z=.00002. There is enough error for X to
make another step, but not Y or Z.
On the tenth iteration through the move loop the Y
error finally equals 1 step (.001), so a step for Y is
commanded and Y's actual (G53 machine) position is updated
and the error reset to zero. On the 100th iteration Z
finally takes a step, etc.

In a "real" servo cycle CNC the process is similar, but
not the same.
In a "real" servo cycle the Actual position is read
from scales or rotary encoders, in a stepper CNC the actual
position is based on the number of step commands previously
issued since the axis was zeroed (it works, just be sure
you've got a LOT more motor than you think you need.)
In my CNC the Calculated position is based on the
iteration count, in a "real" CNC it is based on TIME via a
clock pulse. (My program sets the feedrate by creating
pauses at the end of the move loop with a "delay loop" that
is based on a rather complex and inexact formula to set the
number of iterations through the delay loop.)

In a "real" servo cycle the output is analog- if the
"error" is small a weak (slow) signal is sent to the motor.
If the error is large the signal is strong ("Hey! Your way
off! Hurry up!!"). Notice that to work ALL CNC's must have
an error, the tool position is NEVER exactly what it should
be (but it can be sooooo close.....)

Acceleration and Deceleration

Stepper motors will "go out of synch" if they are
accelerated or decelerated too suddenly. This is because the
pattern of the magnetic fields is advancing faster than the
rotor can keep up. Once a motor has been out of
synchronization a stepper CNC is useless until it has been
re-zeroed, as the position of that axis has been lost. To
help prevent this the move loop contains additional delay
loops to accelerate and decelerate the motor. The base
distances to accel and decel are read from a set up file,
naturally they differ greatly from machine to machine.
The base distance for accel and decel is modified by
the feedrate, the faster the feedrate the grater the accel /
decel distance.
There is a second setup variable for accel / decel that
relates to the computers speed (since this affects how fast
the accel / decel loops run), when this is set wrong the
accel / decel loops will either have a sharp change of speed
at the beginning of accel /decel or at the end of accel /
decel. For Stepster this parameter is adjusted by listening
to the motors during jogging moves.

Backlash Compensation
To compensate for play in the leadscrews and additional
move for any motor that is reversing direction is commanded,
this backlash move happens before the regular move and does
not affect the display or Actual position (G53) of the
machine. In order for backlash compensation to work on a
stepper motor CNC it must work perfectly, any errors will
accumulate. One must understand that a user's G-code files
may run to tens of thousands of lines of code.
In Stepster the backlash compensation is integrated
into the regular linear move routine, a variable is set that
tells the linear move routine not to update the display and
use rapid speed. This is not the best, as it complicates the
linear move routine and every line of code here slows top
speed. A separate move loop should be used for backlash
compensation.

FEED PER REV AND THREADING
(Not implemented in Stepster.)
When a CNC lathe is in the Feed-Per-Rev mode the
spindle encoder pulse train is substituted for the TIME
pulse. When threading the concept is the same, but the
beginning of the move is delayed until the marker pulse (one
per rev) from the encoder is read.

Let me back up to the requirement: slave the Z axis (Z
only, nothing fancy here) to a spindle encoder at a ratio
set by the feed command (for convenience the user will enter
the exact feed per rev, F.0005 would feed 5/1000 inch per
rev).

The theory I have is to treat the Z axis like one of
the shorter axis: the calculated position will increase by
LESS than one step each time through the loop. The loop will
"hang" until the pulse is received from the port (like it
hangs now till the delay loop is complete), then on to the
next iteration.
This differs from a normal one axis move in that
normally the one axis will always move exactly one step per
iteration, not a partial step.
Example: I may want to move the Z axis .000023 per
pulse, the first time through the loop the Z calculated
position would be .000023, no where near the error required
to make a step. After enough times through the loop a step
would be made, and eventually the move loop would end, based
on the actual position equaling the end position.

A "rigid tapping" routine would work as above, but
require program control of the spindle motor, to reverse
rotation of the tap at the bottom, and also must read the
spindle encoder for direction. The routine works like this:
The G-code block includes Z depth, F feed per rev, and R
clearance plane information. The routine first turns the
spindle clockwise and begins the z axis feed per rev move.
When the Z axis depth is reached the routine commands the
spindle to reverse rotation. The Z axis direction does not
reverse until the encoder indicates that rotation has
reversed. After the spindle has reversed direction and the Z
axis has raised up to the R clearance plane the encoder
following is ended and the spindle resumes CW rotation.


Improved Feedrate Control

As mentioned earlier, "real" CNC's use an externally
generated clock pulse to regulate motion. This could be
simulated for a PC CNC by having a multitasking program flip
a bit back and forth. The "move loop" would hang until the
bit was set, then continue to the next iteration. The clock
signal could be constant if the longest axis was set to LESS
than one step per iteration and the other axis were scaled
proportionately. For instance, if the longest axis was
scaled .01 step per iteration the move would take 10 times
as long to finish.
It would be best if the "rate clock" could be
controlled directly, both to enable true "inch per minute" F
codes and to enable the feedrate override by manipulating
the rate clock. On a true CNC the rate clock is a separate
circuit, on a PC CNC this will probably require a
multitasking TSR.
One possible option is to have an externally generated
clock signal generated on a separate circuit board and input
through the LPT port. A potentiometer on this simple 555
timer chip circuit would act as a fully tunable feed
override. This would be complex and expensive but would
solve all problems in achieving true inch per minute feed
rates.

4 The Parser
The parser is a section of the program that reads lines
of text (from the user's text file or from Manual Data
Input) and converts them to commands for the NC to execute.
Stepster recognizes N, G, X, Y, Z, I, J, K, L, R, M, S, and
T, but no actions for N and S are implemented.

There are actually 9 classes of G-codes, and one from
each class may be active at the same time.
G0 through G9 is the motion class, only G0, G1, G2, G3
and G4 are commonly supported.
G10 through G19 are plane class, usually G17, G18 and
G19 (arcs in XY, XZ, and YZ planes) are supported.
G20 through G29 are ????
G30 through G39 are for feed per rev, G33 is clockwise
threading.
G40 through G49 are for offsets, G40, G41 and G42 are
cutter comp, G43 loads Z axis (tool) offsets, etc.
G50 through G59 are for coordinate systems, G51
rotation, G5 scaling, G53 through G59 for coordinate system
selection.
G60 through G69 ????
G70 through G79 are for repetitive moves, such as bolt
hole circles, etc.
G80 through G89 are for canned cycles, such as hole
drilling and boring.
G90 through G99 are for move types, G90 absolute, G91
incremental, G90.1 absolute with absolute I and J, etc.

Note: All CNC's use slightly different "flavors" of G-codes,
and the G70 and G80 class are notoriously different from one
machine to the next.

Note: The use of decimal numbers, such as G90.1, is a new
innovation to increase the number of possible G-codes.

The reason it is important to support the different
classes of G-code is so the user can enter complex lines
such as:

N10 G90 G17 G40 G50 G70 G80 G0 X0 Y0 Z0

The above line would: set absolute moves, arcs in the
normal XY plane, cancel cutter comp, cancel scaling and
rotation, cancel all canned cycles, and rapid to X0 Y0 Z0.
Experienced G-code programmers are taught to use a line like
this after every tool change, so the program can safely be
started in the middle.

Stepster did not properly implement the different
classes of G-codes, the user was warned to use separate
lines for each G-code. While the complex line in the example
above is not mandatory, lines like
G54 G92 X0 Y0 Z0
are quite common. Stepster does parse this line correctly,
but this is mostly accidental.

How the parser works
The parser reads one letter at a time. When a
recognized letter (N, G, X, etc) is encountered a variable
is set to mark the place in an array for the value to be
stored. In Stepster the array G(20) is used, G(1) for N,
G(2) for the G value, G(3) for X, etc. Notice this does not
provide for the different classes of G-code.
Once the place in the array is determined the VAL
command is applied to the rest of the line of text. In BASIC
the VAL command will get the numerical value of an alpha-
numeric string. The VAL command will get the proper result
even if the string contains a letter. In the following
example

a$ = "1234abcd"
result = VAL(a$)

result will be 1234, no error will occur. The parser
continues one letter at a time until the entire line is
read.

After each letter value is read execution branches to
blocks of code for each letter (nothing is done to N or S
letter values). For X,Y, Z, I, J, and K the read in values
are converted to incremental distances (if the control is in
the G90 absolute mode) since this is what the move loops
require.
M codes are executed immediately as read.

If the letter read was G control is routed to a series
of IF statements. Some G codes are processed immediately,
such as G17, G18, and G19. G53, G54 and G55 can also be
processed immediately. Since these G-codes are processed as
read another G-code on the same line is OK, but this is not
as good as storing G-codes in a separate array. Assigning G-
codes to the proper class could be done here.
Each G code results in a "mode" being set. This "mode"
will be used by the post-parser to branch to the appropriate
block, linear, circular, dwell and null. Null is provided
for when no further action is required after reading the
line, such as when a line contains just a G-code that was
executed immediately.

Stepster can set tool offsets from within the program
with the line
N10 /T2 L1.23
and calls that tool offset with the line
N20 T2

This is NOT the standard way input a tool offset, it
was copied from the 1978 Bridgeport Operating System
Software (BOSS) versions 4, 5, and 6. Calling a tool length
is sometimes done with the T letter, but is more often done
with the G43 command
N100 G43 T2
or
N100 G43 L1.234

Use of the G43 command would probably be quite a bit
simpler than the code required to make the / work, it is
confusing to use the T letter both to load AND call a tool
offset.

The Post Parser
The post parser controls where program execution
branches to. It also provides a place to wait for the user
to press the start button when single block operation is
selected.
In theory at least one branch for program operation
should be provided for most of the classes of G-code, at
least to all the classes that read X, Y, or Z. G0 and G1
branch to the linear move routine, G2 and G3 branch to the
circular move routine, G4 branches to the Dwell routine, The
G40 class needs to branch to a routine to set offsets. The
G90 class should also branch to a special section, as G92
optionally reads X, Y, and Z.

Rotation
The post parser is also where rotation can be
implemented, this must happen before the move is called.
Each X, Y point is converted to a range and angle from the
center of rotation (polar coordinates), then the amount of
rotation (angle) is added to the bearing and the result is
converted back to X and Y (Cartesian coordinates).

Scaling
Stepster accomplishes scaling by dynamically changing
the step distances for the X and Y motors. If the true step
distance is .001 and the control is told the step distance
is .002 the resultant part will be half size. This approach
means that ellipses will be described if X and Y are scaled
differently, but unfortunately the Display does not show the
scaled value, it shows the original value. Also, the user
must return to the exact point where scaling was started or
the display will not be correct.
An alternate approach would be to insert the code to
scale the commanded distances to move just before the post
processor calls the move routine. This would result in a
correct display and the ability to change / cancel scaling
anywhere, but ellipses are not possible.
There is no reason why BOTH types of scaling can't be
implemented, with G51 and G51.1.

5 Manual Data Input

In the MDI mode the user types a block of G-code to be
executed. The format of text is the same as for Automatic
operation from a text file. After the user presses the Enter
key control switches to the parser, then to the post parser,
then to the appropriate move routine (if any).
It would be best if a variable in the set up file
specified whether action is to begin immediately after the
user presses return, or whether control should wait for the
Start button (or key) to be pressed, real CNC's do it both
ways, and some allow a choice.


6 Circular Moves
Early CNC's (actually NC's) were only capable of arcs
of less than ninety degrees, and they could not cross the
quadrant boundaries at 3, 6, 9, and 12 o'clock. This is a
much simpler move than a multi-quadrant move where the
motors must change direction.
Backlash compensation is an added complexity, and the
ability to do arcs in the XY, XZ, or YZ planes further
complicates the arc routine. The description of the arc
routine will start with single quadrant moves, then add the
theory for multi-quadrant operation, then backlash, then
plane selection. Until the section on planes all examples
will be in the XY plane.

Single Quadrant Arcs
Arcs also work to the servo theory, the actual
(present) position is compared to the calculated position
(based on time or number of times through the iteration) to
give an Error. When the Error is large enough a step is
commanded and the actual position is updated.

The setup for a single quadrant arc is to find:
1. the Starting Angle
This is based on the incremental distance (in X and Y)
to the center point of the arc (specified with I and J). The
Arc Tangent function is used to return the angle.

Note: most computer languages work in radians. Radians are
capable of describing arcs to 180 degrees. Several lines of
code are required to examine whether the X value of the
starting point is greater or less than the X value of the
center point and whether the Y value of the center point is
greater or less than the Y value of the center point in
order to find whether or not to add 180 degrees to the start
angle. This code is also required for the Ending angle and
is slightly different for clockwise and counter clockwise
moves.

2. the Ending Angle
This is based on the incremental distance (in X and Y)
from the center point to the end point of the arc. These
distances are called I1 and J1. The Arc Tangent function is
used to return the angle.

Note: 360 degrees is added to the Starting or Ending angle
so that the Working angle will not cross zero. This is to
prevent situations such as when a clockwise arc is started
at 10 degrees and ran to 350 degrees. Instead the arc starts
at 370 degrees and runs to 350 degrees.

3. the Radius of the Arc
Based on the square root of (I squared + J squared), it
should also be calculated from I1 and J1, this provides a
check of the user's data, the two radii should agree within
a small error (say .0015 max), and a warning should occur.
If no warning is given the CNC should move in a predictable
way even when bad data is input.

4. The Delta, or amount to increment the Working angle for
each iteration.
This is the amount of change (from zero degrees) at the
radius specified for one motor step. The formula used is Arc
Tangent (step distance / radius). The larger the radius and
the finer the motor step the finer an angle this will be. In
Stepster this value was arbitrarily halved to ensure that
the Error would never be more than one motor step, this is
probably not required, but since the Arc routine never needs
to move at Rapid speeds there is no speed penalty.

5. The motor's direction.
This is also found by examining whether the arc is
above / below and left / right of the center point.

The Arc Move Loop
The concept of the arc move is : At the beginning of
the move the Actual X and Actual Y positions are stipulated
by the Sine and Cosine of the Starting angle, and the
Working angle is set to equal the Starting angle. X and Y
are calculated with Sine and Cosine based on the Working
angle. The Working angle is incremented by a set amount
smaller than the Arc Tangent of one motor step. The arc ends
when the Working angle equals the Ending angle.

The arc move loop at it's core is not much different
than the linear move loop. The X and Y Calculated positions
are found with sine and cosine of the radius at the working
angle. These are compared to the Actual Positions and the
Error found. When an axis' Error is greater than one motor
step a step is commanded and the axis' Actual Position is
updated. At the end of the loop the Working angle is
incremented by Delta (which is a negative number for
clockwise arcs) and the loop repeats until the Working angle
equals the Ending angle.


Multi-quadrant Operation

In order to enable multi quadrant operation I used many
blocks of code that examine the working angle and direction
of the arc. The first of these "quadrant detection" blocks
is at the end of the arc setup. If the working angle is out
of range of the first quadrant detection block control drops
to the next etc. Eventually the working angle is within the
range (quadrant) covered by a block. The motors' direction
are then set, and control goes to the move loop for one
iteration, then returns to the same block. This continues
until the working angle no longer falls in the range
(quadrant) controlled by the block, and control drops to the
next quadrant detection block, etc. etc. In the move loop is
a line examining for the end of the arc (Working angle
equals End angle), this sets a value completely out of range
so that control will fall through all remaining quadrant
detection blocks.
In Stepster this added a couple pages of code, it is
not an especially pretty example of code, and near duplicate
code must be used for clockwise and counter clockwise arcs.
If someone can find a more elegant solution I'd sure like to
see it.

Backlash Compensation
All those quadrant direction selection sections ; ) are
a fine place to add backlash comp, every time a motor
changes direction a few extra steps are added as a linear
move. Keeping track of the last direction the motor moved is
the toughest part.

Three axis Circular Interpolation
This allows a linear move for the Z axis as the X and Y
axis' describe an arc.
To make this work the arc setup must find the total
number of iterations based on the difference between the
Starting and Ending angles divided by Delta. Then the
(incremental) linear distance for the Z axis is divided by
this number. The result is the distance the Z axis should
move each iteration.
Code is added to the arc move loop that compares the
Actual position of Z to the Calculated position (based on
the number of times though the loop times the Z distance per
iteration to yield the Z axis Error, when the error equals
or (slightly) exceeds a motor step a step is commanded, just
like in the normal move routine.

XY, XZ, YZ Plane Selection

This greatly adds to the complexity of the arc move
loop. Instead of X, Y, and Z the arc routine must work with
the Cosine axis, the Sine axis, and the Linear axis. At the
beginning of the routine X, Y, and Z are assigned to the
proper variables, then during the loop they must be re-
assigned to X, Y, and Z to update the display. Fortunately,
even though this complexity slows the arc routine
significantly arcs are never done at maximum feedrate.

7 Automatic Operation
Automatic operation is simply MDI with file
manipulation added. There is some thought to reading an
entire users file and putting it into a matrix in memory to
gain some speed. I don't feel this is required, the time
required for a P-75 with a slow 80 meg hard drive to parse a
line of text is a few milliseconds, it is impossible to
detect with the eye. A line of text is only parsed once, a
move loop may iterate tens of thousands of times. Also, a
user's file may be tens of thousands of lines long,
allocating this much variable space may be difficult.

8 Canned Cycles
Canned cycles are inserted into the post parser, in
this case they come AFTER the move and before control is
returned to get the next line of text to parse. Canned
cycles contain instructions for at least one additional
move, so new values to move to are set, then another move is
commanded by switching control directly to the move routine
so that another move can be executed. After the homing moves
the "mode" is set to null and control goes to the top of the
post parser, this is done because the post parser also
contains a duplicate of the code to update the display.

Note: Neither the code for rotation or canned cycles should
be in the post parser, just IF statements that cause GOSUBS
to the appropriate subroutines.
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    Manufacturing Information Solutions Forum Index -> CNC Controls All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group