How to Code a CNC Machine
This page explains how to code a CNC machine from a blank editor to a proven program: G-code structure, work offsets, tool data, feeds and speeds, and the dry-run checks that catch collisions before the spindle turns. It is written for design engineers and shop programmers who already read a drawing and now need to turn it into machine motion. By the end you can judge which parts should be hand-coded, which need CAM, and where a posted program usually fails.

In this article
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
Key takeaways
What G-code actually is and how a control reads it
A CNC program is a plain text file. Each line is called a block, and each block holds words made of a letter address plus a value: G for preparatory commands, M for machine functions, X, Y, Z for coordinates, F for feed rate, S for spindle speed, T for tool number. The control reads blocks in order, from top to bottom, and executes them as soon as they are buffered. There is no compiler and no error list at the end. A bad line just moves the machine to the wrong place.
Most mills run in G17 (XY plane) with G90 absolute positioning and G21 metric units. Those three codes appear near the top of nearly every program. G91 incremental mode moves by distance from the current point instead of to an absolute coordinate, and it is easy to mix the two by accident. If a tool suddenly plunges to the table, check for a missing G90 before you check anything else.
A typical block looks like N40 G01 X25.0 Y12.0 Z-3.0 F250. The N number is a sequence label, useful when the operator needs to restart mid-program. The F word is modal, meaning it stays active until another F appears. The same is true for G codes in the same group. This is why one forgotten F can make the next twenty blocks feed at the previous value.
- 1G00 rapidPositioning move at machine maximum, never for cutting.
- 2G01 linearStraight cut at the programmed feed rate.
- 3G02 / G03Clockwise and counter-clockwise arcs, need I, J or R.
- 4G43 tool lengthApplies the tool length offset with H.
Set work offsets and tool data before writing a single cut
Coordinates in the program are not machine coordinates. They are positions inside a work offset, usually G54 to G59. The operator touches the part with an edge finder or probe, stores the X, Y, and Z origin in the G54 page, and the program runs relative to that point. Decide the datum before coding. On a milled plate, a common choice is the finished top face for Z0 and one finished corner for X0 Y0. On a turned part, Z0 is normally the finished face and X0 is the spindle centerline.
Tool length offsets are the second half of setup. Each tool has a length stored in the offset table, and G43 H01 pulls that value into the active position. If the length is wrong by 0.5 mm, the tool cuts 0.5 mm too deep. Renishaw-style probes and tool setters remove most of this risk, but the programmer still has to call the right H number. A mismatch between T03 in the program and H03 in the table is one of the most common crash causes in a job shop.
Write the setup sheet as you code. List every tool, its diameter, its corner radius, the holder, the offset number, and the Z depth it reaches. The operator reads that sheet, not your program. If a Ø6 mm flat end mill is listed as Ø6 mm but the CAM library says 5.8 mm, the wall will be undersized and no one will know until inspection.
How to calculate feeds and speeds that survive real material
Start with surface speed, not with a number copied from a chart. For aluminum 6061, a carbide end mill runs well at 300 to 500 m/min surface speed. For 304 stainless, drop to 60 to 120 m/min. For Ti-6Al-4V, stay near 30 to 60 m/min and keep the tool moving. Spindle speed follows from surface speed and tool diameter: rpm = (surface speed × 1000) ÷ (π × diameter). A Ø10 mm carbide tool in aluminum at 400 m/min gives roughly 12,700 rpm, which is why small tools need a fast spindle.
Feed per tooth is where most beginners go wrong. The formula is feed rate = rpm × number of teeth × chip load. A Ø10 mm three-flute carbide end mill in 6061 takes a chip load around 0.05 to 0.10 mm per tooth for roughing. At 12,700 rpm and three teeth, that is 1,900 to 3,800 mm/min. Writing F250 for that cut leaves a lot of cycle time on the table and rubs the edge instead of cutting it.
Depth and width of cut matter as much as speed. For a full-width slot in aluminum, keep axial depth around 0.5 × diameter. For a trochoidal or high-efficiency path, you can go 1 × diameter deep with 10 to 15 percent radial engagement. In stainless and titanium, reduce radial engagement and keep the cutter in the cut rather than letting it dwell. Heat leaves with the chip, so a heavier chip is often safer than a light one.
- 1Aluminum 6061300–500 m/min, 3-flute carbide, chip load 0.05–0.10 mm/tooth.
- 2Stainless 30460–120 m/min, 4-flute, chip load 0.02–0.05 mm/tooth.
- 3Ti-6Al-4V30–60 m/min, 4-flute, chip load 0.02–0.04 mm/tooth.
- 4POM and ABS150–400 m/min, 2-flute, watch for chip welding.
When to hand-code and when to post from CAM
Hand-coding wins on simple work. A plate with six holes, a face, and an outside profile is often faster to write than to model, set up toolpaths, and post. The program is short, easy to read at the machine, and easy to edit when the operator wants to change a depth. Shops that do a lot of fixture plates, brackets, and one-off repair parts keep a library of hand-written templates for exactly this reason.
CAM wins once the geometry stops being 2.5D. A pocket with a drafted wall, a fillet that blends into a curved floor, or any surface described by a solid model needs a posted toolpath. The same is true for 5-axis work, where the machine has to coordinate two rotary axes with the linear axes. Writing that by hand is possible in theory and a waste of time in practice. Post-processor output also carries the correct G68.2 or TCPC codes for the specific control.
A mixed workflow is normal. Use CAM for the surfacing pass, then hand-edit the posted file to add the facing operation, the deburr pass, and a safe retract. Just remember that every manual edit is a chance to break the modal state. If you delete a G43 line, the next tool change runs without a length offset. Keep an original copy of the posted file and note what you changed.
Structure of a clean program, line by line
A safe program starts with a header. Cancel any active compensation with G40, cancel cutter comp and offsets, call G17 G21 G90, then call the work offset. Bring the spindle up to speed only after the tool is clear of the part. A typical opening is G40 G49 G80, then G17 G21 G90, then G54, then G43 H01 Z50.0. That Z move puts the tool 50 mm above the datum before anything else happens.
Body blocks follow the operation order: face, spot drill, drill, tap, rough pocket, finish profile. Each tool change should include a safe Z retract, an M09 to stop coolant, an M05 to stop the spindle, then T and M06. After the change, restart the spindle with the correct S and direction with M03, turn coolant back on with M08, and re-apply the length offset. Programs that skip the retract before a tool change are the ones that drag a tool across the fixture.
End the program with M09, M05, a retract to a safe Z, and M30. M30 resets the program and rewinds it. If the machine has a chip conveyor or a bar feeder, the M-code sequence for those devices has to be checked against the machine manual. Do not assume M30 means the same thing on a Fanuc lathe and a Heidenhain mill.
- 1HeaderSafety cancels, units, plane, work offset, first tool length.
- 2BodyOne operation per section, with a comment line above each.
- 3FooterCoolant off, spindle off, retract, M30.
Common coding mistakes and how to avoid them
The most expensive mistakes are quiet ones. A missing decimal point turns X25.0 into X250. A G91 left active from a previous section makes every following move incremental. A tool length offset applied twice doubles the depth. None of these throw an alarm before the cut. The control does exactly what the block says, which is why the dry run is not optional.
Cutter compensation is another frequent source of scrap. G41 and G42 offset the path to the left or right of the programmed line, and they must be cancelled with G40 before the next rapid. If the compensation is active while the tool moves to a clearance plane, the control may alarm or, worse, swing wide into the fixture. Lead-in moves should be at least the tool radius long so the compensation has room to engage.
Finally, keep the program readable. Comments cost nothing and save hours during setup. Group operations, label the sections, and use consistent formatting. An operator who can read the program can catch a problem before it becomes a crash, and a programmer who can read it six months later can revise it without starting over.
Step by step: how to code a CNC machine from drawing to first article
- 11. Read the drawing and pick the datumIdentify the critical tolerances first. A ±0.005 mm bore sets the process, not the outside profile. Choose a datum that the operator can touch and that inspection can repeat. Note any surface finish callout such as Ra 0.8–1.6 μm, because it changes the finishing pass.
- 22. Plan the operation order and tool listFace first, then spot drill, then drill, then rough, then finish. Keep the tool count low. Assign each tool a number and a length offset. Write the list down before you open the editor, because changing the order later means renumbering every H and T call.
- 33. Write the header and safety blockStart with G40 G49 G80, then G17 G21 G90, then the work offset G54. Add a comment with the part number, the program version, and the date. Never start the spindle with the tool at the datum; move to a safe Z first, typically 50 to 100 mm above the part.
- 44. Code each operation with commentsOne comment line above each section, in plain text, so the operator can search for it. Use G81 for standard drilling, G83 for deep holes with a peck, and G84 for tapping. Set the R plane 2 to 5 mm above the surface and the Z depth to the full drill point, not the shoulder.
- 55. Set feeds and speeds from the materialUse the surface speed and chip load ranges for the workpiece material, not the tool catalog maximum. Reduce by 20 percent for the first article and raise it only after the chips look right. Listen for chatter and check the chip color; blue chips in aluminum mean the speed is too high.
- 66. Dry run in air with offsets raisedRaise the Z work offset by 50 mm, or use the control's dry-run and single-block modes. Step through every tool change and watch the distance-to-go display. This is where you catch a wrong sign, a missing decimal, or a rapid that crosses the part.
- 77. Cut the first article and inspectRun one part, measure every critical feature, and record the values. Adjust the wear offsets rather than rewriting the program. If a dimension moves by more than half the tolerance, find the cause before running the batch.
- 88. Freeze the program and document itSave the proven file as revision A, back it up, and attach the setup sheet. Record the tool list, the offsets used, and any manual edits. The next person to run the job should not have to guess what changed.
Hand-coding vs CAM posting: which to use
Match the method to the geometry, not to personal preference.
| Part feature | Best method | Why it matters |
|---|---|---|
| Facing and simple profiles | Hand-code | Short program, fast to edit at the machine |
| Hole patterns and tapping | Hand-code or CAM | Cycles are short; CAM wins past 20 holes |
| 2.5D pockets | Either | CAM saves time on many depth passes |
| 3D contoured surfaces | CAM | Hand math for surfaces is not practical |
| 4-axis indexed work | CAM | Rotary positions must be posted correctly |
| Simultaneous 5-axis | CAM only | Requires TCPC or G68.2 from the post |
| One-off repair parts | Hand-code | No model exists to program from |
Code the simple parts, post the complex ones, prove everything dry
Hand-code facing, drilling, and simple profiles. Post anything with 3D surfaces or rotary motion. Then run the program in air before it touches metal. That order keeps cycle times short and crashes rare.
Frequently asked questions
Do I need to learn G-code if I use CAM software?
Yes, at least to read it. CAM posts a program, but the programmer still has to check the header, the tool changes, and the retract moves. Most posted files need small manual edits, and a person who cannot read the code cannot tell whether the edit is safe.
It also matters at the machine. When a dimension drifts, the operator adjusts a wear offset. If the cause is in the program, someone has to open the file and find it.
Which G-codes appear in almost every mill program?
G00 for rapid positioning, G01 for linear feed, G02 and G03 for arcs, G17 for the XY plane, G21 for metric units, G90 for absolute positioning, G43 for tool length offset, and G54 for the first work offset. On the machine side, M03 starts the spindle, M05 stops it, M08 and M09 control coolant, and M30 ends the program.
Lathes add G71 and G70 for roughing and finishing cycles, G76 for threading, and G96 for constant surface speed.
How do I check a program without cutting metal?
Use the control's dry-run and single-block modes with the Z work offset raised by 50 mm, or run a graphic simulation if the control has one. Watch the distance-to-go display on every rapid move. Step through each tool change and confirm that the correct length offset is called.
On the first real part, keep the rapid override low and the feed override at 25 to 50 percent. Raise them only after the first few cuts sound clean.
What files should I send to a machine shop for programming and quoting?
A STEP or IGES solid model for the geometry, plus a 2D drawing with tolerances, datums, thread callouts, and surface finish requirements. Add the material grade, the quantity, and any finish or heat treatment. If the part has a critical fit, say which dimension it fits and against what.
At GreatLight, quotation and free DFM analysis come back within 12 hours, and production can start within 24 hours after the files are approved.
Can a hand-written program hold ±0.005 mm?
The tolerance comes from the machine, the tool, and the setup, not from whether a human or CAM wrote the code. A rigid machine with the right tool and a proven setup can hold ±0.005 mm from a clean hand-written program. The risk is human error in the block, which is why the dry run and the first-article inspection matter.
For contoured work, the limiting factor is usually the number of points in the path. Too few points leave facets; too many slow the control down.
Should the programmer also set the work offsets?
It depends on the shop. In small shops the programmer often sets up the first job and proves the program. In larger shops the setup operator touches off the tools and stores the offsets. Either way, the offset numbers in the setup sheet must match the H and T calls in the program.
Documenting which offset each tool uses prevents the most common crash: a tool change that calls the wrong length.
Send the drawing, get a coded process back
Upload a STEP file and a 2D drawing. We return a quotation and free DFM analysis within 12 hours, and our 150 technicians program and run the part on 127 high-precision CNC machines.
12-hour quoteNo minimum order quantity100% inspection before shipment