# Example G-Code Programs

LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org

It is safest to cut "air" first if you don't fully understand what will happen when you run g code.

## Contents

1. Cutting Gears with Loops
2. Cutting Splines with Loops
4. Using a while loop to make circular indents in the side of a hand wheel
5. Simple Turning example using IF
6. Convert Line-Line to Line-Arc-Line -- Use to Cut a Ratchet

## 1. Cutting Gears with Loops

``` (Following is my generic-gear.ngc:)
```

``` #1=25(number of teeth)
#2=[360/#1](angle to turn chuck)
#3=-.1(y clearance)
#4=-.05(X start of cut)
#5=2.2(X end of cut)
#6=0(starting A position)
#7=.7(feed rate infeed Y axis)
#8=.394(depth of cut)
#9=15(feed rate across X axis)
G0 X#4 Y#3
G0 Z0
G0 A0
M3 S70 M8
o200 do
G1 Y[#8-.04] F#7
G1 X#5 F#9
G1 Y#8
G1 X#4 F1.5
G0 Y#3
G0 X#4
#6=[#6+#2]
G0 A#6
o200 while[#6 lt 359.9]
M5 M9
M2
```
Notice that it does a rough cut across then climb mills back for a finish cut. Ed

## 2. Cutting Splines with Loops

``` (Following is my generic-spline.ngc:)
```

``` M6 T0
G43 H0
#1=27(number of splines)
#2=[360/#1](angle to turn chuck)
#3=-.1(y clearance)
#4=-.05(X start of spline)
#5=5(X end of spline)
#6=0(starting A position)
#7=3(feed rate)
#8=.088(depth of cut)
G0 X#4 Y#3
G0 Z0
G0 A#6
M3 S200 M8
o200 do
G1 Y#8 F#7
G1 X#5
G0 Y#3
G0 X#4
#6=[#6+#2]
G0 A#6
o200 while[#6 lt 359.9]
M5 M9
M2
```

``` similar to the gear but does all cutting in a single pass.
Both are using a cutter on an arbor in a vertical spindle.   Ed
```

``` (3/4-16 thread milling)
G0 X0 Y0 (rapid to location)
Z.1
G01 Z-1.020 F50.0
(your finish location will vary depending on conditions always start with a smaller cut until you establish exact finish location)
G91 G01 X.1275 F3.0 (incremental move to finish location speeds and feeds will vary with materials being cut)
G03 Z.0625 I-.1275 F4.0 (incremental 3 axis move creates right hand thread to establish Z movement divide 1 by thread pitch)
( 1 divided by 16 = .0625)
G90 G01 X0 F20.0 (absolute move back to start location)
G01 Z-1.020 (absolute move down to starting Z location)
G91 G01 X.1275 F6.0 (incremental move to finish location)
G03 Z.0625 I-.1275 F6.0 (incremental 3 axis move)
G03 Z.0625 I-.1275 F10.0 (optional free pass to remove any burrs)
G90 G01 X0 F20.0 (absolute move back to start location)
G0 Z3.0
M2
```

## 4. Using a while loop to make circular indents in the side of a hand wheel

``` cat 110_mill_grips.ngc
%
(mill grips on other side, 3/8mill=9.5mm, 12 deep)
(params)
#1=-15  (drill depth)
#2=10   (retraction interval)
#100=-12        (depth)
(fixed)
(speed)
F80
(reset)
G0 Z5
G0 X0 Y0
G4 P5
(start round)
#8=0    (angle in degrees)
#9=30   (angle increment in degrees)
O101 while [#8 lt 360]
#5=32.30        (first step and start)
#6=31.00        (second step)
#7=35           (safe circle)
(first step)
G0 Z1
G0 X[#5 * cos] Y[#5 * sin]
G1 Z[#100 + 0.06]
G1 X[#7 * cos] Y[#7 * sin]
(second step)
G0 Z1
G0 X[#6 * cos] Y[#6 * sin]
G1 Z#100
G1 X[#7 * cos] Y[#7 * sin]
(increment angle)
#8=[#8 + #9]
(wait)
(M0)
O101 endwhile
(end)
G0 Z5
G0 X1 Y-1
G1 X0 Y0
G0 Z20
%
```

## 5. Simple Turning example using IF

