Skip to content

Writing and Reviewing CNC Programs: Hand Code and CAM Output

20 min read Training Guide

Structure a program so it restarts safely, use subprograms and macros, review CAM output for what the software cannot see, and check another person's code.

Table of contents

At the senior level, you stop reading programs for what they do and start judging whether they are any good. Can it restart after a broken tool? Will it run the same way on nights? Does the feed in the code match the feed the machine can really deliver? Did the CAM system (computer-aided manufacturing software) know about the clamp, the holder and the real stock? You also become the person who signs off on other people's code. The examples are Fanuc-style. Macro and high-speed features vary by control and installed options, so check your own manual. Reminder: any new or changed program gets a dry run, then single block at reduced feed.

What You Will Be Able to Do

  • Lay out a program so each tool stands alone and restarts cleanly.
  • Use subprograms and macro variables, and guard against their failure modes.
  • Correct feed for arcs, and work out when short blocks limit the real feed.
  • Review CAM output for what the software cannot know.
  • Check another person's program by a repeatable method.

A Structure That Survives Restarts

A good program assumes nothing about what ran before. Every tool block rebuilds the full state, so anyone can restart at any tool.

%
O2140 (BRACKET OP1 REV C)
(T1 3.0 FACE MILL / T2 1/2 END MILL / T3 1/4 DRILL)
N10 G20 G17 G40 G49 G80 G90

(T1 FACE TOP)
N100 T1 M06
N101 G90 G54 G00 X-2.0 Y1.0 S1200 M03
N102 G43 H01 Z1.0 M08
N103 G01 Z0 F40.0
N104 X7.0 F30.0
N105 G00 Z1.0 M09
N106 G91 G28 Z0
N107 G90
N108 M01

(T2 PROFILE)
N200 T2 M06
N201 G90 G54 G00 X-1.0 Y-1.0 S3400 M03
N202 G43 H02 Z1.0 M08

The rules behind this layout:

  1. Each tool block stands alone. G90, the work offset, the spindle and G43 all appear again after every tool change.
  2. N numbers follow the tool. N200 means tool 2. An operator can find a restart point at a glance.
  3. Each block cleans up. Cancel compensation and canned cycles, retract, and stop coolant before the next tool.
  4. M01 at the end of each tool. It gives the setup person a place to stop and check.
  5. Decimal points on every position and feed. No exceptions.
  6. Comments state intent. Stale comments are worse than none, so update them with the code.

Subprograms

A subprogram holds code that repeats. M98 calls it, and M99 returns. Use one when the same moves happen many times, such as several parts on one table.

(MAIN - FOUR VISES)
N10 G54
N20 M98 P2141
N30 G55
N40 M98 P2141
N50 G56
N60 M98 P2141
N70 G57
N80 M98 P2141

Note what this does and does not do. It machines each part completely before moving to the next, so every tool is changed for each vise. If each part needs 5 tools, that is 20 tool changes.

A better order runs one tool across all four vises, with a subprogram for each tool. That is 5 tool changes. At 6 seconds each, you save 15 x 6 = 90 seconds per cycle. The trade-off is that a broken tool now affects four parts, and the restart logic takes more thought.

Subprogram traps:

  • A subprogram that switches to G91 must switch back to G90 before M99. If it does not, the main program runs in incremental mode.
  • Any modal code changed in a subprogram stays changed on return.
  • A wrong repeat count in an M98 line repeats a move you did not plan.
  • A subprogram that is stored separately has its own revision. Editing it can change every program that calls it.

Macro Variables

Custom macro programming lets a program use variables, math and logic. It is an option on many controls. Use it where it earns its keep: part families, probing, and logic checks.

Variables Typical use Watch for
#1 to #33 Local, passed to a macro call Cleared when the macro ends
#100 to #199 Common, shared between programs Usually lost at power-off
#500 and up Common, kept through power-off Another program may use the same number
System variables Read or write offsets, positions, alarms Numbers differ by control

Worked example: a bolt circle. Six holes sit on a 3.000-inch circle, starting at 30 degrees.

