How to Write a Program for the CNC Milling Machine
This guide walks through the order we use on the shop floor to write a program for the CNC milling machine, from reading the drawing to proving the first article. It is written for engineers and shop programmers who need a repeatable sequence, not a list of G-codes. By the end you will know which decisions must be locked before the first block is posted, and which ones can wait until the dry run.

In this article
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
Key takeaways
Read the drawing like a machinist
The programming work starts on paper, not in CAM. Open the drawing and mark the functional surfaces: the faces that mate with other parts, the bores that carry bearings, the threads that take fasteners. Those are the features that set the tolerance stack. Everything else can float within general tolerances.
Next, list the datums. A bore that positions to a face can only be inspected if that face is machined first. If the drawing calls out a datum that cannot be touched in the first setup, you have to plan two operations and accept the re-fixturing error. Experienced programmers spot this before quoting. Fixing it after the program is written means rewriting the whole sequence.
Check for tool reach. A deep pocket with a corner radius of 3 mm needs a cutter small enough to fit, and a holder slim enough to clear the walls. If the wall is 60 mm tall and the pocket is 12 mm wide, a standard ER holder will rub. That is a 5-axis or long-reach toolpath, and it changes the program structure.
Finally, confirm the stock. For aluminium plate, 2 mm of allowance per side is normal. For a casting that already has bosses and cores, the programme cuts air in some areas and heavy stock in others. Write down the actual stock condition, because that number drives the first roughing pass.
- 1Mark functional facesThese carry the fit, so they set the tolerance stack.
- 2List datums in machining orderA datum that cannot be cut first forces a second setup.
- 3Check tool reachCompare pocket depth against holder diameter before you choose a cutter.
- 4Measure the real stockCastings and weldments are not uniform; the program must cover the worst case.
Choose the right programming environment
Manual G-code is still the fastest route for simple parts: a plate with a few holes, a face mill pass, a chamfer. On a 3-axis machine, a hand-written program of 40 lines is easier to verify than a CAM file with 4,000 moves. If the part is rectangular, has no complex curves and needs two or three tools, write it by hand.
CAM software takes over when the geometry gets curved. A sculpted rib on a robot joint, a tapered pocket, a 3D surface, a 5-axis toolpath, all need a CAM system. The software also handles stock awareness, rest machining and collision checks. That saves hours compared with writing point-to-point moves.
Whichever route you choose, the post-processor matters more than the software brand. A post that outputs the wrong G-code for your control will send the machine to the wrong place. We run 127 high-precision CNC machines, 16 of which are simultaneous 5-axis centres, and each machine family has its own post. Test the post on a scrap block before you trust it with production.
Keep a checklist of the control-specific quirks: how the machine handles G28, whether the tool change uses a safe Z, whether the spindle needs an M19 orientation before a probe. These details belong in the post, not in the operator's head.
- 1Manual G-codeBest for 2.5D plates, drilled holes and simple pockets.
- 2CAM softwareRequired for curved surfaces and 4-axis or 5-axis work.
- 3Post-processorOne per machine family. Test it on scrap before production.
Set the work coordinate system and tool offsets
The work coordinate system tells the machine where the part sits. Pick the corner or centre that the operator can touch with an edge finder or probe. On a vise, the fixed jaw and the top face are the usual choice. On a fixture plate, use a dowel pin hole. The rule is simple: the WCS must be reachable with the tools the operator actually has.
Use G54 for op 1 and G55 for op 2. Do not reuse G54 on a second vise unless the vises are dialled in together. If you have three parts on the table, give each one its own offset. This avoids the classic mistake of running a program on the wrong position and cutting into the fixture.
Tool offsets are separate from work offsets. Each tool needs its length measured and stored in the tool offset register. Radius compensation, when used, must match the cutter diameter in the program. If you program to the centreline, you do not need cutter comp, but you must adjust the toolpath when the cutter wears. For a ±0.005 mm bore, use cutter comp and adjust the offset after the first article.
Record the Z zero on the top of the stock or on a gauge block. Never leave the operator guessing which surface was used. Write the Z reference on the setup sheet, and note the tool number used to touch it off.
- 1G54 = op 1G55 = op 2. One offset per setup, not per program.
- 2Touch-off surfaceUse a face the operator can reach with a probe or edge finder.
- 3Cutter compUse it when the feature tolerance is tighter than the cutter wear band.
- 4Write it downPut the Z reference and tool number on the setup sheet.
Pick tools and cutting parameters
Start with the smallest radius in the part. If the drawing shows a 4 mm inside corner, the largest cutter that can clean it is 8 mm, and you need a 4 mm or smaller tool for the corner itself. Choose the largest tool that fits the feature, because a bigger cutter is stiffer and removes metal faster.
For aluminium, a 3-flute carbide end mill at 12 mm diameter runs well at 8,000–12,000 rpm with a feed of 0.08–0.12 mm per tooth. That gives a chipload the cutter can survive and a surface finish near Ra 0.8–1.6 μm. For stainless 304, drop the surface speed to 80–120 m/min and keep the chipload above 0.03 mm per tooth. Too light a chip work-hardens the material.
Titanium and Inconel need more care. Ti-6Al-4V cuts at 40–60 m/min with high-pressure coolant and a chipload around 0.05 mm per tooth. Inconel is slower still, 20–30 m/min, and the tool must never rub. If the chips come off as dust, you are rubbing, not cutting. Increase the feed or reduce the speed.
Depth of cut matters as much as speed. For roughing aluminium, axial depth of 1 × D and radial width of 0.4 × D is a common starting point with a 3-flute cutter. For stainless, reduce axial depth to 0.5 × D. For finishing, take 0.2–0.5 mm radial and full axial depth to avoid witness marks.
- 1Largest tool that fitsStiffer cutter, fewer passes, better finish.
- 2Aluminium 60613-flute, 0.08–0.12 mm/tooth, 8,000–12,000 rpm at Ø12 mm.
- 3Stainless 30480–120 m/min, keep chipload above 0.03 mm/tooth.
- 4Titanium and Inconel40–60 m/min and 20–30 m/min. Never let the tool rub.
Simulate, dry run and tune the first part
Simulation catches collisions, not bad cutting data. Run the CAM simulation with the actual holder and fixture models. Check that the tool does not hit the vise, the clamps or the table. If the simulation shows a rapid move through the part, fix the clearance plane before you post.
The dry run is the real test. Raise Z by 50 mm and run the program with the spindle off, feed override at 50%. Watch the tool path, the tool changes and the coolant. If the machine has a graphics mode, use it first, then do the dry run. A crash at this stage costs nothing but time.
For the first article, cut the part and measure every dimension on the drawing. Check the critical bores with a bore gauge, the flatness with a surface plate, and the surface finish against the Ra callout. If a bore is 0.02 mm undersize, adjust the cutter comp and run the finish pass again. Do not adjust the program geometry unless the error is consistent across the whole batch.
Once the first article passes, lock the program. Save it with the offset values, tool list and inspection report. The next run should not need a programmer. That is the difference between a one-off and a repeatable process.
- 1Simulate with fixturesHolder and clamp models catch the collisions CAM misses.
- 2Dry run at +50 mmSpindle off, 50% feed override, watch every tool change.
- 3Measure the first articleBore gauge, surface plate and Ra check against the drawing.
- 4Lock and archiveOffsets, tool list and inspection notes go with the program.
Step-by-step programming sequence
Follow this order on every new part. Skipping a step usually shows up as a scrapped first article.
- 1Draw the setup sheetSketch the part on the vise or fixture. Mark the WCS origin, the Z reference and the tool numbers. Include the stock size and the first-operation face.
- 2Choose the tool listPick the largest cutter that fits the smallest internal radius. Add a face mill, a roughing end mill, a finisher, a drill and a chamfer tool. Keep the list under eight tools if possible.
- 3Set the cutting dataFor aluminium 6061, start at 8,000–12,000 rpm and 0.08–0.12 mm per tooth. For stainless 304, 80–120 m/min surface speed and 0.03 mm minimum chipload. Adjust after the first pass.
- 4Program the roughing passUse 1 × D axial and 0.4 × D radial for aluminium. Leave 0.3–0.5 mm on walls and floors for the finisher. Include a 2 mm clearance plane above the stock.
- 5Program the finishing passUse cutter comp for bores and profiles tighter than ±0.05 mm. Take 0.2–0.5 mm radial and full axial depth. Keep the feed constant through corners.
- 6Simulate and dry runSimulate with holder and fixture models. Then dry run at +50 mm Z with the spindle off and feed override at 50%.
- 7Cut and inspect the first articleMeasure the critical features. Adjust cutter comp for size, not the program geometry. Record the offsets that produced a good part.
- 8Document and releaseSave the program with the setup sheet, tool list and inspection report. The next run should not need a programmer.
Programming choices by part type
Use this table to decide the programming route before you open CAM.
| Part feature | Programming route | Key parameter | Common mistake |
|---|---|---|---|
| Flat plate with drilled holes | Manual G-code | G81 drill cycle, 3 mm peck | Forgetting the initial point above stock |
| 2.5D pocket with sharp corners | CAM 2D pocket | 4 mm cutter for 4 mm corner radius | Using a cutter larger than the corner |
| Curved surface, 3-axis | CAM 3D surfacing | 0.2 mm stepover for Ra 0.8 μm | Too coarse a stepover, visible scallops |
| Undercut or deep rib | CAM 5-axis | Tool axis tilt 15–30° | Programming 3-axis and hitting the holder |
| Turned-milled shaft | Mill-turn centre | B-axis interpolation | Separate ops lose concentricity |
| Thin-wall aluminium housing | CAM with rest machining | 0.3 mm radial finish pass | Full-width cut bows the wall |
| Hardened tool steel insert | CAM with high-feed cutter | 0.5 mm axial, 0.3 mm radial | Rubbing instead of cutting |
Fix the process before you fix the code
Most scrapped first articles come from a missing setup sheet, not a bad toolpath. Lock the WCS, tool list and cutting data, then write the program around them.
Frequently asked questions
Can I write a program for the CNC milling machine without CAM software?
Yes, for simple 2.5D parts. Manual G-code is faster to write and easier to verify when the part is a plate with holes, slots and a face mill pass.
Once the part has curved surfaces, deep pockets or 5-axis features, CAM software saves time and reduces the risk of a collision. The post-processor must match the machine control either way.
What is the difference between cutter compensation and programming to the centreline?
Cutter compensation lets you adjust the toolpath by changing the offset value at the machine. You program the finished profile and the control shifts the path by the cutter radius.
Programming to the centreline means the toolpath is already offset in CAM. It works, but every size adjustment needs a new program. For bores and profiles tighter than ±0.05 mm, cutter comp is the practical choice.
How do I choose the feed rate for a new material?
Start with the surface speed. Aluminium runs at 200–400 m/min, stainless 304 at 80–120 m/min, Ti-6Al-4V at 40–60 m/min and Inconel at 20–30 m/min.
Convert surface speed to rpm with the cutter diameter, then set the chipload per tooth. A 3-flute Ø12 mm cutter in aluminium at 10,000 rpm and 0.10 mm per tooth gives a feed of 3,000 mm/min.
Why does the first article need a dry run?
Simulation uses a model of the machine. The dry run uses the real machine, the real fixture and the real offsets. It catches wrong offsets, wrong tool numbers and clearance planes that are too low.
Run it with the spindle off, Z raised by 50 mm and feed override at 50%. A crash at this stage costs time, not a spindle.
When should I hand the program to a machining service instead?
When the part needs 5-axis access, when the tolerance is ±0.005 mm across multiple features, or when the fixture itself has to be designed and built.
We run 127 high-precision CNC machines across three plants and quote with a free DFM analysis within 12 hours. Production can start within 24 hours of approval.
What documentation should ship with a proven program?
The setup sheet with WCS and Z reference, the tool list with offsets, the cutting data used, the inspection report and the program file with its revision number.
That package lets a second operator run the job without reprogramming. It also makes the next revision easier to plan.
Send us the drawing, get a program-ready quote
Upload your CAD files and we will return a quotation with a free DFM analysis within 12 hours. No minimum order quantity, from one prototype to 10,000+ parts.
12-hour quoteFree DFM analysis100% inspection before shipment