``` (simple turning)
(#100 = max Z = start Z > #101)
(#101 = min Z)
(#200 = max X = start X > #201)
(#201 = min X)
(#300 = feed)
(#400 = stepsize)
(Z)
#100 = 200
#101 = 0
(X)
#200 = 17
#201 = 14
(FEED)
#300 = 120
(STEP)
#400 = 1
(END OF PARAMETERS)
(set feed)
F#300
(set current X)
#250 = #200
O501 while [#250 gt #201]
#250 = [#250 - #400]
O502 if [#250 lt #201]
#250 =
O502 endif
(goto start point, safety x 1mm)
G0 X[#250 + #400 + 1]
G0 Z#100
G0 X#250
G1 F#300 Z#101
O501 endwhile
(retract to orig X)
(END)
G0 X[#200 + 1]
M2
```

## 6. Convert Line-Line to Line-Arc-Line -- Use to Cut a Ratchet

``` %
(Author: Kenneth Lerman)
(compute the intersection of two lines)
(<x1,y1> - <x2,y2> and <x3,y3> - <x4,y4>)
(returns: #<_xi> #<_yi>)
(#<_status> is 0 if OK)
(#<_status> is 1 if intersection is outside of one or both segments)
(#<_status> is 2 if lines are parallel)
(#<_status> is 3 if lines are coincident)
o<intersect> sub
#<x1> = #1
#<y1> = #2
#<x2> = #3
#<y2> = #4
#<x3> = #5
#<y3> = #6
#<x4> = #7
#<y4> = #8

;(print, intersect <#1,#2><#3,#4> <#5,#6><#7,#8>)
#<denom> = [[#<y4>-#<y3>]*[#<x2>-#<x1>]-[#<x4>-#<x3>]*[#<y2>-#<y1>]]
#<uaNum> = [[#<x4>-#<x3>]*[#<y1>-#<y3>]-[#<y4>-#<y3>]*[#<x1>-#<x3>]]
#<ubNum> = [[#<x2>-#<x1>]*[#<y1>-#<y3>]-[#<y2>-#<y1>]*[#<x1>-#<x3>]]

o<t> if [#<denom> EQ 0]
#<_status> = 2
o<tt> if [#<uaNum> EQ 0 AND #<ubNum> EQ 0]
#<_status> = 3
;(print, "Colinear lines")
o<tt> endif
o<intersect> return
o<t> endif
#<ua> = [#<uaNum>/#<denom>]
#<ub> = [#<ubNum>/#<denom>]

#<_xi> = [#<x1>+#<ua>*[#<x2>-#<x1>]]
#<_yi> = [#<y1>+#<ua>*[#<y2>-#<y1>]]

#<_status> = 0

(test for failure conditions)
o<t1> if[[#<ua> LT 0] OR [#<ua> GT 1]]
#<_status> = 1
o<t1> endif
o<t2> if[[#<ub> LT 0] OR [#<ub> GT 1]]
#<_status> = 1
o<t2> endif
o<intersect> endsub

(Given three points defining non-collinear line segments and given a radius)
(Convert them to two line segments with an arc connecting them)
(Input args in order: x0,y0 x1,y1 x2,y2 r  -- x1,y1 is the common point)
(Output: _xa,_ya,_xb,_yb, _status)
(Where: x0,y0 _xa,_ya define the 1st segment and _xb,_yb x2,y2 define the 2nd)
(_status = 0 for OK, _status = 1 for error -- usually radius too large)

o<linearc> sub
#<x0> = #1
#<y0> = #2
#<x1> = #3
#<y1> = #4
#<x2> = #5
#<y2> = #6
#<R> = #7

;(print, linearc <#<x0>,#<y0>> <#<x1>,#<y1>> <#<x2>,#<y2>> R #<R>)

(The A's correspond to the first line; the B's to the second)

(compute the normalized vectors)
#<dxA> = [#<x0>-#<x1>]
#<dyA> = [#<y0>-#<y1>]
#<normA> = [sqrt[#<dxA>**2+#<dyA>**2]]
#<NdxA> = [#<dxA>/#<normA>]
#<NdyA> = [#<dyA>/#<normA>]

(compute the first parallel line offset by R)
#<Rx0A_1> = [#<x0>+#<R>*#<NdyA>]
#<Ry0A_1> = [#<y0>-#<R>*#<NdxA>]
#<Rx1A_1> = [#<x1>+#<R>*#<NdyA>]
#<Ry1A_1> = [#<y1>-#<R>*#<NdxA>]

;(print, --1-- <#<Rx0A_1>,#<Ry0A_1>> <#<Rx1A_1>,#<Ry1A_1>>)

(compute the second parallel line offset by R)
#<Rx0A_2> = [#<x0>-#<R>*#<NdyA>]
#<Ry0A_2> = [#<y0>+#<R>*#<NdxA>]
#<Rx1A_2> = [#<x1>-#<R>*#<NdyA>]
#<Ry1A_2> = [#<y1>+#<R>*#<NdxA>]
;(print, --2-- <#<Rx0A_2>,#<Ry0A_2>> <#<Rx1A_2>,#<Ry1A_2>>)

(now do the same for the second line)

(compute the normalized vectors)
#<dxB> = [#<x2>-#<x1>]
#<dyB> = [#<y2>-#<y1>]
#<normB> = [sqrt[#<dxB>**2+#<dyB>**2]]
#<NdxB> = [#<dxB>/#<normB>]
#<NdyB> = [#<dyB>/#<normB>]

(compute the first parallel line offset by R)
#<Rx2B_1> = [#<x2>+#<R>*#<NdyB>]
#<Ry2B_1> = [#<y2>-#<R>*#<NdxB>]
#<Rx1B_1> = [#<x1>+#<R>*#<NdyB>]
#<Ry1B_1> = [#<y1>-#<R>*#<NdxB>]

(compute the second parallel line offset by R)
#<Rx2B_2> = [#<x2>-#<R>*#<NdyB>]
#<Ry2B_2> = [#<y2>+#<R>*#<NdxB>]
#<Rx1B_2> = [#<x1>-#<R>*#<NdyB>]
#<Ry1B_2> = [#<y1>+#<R>*#<NdxB>]

(now find a pair of line segments that intersect within the segments)

o<loop> do (we do not really loop -- this is so we can break)
o<intersect> call [#<Rx0A_1>][#<Ry0A_1>][#<Rx1A_1>][#<Ry1A_1>] [#<Rx2B_1>] [#<Ry2B_1>][#<Rx1B_1>][#<Ry1B_1>]
o<t1> if [#<_status> EQ 0]
;(print,1: x=#<_xi> y=#<_yi> status=#<_status>)
(now move the intersection back to the lines)
#<_xa> = [#<_xi>-#<R>*#<NdyA>]
#<_ya> = [#<_yi>+#<R>*#<NdxA>]
#<_xb> = [#<_xi>-#<R>*#<NdyB>]
#<_yb> = [#<_yi>+#<R>*#<NdxB>]
o<loop> break
o<t1> endif

o<intersect> call [#<Rx0A_2>][#<Ry0A_2>][#<Rx1A_2>][#<Ry1A_2>] [#<Rx2B_1>] [#<Ry2B_1>][#<Rx1B_1>][#<Ry1B_1>]
o<t2> if [#<_status> EQ 0]
;(print,2: x=#<_xi> y=#<_yi> status=#<_status>)
(now move the intersection back to the lines)
#<_xa> = [#<_xi>+#<R>*#<NdyA>]
#<_ya> = [#<_yi>-#<R>*#<NdxA>]
#<_xb> = [#<_xi>-#<R>*#<NdyB>]
#<_yb> = [#<_yi>+#<R>*#<NdxB>]
o<loop> break
o<t2> endif

o<intersect> call [#<Rx0A_1>][#<Ry0A_1>][#<Rx1A_1>][#<Ry1A_1>] [#<Rx2B_2>] [#<Ry2B_2>][#<Rx1B_2>][#<Ry1B_2>]
o<t3> if [#<_status> EQ 0]
;(print,3: x=#<_xi> y=#<_yi> status=#<_status>)
(now move the intersection back to the lines)
#<_xa> = [#<_xi>-#<R>*#<NdyA>]
#<_ya> = [#<_yi>+#<R>*#<NdxA>]
#<_xb> = [#<_xi>+#<R>*#<NdyB>]
#<_yb> = [#<_yi>-#<R>*#<NdxB>]
o<loop> break
o<t3> endif

o<intersect> call [#<Rx0A_2>][#<Ry0A_2>][#<Rx1A_2>][#<Ry1A_2>] [#<Rx2B_2>] [#<Ry2B_2>][#<Rx1B_2>][#<Ry1B_2>]
o<t4> if [#<_status> EQ 0]
;(print,4: x=#<_xi> y=#<_yi> status=#<_status>)
(now move the intersection back to the lines)
#<_xa> = [#<_xi>+#<R>*#<NdyA>]
#<_ya> = [#<_yi>-#<R>*#<NdxA>]
#<_xb> = [#<_xi>+#<R>*#<NdyB>]
#<_yb> = [#<_yi>-#<R>*#<NdxB>]
o<loop> break
o<t4> endif

(if we get here, we failed)
#<_status> = 1
;(print, failed)
o<linearc> return
o<loop> while  (the loop is a fake so we can break out)

(no need check that target point is within lines)
(if the intersection of the offset lines was OK, the translated one is too)
#<_status> = 0

o<linearc> endsub

o<drawlines> sub
o<linearc> call [#1][#2][#3][#4][#5][#6][#7]
(print, _xa=#<_xa> ya=#<_ya> xb=#<_xb> yb=#<_yb>)
g0 x#1 y#2
g1 f1 x#<_xa> y#<_ya>
g3 r#7 x#<_xb> y#<_yb>
g1 x#5 y#6
o<drawlines> endsub

;o<drawlines> call    
;o<drawlines> call    
;o<drawlines> call    
;o<drawlines> call    

;o<drawlines> call    

(print, ====================)
;o<intersect> call     
;(print, x=#<_xi> y=#<_yi> status=#<_status>)
;o<intersect> call [-5]   [-5] 
;(print, x=#<_xi> y=#<_yi> status=#<_status>)
;o<intersect> call [-5][-5]   [-5] 
;(print, x=#<_xi> y=#<_yi> status=#<_status>)

;o<intersect> call   [-5][-5]  [-5] 
;(print, x=#<_xi> y=#<_yi> status=#<_status>)
;o<intersect> call [-5][-5]   [-5] 
;(print, x=#<_xi> y=#<_yi> status=#<_status>)

(Cut a ratchet)
(Assumes center is at zero, zero)
(Assumes tool is at working depth and does not change Z)
(First tooth is at top -- max Y)
(Starting point is at above peak of first tooth and to left by at least toolD)
(End point will be in same general area)
o<ratchet> sub
#<id> = #1
#<od> = #2
#<N>  = #3
#<toolD> = #4
#<gulletR> = #5
#<peakR> = #6
#<feed> = #<_feed>

#<ir> = [#<id>/2]
#<or> = [#<od>/2]

#<delta> = [360/#<N>]
#<currA> = 0 (current angle)

g41.1 d#<toolD> (stay to left side)
g1 f#<feed> x0 y#<or>

#<x1> = [#<or> * sin[#<currA>]]
#<y1> = [#<or> * cos[#<currA>]]

o<loop> while [#<currA> LT 360]
#<currA> = [#<currA> + #<delta>]
#<x2> = [#<ir> * sin[#<currA>]]
#<y2> = [#<ir> * cos[#<currA>]]
#<x3> = [#<or> * sin[#<currA>]]
#<y3> = [#<or> * cos[#<currA>]]

o<linearc> call [#<x1>][#<y1>] [#<x2>][#<y2>] [#<x3>][#<y3>] [#<gulletR>]
o<t1> if [#<_status> NE 0]
(print, status NE 0)
o<ratchet> return
o<t1> endif
g1 f#<feed> x#<_xa> y#<_ya>

g3 f#<feed> r#<gulletR> x#<_xb> y#<_yb>

#<x1> = #<x2>
#<y1> = #<y2>
#<x2> = #<x3>
#<y2> = #<y3>

#<x3> = [#<ir> * sin[#<currA>+#<delta>]]
#<y3> = [#<ir> * cos[#<currA>+#<delta>]]

o<linearc> call [#<x1>][#<y1>] [#<x2>][#<y2>] [#<x3>][#<y3>] [#<peakR>]
o<t2> if [#<_status> NE 0]
o<ratchet> return
o<t2> endif
g1 f#<feed> x#<_xa> y#<_ya>
g2 f#<feed> r#<peakR> x#<_xb> y#<_yb>
(we are now at the head of the next angle)

#<x1> = #<x2>
#<y1> = #<y2>
#<x2> = #<x3>
#<y2> = #<y3>

o<loop> endwhile

o<ratchet> endsub

#<_feed> = 5.0

g40 (cutter comp off)

;g54
;g1 f#<_feed> x0 y0
g1 f#<_feed> y[[5.0/2]+[2*.250]] x[0-[2*.250]]
o<ratchet> call [4.0][5.0][.250][.126][.0625]

m2
%
```

## 7. Links to other Examples

LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org