#1=1.5  (RADIUS)
#2=6    (NUMBER OF HOLES)
#3=30.0 (START ANGLE)
#4=0    (COUNTER)
G99 G81 Z-0.5 R0.1 F6.0 L0
WHILE [#4 LT #2] DO1
#5=#3+[#4*360/#2]
X[#1*COS[#5]] Y[#1*SIN[#5]]
#4=#4+1
END1
G80

The L0 stores the cycle without drilling at the current spot, and some controls use K0 for this. Check the math by hand before you trust it. At 30 degrees, X = 1.5 x 0.8660 = 1.2990 and Y = 1.5 x 0.5000 = 0.7500. The next hole, at 90 degrees, is X 0, Y 1.5. Run it in graphics or with the Z raised, and compare the first two positions with your numbers.

Add guards. A macro can write a bad number with total confidence, so make it stop when a value makes no sense. In this probing example, #100 holds a measured size error.

IF [ABS[#100] GT 0.005] THEN #3000=1 (SIZE ERROR TOO LARGE)

Writing #3000 raises an alarm and stops the program. Without a check like this, a chip on the probe could send a large correction into the wear offset, and the next part would be scrap, or worse.

Writing offsets from a program. G10 can set a work offset from code, such as G10 L2 P1 X-18.3620 Y-9.1250. That is handy on a fixed fixture and dangerous elsewhere. It overwrites the setup person's value with no warning. In G91 mode it adds to the value instead of replacing it. Use it only with a clear reason, and flag it on the setup sheet.

Feed Rate on Arcs

The control applies F to the center of the tool. The cutting edge is what matters. On an inside arc, the edge travels farther than the center, so the real feed at the edge is higher than the programmed one.

Feed at center = edge feed x (arc radius - tool radius) / arc radius

Worked example. A 1/2-inch end mill (radius 0.250) cuts an inside corner with a 1.000 radius. You want 40 inches per minute at the edge.

Feed at center = 40 x (1.000 - 0.250) / 1.000 = 30 IPM

If you left F40.0 in the code, the edge would run at about 53 IPM in the corner, a third over target, just where the tool wraps around the most material. That is where tools break. For an outside arc, the correction goes the other way: multiply by (arc radius + tool radius) / arc radius. Many CAM systems do this for you. Check whether yours is set to.

Reviewing CAM Output

CAM software builds a toolpath from a model. It knows only what somebody told it. Your review looks for the gap between that model and the real machine.

Check Question What goes wrong
Post processor Is it the right post and version for this machine? Codes the control rejects, or reads differently
Work zero Does the program's zero match the setup sheet? Whole job runs in the wrong place
Stock Is the model the real stock, including casting skin or extra? Rapid into material the model did not have
Tool and holder Is the real holder and stickout modeled? Holder hits a wall the tool cleared
Fixture Are clamps and jaws in the model? Crash on a linking move
Compensation type Computer, control or wear? Wrong D value, every wall off
Linking moves Are rapids above all material? Rapid across a boss
Lead-ins Are ramps and plunges right for the tool? A square end mill plunged straight into solid metal

The compensation trap. In computer compensation, CAM has already offset the path, and no G41 is posted. In control compensation, the code follows the part line and the D value holds the full tool radius. In wear compensation, the path is already offset and G41 is posted, so D holds only a small correction near zero. Put a full radius in D on a wear-type program and every wall moves over by a full tool radius. So the setup sheet has to say which type was used.

Short Blocks Can Starve the Control

A 3D toolpath is made of many short lines. A control takes a set time to process each block. If the blocks go by faster than that, the machine slows down whatever F says.

Worked example. A surfacing path has segments 0.002 inch long at F100.0.

  1. 100 IPM is 100 / 60 = 1.67 inches a second.
  2. That needs 1.67 / 0.002 = 833 blocks a second.
  3. Say your control processes a block in 4 milliseconds. That gives 250 blocks a second.
  4. The fastest real feed is 0.002 x 250 x 60 = 30 IPM.

The screen says 100, and the machine does 30. Your cycle time is more than three times what CAM predicted. The chip load falls too, so the tool may rub. Find your control's real rate in its specifications. Your options are to loosen the CAM tolerance where the print allows it, output arcs instead of lines, or use the control's look-ahead mode.

A look-ahead or high-speed mode, such as G05.1 on many Fanuc controls where the option is installed, reads ahead and plans speed through the moves. It can smooth the path, which rounds sharp corners slightly. The setting decides how much. Learn it before you use it on a finish pass with a tight tolerance.

CAM Tolerance and Scallop

CAM tolerance sets how far the line segments may stray from the true surface. It adds to your other errors, so a common practice is to keep it to about a tenth of the print tolerance for finish passes. Tighter settings make longer files and shorter blocks, which leads back to the problem above.

A ball end mill also leaves ridges between passes, called scallops. For small stepovers:

Scallop height = stepover squared / (8 x tool radius)

Worked example. A 1/4-inch ball (radius 0.125) with a 0.010 stepover leaves 0.0001 / 1.0 = 0.0001 inch, or 100 microinches of height. Halving the stepover cuts the scallop to a quarter, and it doubles the time. Choose based on the finish the print requires.

Simulation Levels

Level What it reads What it catches
Backplot The CAM toolpath Obvious path errors
Code simulation The posted G-code Post errors, wrong offsets, codes
Machine simulation Code plus machine, fixture, holders Collisions, travel limits, rotary moves

A clean backplot proves the path, not the code. On 5-axis work or a tight fixture, simulate the posted code on a model of the real machine. Even then, the model is only as good as the setup that matches it.

Checking Another Person's Program

Use the same method every time, so that you are not relying on spotting things.

  1. Confirm the print revision, the program number and the setup sheet agree.
  2. Read the tool list against the tools and holders that will be used.
  3. For each tool, check the T, H and D numbers, then S and F against the tool data.
  4. Check the Z depths against the print. Does anything cut deeper than the part or the fixture allows?
  5. Check every rapid near material or clamps.
  6. Check that compensation, cycles and modes are canceled.
  7. Check the restart blocks.
  8. Check the end of the program for a safe stop position.

Worked example. The tool list says T4 is a 1/4-inch carbide drill in steel, at 200 SFM and 0.004 IPR. You find:

N400 T4 M06
N401 G90 G54 G00 X2.0 Y1.5 S8200 M03
N402 G43 H5 Z0.1 M08
N403 G99 G83 Z-2.5 Q0.75 R0.1 F18.0

Four problems stand out:

  • H5 with T4. The wrong tool length is active, unless the setup sheet explains it.
  • S8200. The right speed is 200 x 3.82 / 0.25 = about 3,056 RPM. S8200 is over 530 SFM, which would burn up the drill.
  • F18.0. At 3,056 RPM and 0.004 IPR, the feed should be about 12.2 IPM.
  • Q0.75. That is a peck of three drill diameters into a hole 10 diameters deep. Chips will pack. A smaller Q and a check for through-coolant are in order.

There is a fifth question. Z0.1 as the first height with G99 leaves little room if a clamp sits between holes. Check the fixture.

Controlling the Final Program

Decide where the truth lives. If you edit posted code by hand and someone reposts from CAM, your edit is gone. So any change that must last belongs in the CAM file, with a new revision. Hand edits are fine for small hand-written programs, or as a short-term fix with a tracked change. For a released job, a change to the process can also trigger a new first article, so bring quality in.

Common Mistakes

Mistake What it costs
Tool blocks that depend on earlier lines A crash on restart
Leaving G91 active at the end of a subprogram The main program moves to the wrong place
Macro writing offsets with no limit check One bad reading ruins parts
Ignoring feed on tight inside arcs Broken tools in corners
Trusting F on dense 3D paths Cycle time and chip load are not what you planned
Reviewing only the backplot Post and holder errors reach the machine
Hand edits in posted code Lost at the next repost

Check Your Understanding

1. A mold surfacing job takes three times longer than CAM predicted, and the feed display never reaches F. Nothing is alarming. Where do you look?

At segment length and the control's block rate. Short blocks may be capping the real feed. Loosen the CAM tolerance where the print allows it, output arcs, or use a look-ahead mode.

2. A tool rounds an outside corner at the same F as the straight wall. What happens at the cutting edge, and how do you correct it?

On an outside arc, the edge travels a shorter path than the center, so the edge feed drops. Multiply the feed by (arc radius + tool radius) / arc radius to hold it.

3. A new setup person asks why the setup sheet has to name the CAM compensation type. What do you tell them?

Because the same D register means different things. With control compensation it holds the full tool radius, and with wear compensation it holds a small correction near zero. A wrong guess moves every wall.

4. A macro updates a wear offset from a probe reading. What should you add before you trust it?

A range check that raises an alarm if the measured error is too large, so a dirty stylus or a bad reading cannot write a big correction.

5. An operator fixes a feed in a posted program, and it runs better. What needs to happen next?

The change has to go back into the CAM file or the master, with a new revision and a record. Otherwise it is lost at the next repost.

Key Takeaways

  • Every tool block rebuilds the full state, so anyone can restart at any tool.
  • Subprograms save lines and hide traps. Restore modes before M99.
  • Macros need limit checks. Hand-check the first results.
  • The tool center feed is not the edge feed on an arc, and F is not the real feed on dense paths.
  • CAM only knows what it was told. Check stock, holders, fixtures and compensation type.
  • Review by a fixed method, and keep lasting changes in the master file.