CNC Subprograms & Macros
Subprograms and macros are the two ways a CNC program stops being a fixed list of moves and becomes reusable code. A plain program is written for one part: it runs from its first block to its last and is done, and the shop that machines the same feature on four identical parts, or the same shaped part in three sizes, writes the same moves four times or three times over. Subprograms and macros break that repetition. A subprogram is a sequence of code stored on its own, which the main program can call as often as it needs; a macro is a program that works with variables — named or numbered values that the program reads, computes and writes — so that one program can machine a whole family of parts by changing the numbers it is given. Together they carry the language of G-code from a list of instructions into something like a small, disciplined computer program.
Subprograms: code that runs again
A subprogram is exactly what its name says: a program within the machine’s memory that is not run on its own but called from another. The main program, at the point where the repeated work begins, issues a call naming the subprogram; the control runs the subprogram from its start to its end; and it returns to the main program at the block after the call, ready for the next instruction. The pattern can repeat many times — a subprogram that machines one of a pair of identical parts is called twice, one that cuts a repeated feature is called for every repetition — and subprograms can call other subprograms, nesting the reuse as deeply as the work needs. The economy is the same economy as the canned cycle: the sequence is written once, in one place, where a change to it changes every use; but where a canned cycle is a fixed routine built into the control, a subprogram is the shop’s own routine, written in its own code and called where it is wanted.
How a subprogram is used
The subprogram earns its keep wherever the same work recurs, and the shop uses it the moment the repetition is seen. On many controls the call is made with a code such as M98 naming the subprogram, and the subprogram ends with the code that returns to the caller; the call can also carry a repeat count, running the subprogram several times in a row — the tool’s way of machining the same pocket on each of the four parts bolted to the fixture without four copies of the pocket code. The main program then reads as the skeleton of the job — load the part, call the subprogram for the pocket, index the fixture, call it again, change the tool — and the detail lives in the subprograms it calls. This is the structure of a program at its cleanest: a long, repetitive job reduced to a short list of calls, with each repeated sequence written once, proved once and trusted for every use. The discipline is to give subprograms clear boundaries and clear names, so that what they do is plain to the machinist who reads the call.
Macros: programs with variables
A macro is a program that thinks in variables, and the variables are its whole difference from ordinary code. Where a normal program writes the value into every block — drill to Z minus 10, mill the pocket at X 25 — a macro writes a variable instead: drill to the depth named by variable one, mill at the position named by variable two — and the control evaluates the variable when it runs the block, using whatever value the variable holds at that moment. The program can then assign values to its variables, do arithmetic on them (adding, subtracting, multiplying and dividing, and the functions that go with them) and make decisions with them, branching to different blocks or repeating a group of blocks while a condition holds, in the manner of a conventional programming language. The result is a program that is not a fixed list but a set of instructions about a job — one that can read the diameter of a cutter, work out the offsets from it, and cut accordingly, or ask the operator for a depth and use the answer.
The parametric program
The most powerful use of the macro is the parametric program: one program that machines a family of parts, written so that the dimensions are variables rather than numbers. A program written this way machines the blank whose length, width and depth are the values of its variables; to run it for another size the machinist changes the variable values — typing them at the control, reading them from a data file, or passing them to the macro at the call — and the same program cuts the new size without a single further edit. Such programs are the shop’s own custom cycles, and the machine makers use exactly this mechanism for the cycles and probes built into the machine. The parametric program turns programming from writing each part into writing the logic of a family once, and it is the highest form of the reuse this entry describes — the sequence and the dimensions both captured in one place.
Proving reusable code
Subprograms and macros repay the shop that proves them, because their power is also their danger. A macro’s logic can be harder to follow than a plain list of moves — the block that drills to variable one does not say what depth it will use until the program runs — and a loop written carelessly can run on far longer than intended, or never end at all. The discipline that tames them is the discipline of the rest of this group: the code is written clearly, with comments naming what each variable and each section does; it is proved first on the material or in the machine’s graphics, with the variable values chosen to exercise the extremes as well as the ordinary case; and a tested subprogram or macro is kept and reused, carrying its proof with it. Written and proved this way, subprograms and macros make the shop’s programs shorter, its repetition cheaper and its families of parts a matter of changing a number — the fundamentals of G-code raised from writing every move to writing the logic that makes the moves, once, well.