a version of g-code compatible with EMC2
Introduction:
In this tutorial I will try to explain some of the fundamentals of RS-274-NGC, which is a version of g-code compatible with EMC2 (enhanced machine control 2).
Format and Scope:
I'll try and make it so that there will be one section per command. People are welcome to discuss, especially since I am not the last word on the subject- and there are plenty of gaps in my knowledge. As our understanding of the subject changes, edits and amendments will be made. This is not meant to be an exhaustive exploration of g-code, RS-274-NGC, EMC2, or CNC in general. The goal is to provide a readily-accessible knowledge base for people (specifically micRo and RoGR users) to explore CNC on their own.. What I do know, however, will help many an aspiring CNC machinist.
Brief History:
G-code is the street-name for a closely-related family of languages developed for Numeric Control of machine tools. In the 1960's g-code was established under the designation RS-274. There are many dialects of RS-274. One of the last nearly universal version is known as RS-274-D. In the late '90s the National Institute of Standards and Technology began developing an updated version of g-code, as well as a real-time computer interpreter and controller for their dialect of RS-274. The NIST version of g-code was named RS-274-NGC (NGC is an acronym for Next Generation Control), and the software was named EMC (Enhanced Machine Control). EMC has existed for about 10 years, it was originally written for the Windows NT operating system, but has since been ported to Linux. All current versions of EMC require Linux. As of this post, the most current version of EMC is known as EMC2, and its version is 2.3. RS-274-NGC as well as EMC2 are available for anyone to use at no cost (www.linuxcnc.org).
Why G-code? Why RS-274-NGC? Why EMC2?:
There are a number of alternate schemes for Numeric Control, but G-code is the most universal. There are a number of problems with it (which I won't go into detail about here), but it is a fairly easy way to program a machine and has nearly unanimous support. The main topic here is EMC2's version of RS-274-NGC, the reason being that EMC2 is a very capable G-code interpreter, is highly configurable, and is as free as life. In my humble opinion, it knocks, and then beats the socks off of the commercial alternatives. Simply put, it's the best platform for machine control that isn't purpose-built.
Why Program G-code instead of using a CAD/CAM package?:
First, it's free. Second, 95% of things that need to be machined consist of relatively simple geometries that are totally suitable to being hand-coded. Third, for simple geometries, the amount of time spent developing a g-code program by hand is significantly less than the time required within a combination of CAD and CAM softwares. Fourth, when there is a mistake (and there always are), correction is a simple process that can be performed quickly in a text editor. Re-design via CAD/CAM adds un-needed time, confusion, and complexity. Fifth, g-code is not subject to the whims of whatever CAM software you'd otherwise be using. This can become a serious point of frustration. Ask me how I know. Point 5b, hand-written g-code *can* be relatively easy to trouble-shoot, where-as generated g-code tends to be coordinate-happy, lengthy, incomprehensible, and totally absent of comments.
Why This?:
There are other tutorials for writing g-code available. There's a pretty good one on the EMC2 website (www.linuxcnc.org). This isn't meant to substitute for other sources, so much as it's meant to clarify them for those who are not programmers, and to add insight to the otherwise obscure while providing a forum for clarification.
What do I need?:
G-code is a plain-text language that can be written with most simple text-editor programs. The default g-code file extension recognized by EMC2 is .ngc (in all lower-case). It is, however, convenient to be running Linux with EMC2 (for trouble-shooting). The calculator is your friend. Basically, everything you need is on the EMC2 live-disc install with the exception of an internet connection.
Code Reference
G0 - Rapid Motion
Syntax:
G0 Xn Yn Zn
(rapid motion command, X coordinate, Y coordinate, Z coordinate)
Example:
G0 Y1.375 Z-2
This is the command to move the machine to a given coordinate at the fastest available speed. That means, in the context of EMC2, the maximum velocity on each axis. When using G0, there is no coordination between the axes- so one axis may finish before another, depending on the settings for each axis...
My take:
In my humble opinion, G0 is not very useful in comparison to G1 (coordinated move). There's nothing G0 can do that G1 can't do better.
G1 - Coordinated Motion
Syntax:
G1 Fn Xn Yn Zn
(coordinated motion, feedrate in current units, X coordinate, Y coordinate, Z coordinate)
Example:
G1 F20 X24.5 Y10
G1 allows for a coordinated move to a given location at a given feed rate (rate of tool travel). This is probably the single most used command within g-code. Each axis will arrive at the same time, since the feed rate is muxed between all the moving axes.
Skipping ahead: File headers and ends.....
Most of the time you will want to put a line of code at the top of the file which will tell the interpreter (EMC2) how to read it...
Headers:
G20 sets the file units to inches.
G21 sets the file units to millimeters.
G90 sets the coordinate system to absolute coordinates.
G91 sets the coordinate system to incremental coordinates.
G17 makes arcs within the XY plane.
G18 makes arcs within the XZ plane.
G19 makes arcs within the YZ place.
Ends:
M30 signifies the end of a program.
Notes:
These header commands are fundamental enough to how a file is read, that they should always be included at the beginning of a file. However, these "header" commands can be changed at-will within a file as well. So it is possible to switch between absolute units and incremental units, or arc planes at will. None of these require any additional arguments or variables.
Example:
G20 G90
G1 F20 X10 Y5
G1 F5 Z-1
G1 F20 Z0
G1 F20 X0 Y0
M30
G2 and G3 - Arc Commands
G2 = clockwise arc
G3 = counter-clockwise arc
Syntax
G17 XY plane:
G2 Fn Xn Yn In Jn Zn
(Clockwise arc, Feedrate, Destination X coordinate, Destination Y coordinate, X-axis arc-centerpoint offset, Y-axis arc-centerpoint offset, Interpolated destination Z-axis coordinate)
G18 XZ plane:
G2 Fn Xn Zn In Kn Yn
(Clockwise arc, Feedrate, Destination X coordinate, Destination Z coordinate, X-axis arc-centerpoint offset, Z-axis arc-centerpoint offset, Interpolated destination Y-axis coordinate)
G19 YZ plane:
G2 Fn Yn Zn Jn Kn Xn
(Clockwise arc, Feedrate, Destination Y coordinate, Destination Z coordinate, Y-axis arc-centerpoint offset, Z-axis arc-centerpoint offset, Interpolated destination X-axis coordinate)
Examples given in G17 XY plane..
Example 1:
(1 unit diameter half-circle that descends to Z -2)
G2 F10 X0 Y-1 I0 J-.5 Z-2
Example 2:
(a complete counter-clockwise circle without Z-axis interpolation)
G3 F20 X-1 Y0 I-.5 J0
G3 F20 X0 Y0 I0.5 J0
Notes:
As you've probably already surmised, G2/G3 allows for all manners of arcs- not just half-circles. The important things to keep in mind are: The arc starts wherever the position of the tool is, and is given in terms of it's end coordinate position. One plane can be selected at a time (G17, XY plane, G18, XZ plane, G19, YZ plane), but the third axis can be interpolated across the arc motion- allowing for helix and rudimentary spiral shapes.
Destination coordinates are given in regular Xn Yn Zn format, but Center-point offset coordinates are given in incremental coordinates: I = X-axis offset, J = Y-axis offest, K = Z-axis offset. The offsets correspond with the two axes in the given plane. That is, if a G17 arc is made (XY plane), then destination X and Y coordinates are given, as well as X and Y center-point offsets..
G4 - Pause Command
Syntax:
G4 Pn
(pause command, Pause in seconds)
Example:
G4 P2
(causes machine to pause for 2 seconds)
Notes:
G4 tells the machine to pause for a given amount of time. This is given in decimal seconds. Good for letting a spindle get up to speed before doing work.
Quick note on some global commands....
Feedrate:
Feedrate controls the speed a machine is moving the tool. It's given in units that agree with the units specified in the file header (if units aren't given in the header, it defaults to whatever the machine is currently set at). For inches it's given in Inches Per Minute, in millimeters- millimeters per minute. Feedrate can be set without an accompanying G or M command. Feedrate can be any number from zero to the maximum allowed for your machine.
Syntax:
Fn
(feedrate in current units)
Example:
F10
G1 X10 Y10
G1 X20
G1 Y20
G1 X10
Or:
G1 F10 X10 Y10
G1 F10 X20
G1 F10 Y20
G1 F10 X10
Spindle Speed
This sets the speed of the spindle in RPM. It is not necessary for spindle speed to be set within a file, and it's probably that the majority of users won't have a spindle which is under computer control.. For those who do... Pretty much the same rules apply to spindle speed as do feed rate. It does not need to be associated with another command in order to take place, and all numbers from and including zero can be used up to the maximum set for your spindle.
Syntax:
Sn
(spindle speed in rpm)
Example
S600
G1 F10 X10 Y10
G1 F10 X20
G1 F10 Y20
S1200
G4 P5.5
G1 F10 Y10
G1 F10 X10
Some "O" Commands
O commands provide looping and flow to a program. These allow for relatively compact programming of parts with lots of repetitive operations... These are also the "killer app" of hand-written G-code, since no CAM software (I know of) will generate these..
Subroutines
Syntax:
Onnn SUB
......(lines of code)
Onnn ENDSUB
.....(more lines of code)
Onnn CALL
What this means:
A Subroutine is a bit of code that can be called, or executed, elsewhere in the file. First the subroutine has to be defined, meaning that it must begin with "Onnn SUB", where the nnn part is a number specific to this subroutine, basically a name for the subroutine. After the body of the subroutine, it has to end with "Onnn ENDSUB". The number must correspond with the number in the definition line. The subroutine can be defined anywhere within a file, as long as it is defined before it is called. In order to call a subroutine, use "Onnn CALL" where nnn is the number of the subroutine you want to call. Subroutines can be nested, that is, one subroutine can be called from within another.
Example:
for this example, which is a complete file instead of a fragment, a subroutine will be used to bore holes at given locations. A combination of incremental and absolute coordinates will be used in order to accomplish this..
(HEADER)
G20 G90
(HOLE BORE SUBROUTINE)
O100 SUB
G91
(FIND START POSITION)
G1 F20 Z-.125
G1 F10 Y1
(HELIX-BORE TO DEPTH)
G3 F10 Y-2 J-1 Z-.125
G3 F10 Y2 J1 Z-.125
G3 F10 Y-2 J-1 Z-.125
G3 F10 Y2 J1 Z-.125
(STAY AT BOTTOM)
G3 F10 Y-2 J-1
G3 F10 Y2 J1
(RETURN TO POSITION)
G1 F20 Z0.625
G1 F10 Y-1
G90
O100 ENDSUB
(FILE BODY)
(TOUCH-OFF CLEARANCE)
G91
G1 F20 Z0.125
G90
(HOLE 1)
G1 F20 X5.375 Y4.5
O100 CALL
(HOLE2)
G1 F20 Y9
O100 CALL
(HOLE3)
G1 F20 X9.75
O100 CALL
(HOLE4)
G1 F20 X15.125
O100 CALL
(HOLE5)
G1 F20 Y4.5
O100 CALL
(HOME AND END)
G1 F20 Z0
G1 F30 X0 Y0
M30
Global Variables
Syntax:
#<_globalvarname> = n
...(lines of code)
G1 F20 X[#<_globalvarname>]
Notes:
Global variables are useful for controlling a setting across a file. Also, since math functions can be used on variables, and variables can be re-defined, it makes modular programming possible. There's a lot to be said for this, and this is a subject that will be returned to. The mechanics of it work like this: A variable must be named and given a value before it is to be used elsewhere within a file, however, it can be re-defined later. For a global variable, that is, a variable that can be read by anything within the file, it's important to use this format, #<_name> the underscore is what tells the interpreter that it is, in fact, global. Variables can be any real number.
Example:
I'll take the same file from the previous two examples, but modify it so that it uses a number of variables to set key values. Setting a file up this way is especially useful for moderately sized jobs which require fine-tuning. In this file, the bore-size, boring feed-rate, coordinated feed-rate, and depth of the bore are controlled via a set of global variables.
(HEADER)
G20 G90
(GLOBAL VARIABLE DEFINITIONS)
#<_rad> = .5 (RADIUS FOR BORE SUB-ROUTINE)
#<_depthpass> = -.125 (DEPTH FOR SINGLE HALF-CYCLE OF BORE)
#<_repeat> = 2 (NUMBER OF REPEATS)
#<_clear> = .125 (HEIGHT OF CLEARANCE FROM TOUCH-OFF)
#<_bfeed> = 10 (BORE FEED RATE)
#<_jfeed> = 20 (COORDINATED MOVE FEED RATE)
#<_diam> = [2 * #<_rad>]
(HOLE BORE SUBROUTINE)
O100 SUB
G91
(FIND START POSITION)
G1 F#<_jfeed> Z[-1 * #<_clear>]
G1 F#<_bfeed> Y#<_rad>
(HELIX-BORE TO DEPTH)
O110 REPEAT [#<_repeat>]
G3 F#<_bfeed> Y[-1 * #<_diam>] J[-1 * #<_rad>] Z#<_depthpass>
G3 F#<_bfeed> Y#<_diam> J#<_rad> Z#<_depthpass>
O110 ENDREPEAT
(STAY AT BOTTOM)
G3 F#<_bfeed> Y[-1 * #<_diam> J[-1 * #<_rad>]
G3 F#<_bfeed> Y#<_diam> J#<_rad>
(RETURN TO POSITION)
G1 F#<_jfeed> Z[[#<_repeat> * [-1 * #<_depthpass>]] + #<_clear>]
G1 F#<_jfeed> Y[-1 * #<_rad>]
G90
O100 ENDSUB
(FILE BODY)
(TOUCH-OFF CLEARANCE)
G91
G1 F#<_jfeed> Z#<_clear>
G90
(CLUNKY START POSITION CODE)
G1 F#<_jfeed> X1 Y9
(HOLES 2 3 4)
O200 REPEAT [3]
G91
G1 F#<_jfeed> X4.375
O100 CALL
G90
O200 ENDREPEAT
(HOLE5)
G1 F#<_jfeed> Y4.5
O100 CALL
(HOLE1)
G1 F#<_jfeed> X5.375
O100 CALL
(HOME AND END)
G1 F20 Z0
G1 F30 X0 Y0
M30
Comments
Syntax:
(your comment between these parenthesis)
Comments can and should be used within a file. These let you, or someone else, know what is going on in a g-code program, without necessarily having to mentally de-construct the code.
Math
All simple math operators can be used within RS-274-NGC g-code. These include, Addition (+), Subtraction (-), Multiplication (*), Division (/).. Other operators are available and will be discussed later as they come up.
Brackets []
You may have noticed the use of brackets in the examples by now... Brackets are used to encapsulate a math function. They behave the same way as parenthesis do in standard algebra, that is, each layer of brackets (from highest to lowest) is calculated -in order- before the next. As a practical note, there seems to be an intermittent bug within the interpreter... sometimes it cares if variables, when used, are put in brackets. Or at least it seems that way. Regardless, encapsulating variables within brackets can help clean-up the appearance of your code, are ignored -if non-functional- by the interpreter, and seem to always work.
While Endwhile
Syntax:
Onnn WHILE [mathematical condition]
....(lines of code to be repeated)...
Onnn ENDWHILE
Notes:
The O-word WHILE is similar to the REPEAT O-word, but allows for a condition of your choosing to be met.
Example:
This is a further modified version of the example code from the last several posts... Except this time a REPEAT is replaced with a WHILE command to find the depth of a bore.. A variable named #<_counter> is used to keep count of how many descending half-circles are performed, and then multiplied with the variable #<_depthpass> to figure the actual bore depth, which is compared with the variable #<_finaldepth> with the GT (greater-than) comparator. Once the actual depth is no longer greater-than the condition is broken, and the while loop stops. After the WHILE loop stops, the #<_counter> variable is reset to equal 0 for the next operation. Setting up an operation this way allows for the dynamic changing of variables without changing the overall outcome. Meaning that the depth of a cutting pass can be set independently from the final depth, amongst other things..
(HEADER)
G20 G90
(GLOBAL VARIABLE DEFINITIONS)
#<_rad> = .5 (RADIUS FOR BORE SUB-ROUTINE)
#<_depthpass> = -.125 (DEPTH FOR SINGLE HALF-CYCLE OF BORE)
#<_finaldepth> = -1 (FINAL DEPTH OF BORE)
#<_clear> = .125 (HEIGHT OF CLEARANCE FROM TOUCH-OFF)
#<_bfeed> = 10 (BORE FEED RATE)
#<_jfeed> = 20 (COORDINATED MOVE FEED RATE)
#<_diam> = [2 * #<_rad>]
#<_counter> = 0 (DEPTH COUNTER)
(HOLE BORE SUBROUTINE)
O100 SUB
G91
(FIND START POSITION)
G1 F#<_jfeed> Z[-1 * #<_clear>]
G1 F#<_bfeed> Y#<_rad>
(HELIX-BORE TO DEPTH)
O110 WHILE [[#<_counter> * #<_depthpass>] GT #<_finaldepth>]
G3 F#<_bfeed> Y[-1 * #<_diam>] J[-1 * #<_rad>] Z#<_depthpass>
G3 F#<_bfeed> Y#<_diam> J#<_rad> Z#<_depthpass>
#<_counter> = [#<_counter> + 2]
O110 ENDWHILE
#<_counter> = 0 (DEPTH COUNTER RESET)
(STAY AT BOTTOM)
G3 F#<_bfeed> Y[-1 * #<_diam> J[-1 * #<_rad>]
G3 F#<_bfeed> Y#<_diam> J#<_rad>
(RETURN TO POSITION)
G1 F#<_jfeed> Z[[#<_counter> * [-1 * #<_depthpass>]] + #<_clear>]
G1 F#<_jfeed> Y[-1 * #<_rad>]
G90
O100 ENDSUB
(FILE BODY)
(TOUCH-OFF CLEARANCE)
G91
G1 F#<_jfeed> Z#<_clear>
G90
(CLUNKY START POSITION CODE)
G1 F#<_jfeed> X1 Y9
(HOLES 2 3 4)
O200 REPEAT [3]
G91
G1 F#<_jfeed> X4.375
O100 CALL
G90
O200 ENDREPEAT
(HOLE5)
G1 F#<_jfeed> Y4.5
O100 CALL
(HOLE1)
G1 F#<_jfeed> X5.375
O100 CALL
(HOME AND END)
G1 F20 Z0
G1 F30 X0 Y0
M30
Pause - M0
Syntax:
M0
Notes:
M0 is a pause M-code that pauses the program indefinitely until the pause button is pushed again. This is useful if you're making a run of parts, and you want pause in between re-jiggings.
Source:Lumenlab
In this tutorial I will try to explain some of the fundamentals of RS-274-NGC, which is a version of g-code compatible with EMC2 (enhanced machine control 2).
Format and Scope:
I'll try and make it so that there will be one section per command. People are welcome to discuss, especially since I am not the last word on the subject- and there are plenty of gaps in my knowledge. As our understanding of the subject changes, edits and amendments will be made. This is not meant to be an exhaustive exploration of g-code, RS-274-NGC, EMC2, or CNC in general. The goal is to provide a readily-accessible knowledge base for people (specifically micRo and RoGR users) to explore CNC on their own.. What I do know, however, will help many an aspiring CNC machinist.
Brief History:
G-code is the street-name for a closely-related family of languages developed for Numeric Control of machine tools. In the 1960's g-code was established under the designation RS-274. There are many dialects of RS-274. One of the last nearly universal version is known as RS-274-D. In the late '90s the National Institute of Standards and Technology began developing an updated version of g-code, as well as a real-time computer interpreter and controller for their dialect of RS-274. The NIST version of g-code was named RS-274-NGC (NGC is an acronym for Next Generation Control), and the software was named EMC (Enhanced Machine Control). EMC has existed for about 10 years, it was originally written for the Windows NT operating system, but has since been ported to Linux. All current versions of EMC require Linux. As of this post, the most current version of EMC is known as EMC2, and its version is 2.3. RS-274-NGC as well as EMC2 are available for anyone to use at no cost (www.linuxcnc.org).
Why G-code? Why RS-274-NGC? Why EMC2?:
There are a number of alternate schemes for Numeric Control, but G-code is the most universal. There are a number of problems with it (which I won't go into detail about here), but it is a fairly easy way to program a machine and has nearly unanimous support. The main topic here is EMC2's version of RS-274-NGC, the reason being that EMC2 is a very capable G-code interpreter, is highly configurable, and is as free as life. In my humble opinion, it knocks, and then beats the socks off of the commercial alternatives. Simply put, it's the best platform for machine control that isn't purpose-built.
Why Program G-code instead of using a CAD/CAM package?:
First, it's free. Second, 95% of things that need to be machined consist of relatively simple geometries that are totally suitable to being hand-coded. Third, for simple geometries, the amount of time spent developing a g-code program by hand is significantly less than the time required within a combination of CAD and CAM softwares. Fourth, when there is a mistake (and there always are), correction is a simple process that can be performed quickly in a text editor. Re-design via CAD/CAM adds un-needed time, confusion, and complexity. Fifth, g-code is not subject to the whims of whatever CAM software you'd otherwise be using. This can become a serious point of frustration. Ask me how I know. Point 5b, hand-written g-code *can* be relatively easy to trouble-shoot, where-as generated g-code tends to be coordinate-happy, lengthy, incomprehensible, and totally absent of comments.
Why This?:
There are other tutorials for writing g-code available. There's a pretty good one on the EMC2 website (www.linuxcnc.org). This isn't meant to substitute for other sources, so much as it's meant to clarify them for those who are not programmers, and to add insight to the otherwise obscure while providing a forum for clarification.
What do I need?:
G-code is a plain-text language that can be written with most simple text-editor programs. The default g-code file extension recognized by EMC2 is .ngc (in all lower-case). It is, however, convenient to be running Linux with EMC2 (for trouble-shooting). The calculator is your friend. Basically, everything you need is on the EMC2 live-disc install with the exception of an internet connection.
Code Reference
G0 - Rapid Motion
Syntax:
G0 Xn Yn Zn
(rapid motion command, X coordinate, Y coordinate, Z coordinate)
Example:
G0 Y1.375 Z-2
This is the command to move the machine to a given coordinate at the fastest available speed. That means, in the context of EMC2, the maximum velocity on each axis. When using G0, there is no coordination between the axes- so one axis may finish before another, depending on the settings for each axis...
My take:
In my humble opinion, G0 is not very useful in comparison to G1 (coordinated move). There's nothing G0 can do that G1 can't do better.
G1 - Coordinated Motion
Syntax:
G1 Fn Xn Yn Zn
(coordinated motion, feedrate in current units, X coordinate, Y coordinate, Z coordinate)
Example:
G1 F20 X24.5 Y10
G1 allows for a coordinated move to a given location at a given feed rate (rate of tool travel). This is probably the single most used command within g-code. Each axis will arrive at the same time, since the feed rate is muxed between all the moving axes.
Skipping ahead: File headers and ends.....
Most of the time you will want to put a line of code at the top of the file which will tell the interpreter (EMC2) how to read it...
Headers:
G20 sets the file units to inches.
G21 sets the file units to millimeters.
G90 sets the coordinate system to absolute coordinates.
G91 sets the coordinate system to incremental coordinates.
G17 makes arcs within the XY plane.
G18 makes arcs within the XZ plane.
G19 makes arcs within the YZ place.
Ends:
M30 signifies the end of a program.
Notes:
These header commands are fundamental enough to how a file is read, that they should always be included at the beginning of a file. However, these "header" commands can be changed at-will within a file as well. So it is possible to switch between absolute units and incremental units, or arc planes at will. None of these require any additional arguments or variables.
Example:
G20 G90
G1 F20 X10 Y5
G1 F5 Z-1
G1 F20 Z0
G1 F20 X0 Y0
M30
G2 and G3 - Arc Commands
G2 = clockwise arc
G3 = counter-clockwise arc
Syntax
G17 XY plane:
G2 Fn Xn Yn In Jn Zn
(Clockwise arc, Feedrate, Destination X coordinate, Destination Y coordinate, X-axis arc-centerpoint offset, Y-axis arc-centerpoint offset, Interpolated destination Z-axis coordinate)
G18 XZ plane:
G2 Fn Xn Zn In Kn Yn
(Clockwise arc, Feedrate, Destination X coordinate, Destination Z coordinate, X-axis arc-centerpoint offset, Z-axis arc-centerpoint offset, Interpolated destination Y-axis coordinate)
G19 YZ plane:
G2 Fn Yn Zn Jn Kn Xn
(Clockwise arc, Feedrate, Destination Y coordinate, Destination Z coordinate, Y-axis arc-centerpoint offset, Z-axis arc-centerpoint offset, Interpolated destination X-axis coordinate)
Examples given in G17 XY plane..
Example 1:
(1 unit diameter half-circle that descends to Z -2)
G2 F10 X0 Y-1 I0 J-.5 Z-2
Example 2:
(a complete counter-clockwise circle without Z-axis interpolation)
G3 F20 X-1 Y0 I-.5 J0
G3 F20 X0 Y0 I0.5 J0
Notes:
As you've probably already surmised, G2/G3 allows for all manners of arcs- not just half-circles. The important things to keep in mind are: The arc starts wherever the position of the tool is, and is given in terms of it's end coordinate position. One plane can be selected at a time (G17, XY plane, G18, XZ plane, G19, YZ plane), but the third axis can be interpolated across the arc motion- allowing for helix and rudimentary spiral shapes.
Destination coordinates are given in regular Xn Yn Zn format, but Center-point offset coordinates are given in incremental coordinates: I = X-axis offset, J = Y-axis offest, K = Z-axis offset. The offsets correspond with the two axes in the given plane. That is, if a G17 arc is made (XY plane), then destination X and Y coordinates are given, as well as X and Y center-point offsets..
G4 - Pause Command
Syntax:
G4 Pn
(pause command, Pause in seconds)
Example:
G4 P2
(causes machine to pause for 2 seconds)
Notes:
G4 tells the machine to pause for a given amount of time. This is given in decimal seconds. Good for letting a spindle get up to speed before doing work.
Quick note on some global commands....
Feedrate:
Feedrate controls the speed a machine is moving the tool. It's given in units that agree with the units specified in the file header (if units aren't given in the header, it defaults to whatever the machine is currently set at). For inches it's given in Inches Per Minute, in millimeters- millimeters per minute. Feedrate can be set without an accompanying G or M command. Feedrate can be any number from zero to the maximum allowed for your machine.
Syntax:
Fn
(feedrate in current units)
Example:
F10
G1 X10 Y10
G1 X20
G1 Y20
G1 X10
Or:
G1 F10 X10 Y10
G1 F10 X20
G1 F10 Y20
G1 F10 X10
Spindle Speed
This sets the speed of the spindle in RPM. It is not necessary for spindle speed to be set within a file, and it's probably that the majority of users won't have a spindle which is under computer control.. For those who do... Pretty much the same rules apply to spindle speed as do feed rate. It does not need to be associated with another command in order to take place, and all numbers from and including zero can be used up to the maximum set for your spindle.
Syntax:
Sn
(spindle speed in rpm)
Example
S600
G1 F10 X10 Y10
G1 F10 X20
G1 F10 Y20
S1200
G4 P5.5
G1 F10 Y10
G1 F10 X10
Some "O" Commands
O commands provide looping and flow to a program. These allow for relatively compact programming of parts with lots of repetitive operations... These are also the "killer app" of hand-written G-code, since no CAM software (I know of) will generate these..
Subroutines
Syntax:
Onnn SUB
......(lines of code)
Onnn ENDSUB
.....(more lines of code)
Onnn CALL
What this means:
A Subroutine is a bit of code that can be called, or executed, elsewhere in the file. First the subroutine has to be defined, meaning that it must begin with "Onnn SUB", where the nnn part is a number specific to this subroutine, basically a name for the subroutine. After the body of the subroutine, it has to end with "Onnn ENDSUB". The number must correspond with the number in the definition line. The subroutine can be defined anywhere within a file, as long as it is defined before it is called. In order to call a subroutine, use "Onnn CALL" where nnn is the number of the subroutine you want to call. Subroutines can be nested, that is, one subroutine can be called from within another.
Example:
for this example, which is a complete file instead of a fragment, a subroutine will be used to bore holes at given locations. A combination of incremental and absolute coordinates will be used in order to accomplish this..
(HEADER)
G20 G90
(HOLE BORE SUBROUTINE)
O100 SUB
G91
(FIND START POSITION)
G1 F20 Z-.125
G1 F10 Y1
(HELIX-BORE TO DEPTH)
G3 F10 Y-2 J-1 Z-.125
G3 F10 Y2 J1 Z-.125
G3 F10 Y-2 J-1 Z-.125
G3 F10 Y2 J1 Z-.125
(STAY AT BOTTOM)
G3 F10 Y-2 J-1
G3 F10 Y2 J1
(RETURN TO POSITION)
G1 F20 Z0.625
G1 F10 Y-1
G90
O100 ENDSUB
(FILE BODY)
(TOUCH-OFF CLEARANCE)
G91
G1 F20 Z0.125
G90
(HOLE 1)
G1 F20 X5.375 Y4.5
O100 CALL
(HOLE2)
G1 F20 Y9
O100 CALL
(HOLE3)
G1 F20 X9.75
O100 CALL
(HOLE4)
G1 F20 X15.125
O100 CALL
(HOLE5)
G1 F20 Y4.5
O100 CALL
(HOME AND END)
G1 F20 Z0
G1 F30 X0 Y0
M30
Global Variables
Syntax:
#<_globalvarname> = n
...(lines of code)
G1 F20 X[#<_globalvarname>]
Notes:
Global variables are useful for controlling a setting across a file. Also, since math functions can be used on variables, and variables can be re-defined, it makes modular programming possible. There's a lot to be said for this, and this is a subject that will be returned to. The mechanics of it work like this: A variable must be named and given a value before it is to be used elsewhere within a file, however, it can be re-defined later. For a global variable, that is, a variable that can be read by anything within the file, it's important to use this format, #<_name> the underscore is what tells the interpreter that it is, in fact, global. Variables can be any real number.
Example:
I'll take the same file from the previous two examples, but modify it so that it uses a number of variables to set key values. Setting a file up this way is especially useful for moderately sized jobs which require fine-tuning. In this file, the bore-size, boring feed-rate, coordinated feed-rate, and depth of the bore are controlled via a set of global variables.
(HEADER)
G20 G90
(GLOBAL VARIABLE DEFINITIONS)
#<_rad> = .5 (RADIUS FOR BORE SUB-ROUTINE)
#<_depthpass> = -.125 (DEPTH FOR SINGLE HALF-CYCLE OF BORE)
#<_repeat> = 2 (NUMBER OF REPEATS)
#<_clear> = .125 (HEIGHT OF CLEARANCE FROM TOUCH-OFF)
#<_bfeed> = 10 (BORE FEED RATE)
#<_jfeed> = 20 (COORDINATED MOVE FEED RATE)
#<_diam> = [2 * #<_rad>]
(HOLE BORE SUBROUTINE)
O100 SUB
G91
(FIND START POSITION)
G1 F#<_jfeed> Z[-1 * #<_clear>]
G1 F#<_bfeed> Y#<_rad>
(HELIX-BORE TO DEPTH)
O110 REPEAT [#<_repeat>]
G3 F#<_bfeed> Y[-1 * #<_diam>] J[-1 * #<_rad>] Z#<_depthpass>
G3 F#<_bfeed> Y#<_diam> J#<_rad> Z#<_depthpass>
O110 ENDREPEAT
(STAY AT BOTTOM)
G3 F#<_bfeed> Y[-1 * #<_diam> J[-1 * #<_rad>]
G3 F#<_bfeed> Y#<_diam> J#<_rad>
(RETURN TO POSITION)
G1 F#<_jfeed> Z[[#<_repeat> * [-1 * #<_depthpass>]] + #<_clear>]
G1 F#<_jfeed> Y[-1 * #<_rad>]
G90
O100 ENDSUB
(FILE BODY)
(TOUCH-OFF CLEARANCE)
G91
G1 F#<_jfeed> Z#<_clear>
G90
(CLUNKY START POSITION CODE)
G1 F#<_jfeed> X1 Y9
(HOLES 2 3 4)
O200 REPEAT [3]
G91
G1 F#<_jfeed> X4.375
O100 CALL
G90
O200 ENDREPEAT
(HOLE5)
G1 F#<_jfeed> Y4.5
O100 CALL
(HOLE1)
G1 F#<_jfeed> X5.375
O100 CALL
(HOME AND END)
G1 F20 Z0
G1 F30 X0 Y0
M30
Comments
Syntax:
(your comment between these parenthesis)
Comments can and should be used within a file. These let you, or someone else, know what is going on in a g-code program, without necessarily having to mentally de-construct the code.
Math
All simple math operators can be used within RS-274-NGC g-code. These include, Addition (+), Subtraction (-), Multiplication (*), Division (/).. Other operators are available and will be discussed later as they come up.
Brackets []
You may have noticed the use of brackets in the examples by now... Brackets are used to encapsulate a math function. They behave the same way as parenthesis do in standard algebra, that is, each layer of brackets (from highest to lowest) is calculated -in order- before the next. As a practical note, there seems to be an intermittent bug within the interpreter... sometimes it cares if variables, when used, are put in brackets. Or at least it seems that way. Regardless, encapsulating variables within brackets can help clean-up the appearance of your code, are ignored -if non-functional- by the interpreter, and seem to always work.
While Endwhile
Syntax:
Onnn WHILE [mathematical condition]
....(lines of code to be repeated)...
Onnn ENDWHILE
Notes:
The O-word WHILE is similar to the REPEAT O-word, but allows for a condition of your choosing to be met.
Example:
This is a further modified version of the example code from the last several posts... Except this time a REPEAT is replaced with a WHILE command to find the depth of a bore.. A variable named #<_counter> is used to keep count of how many descending half-circles are performed, and then multiplied with the variable #<_depthpass> to figure the actual bore depth, which is compared with the variable #<_finaldepth> with the GT (greater-than) comparator. Once the actual depth is no longer greater-than the condition is broken, and the while loop stops. After the WHILE loop stops, the #<_counter> variable is reset to equal 0 for the next operation. Setting up an operation this way allows for the dynamic changing of variables without changing the overall outcome. Meaning that the depth of a cutting pass can be set independently from the final depth, amongst other things..
(HEADER)
G20 G90
(GLOBAL VARIABLE DEFINITIONS)
#<_rad> = .5 (RADIUS FOR BORE SUB-ROUTINE)
#<_depthpass> = -.125 (DEPTH FOR SINGLE HALF-CYCLE OF BORE)
#<_finaldepth> = -1 (FINAL DEPTH OF BORE)
#<_clear> = .125 (HEIGHT OF CLEARANCE FROM TOUCH-OFF)
#<_bfeed> = 10 (BORE FEED RATE)
#<_jfeed> = 20 (COORDINATED MOVE FEED RATE)
#<_diam> = [2 * #<_rad>]
#<_counter> = 0 (DEPTH COUNTER)
(HOLE BORE SUBROUTINE)
O100 SUB
G91
(FIND START POSITION)
G1 F#<_jfeed> Z[-1 * #<_clear>]
G1 F#<_bfeed> Y#<_rad>
(HELIX-BORE TO DEPTH)
O110 WHILE [[#<_counter> * #<_depthpass>] GT #<_finaldepth>]
G3 F#<_bfeed> Y[-1 * #<_diam>] J[-1 * #<_rad>] Z#<_depthpass>
G3 F#<_bfeed> Y#<_diam> J#<_rad> Z#<_depthpass>
#<_counter> = [#<_counter> + 2]
O110 ENDWHILE
#<_counter> = 0 (DEPTH COUNTER RESET)
(STAY AT BOTTOM)
G3 F#<_bfeed> Y[-1 * #<_diam> J[-1 * #<_rad>]
G3 F#<_bfeed> Y#<_diam> J#<_rad>
(RETURN TO POSITION)
G1 F#<_jfeed> Z[[#<_counter> * [-1 * #<_depthpass>]] + #<_clear>]
G1 F#<_jfeed> Y[-1 * #<_rad>]
G90
O100 ENDSUB
(FILE BODY)
(TOUCH-OFF CLEARANCE)
G91
G1 F#<_jfeed> Z#<_clear>
G90
(CLUNKY START POSITION CODE)
G1 F#<_jfeed> X1 Y9
(HOLES 2 3 4)
O200 REPEAT [3]
G91
G1 F#<_jfeed> X4.375
O100 CALL
G90
O200 ENDREPEAT
(HOLE5)
G1 F#<_jfeed> Y4.5
O100 CALL
(HOLE1)
G1 F#<_jfeed> X5.375
O100 CALL
(HOME AND END)
G1 F20 Z0
G1 F30 X0 Y0
M30
Pause - M0
Syntax:
M0
Notes:
M0 is a pause M-code that pauses the program indefinitely until the pause button is pushed again. This is useful if you're making a run of parts, and you want pause in between re-jiggings.
Source:Lumenlab
Subscribe to:
Posts (Atom)