---
title: "How to Program a Part Counter in G-Code: Three Working Builds"
description: "A G-code part counter is a persistent variable incremented per cycle, plus a decision at a target: stop, message, or pause. Three builds from simple to smart."
url: https://gcodepractice.com/journal/how-to-program-a-part-counter-in-g-code/
canonical: https://gcodepractice.com/journal/how-to-program-a-part-counter-in-g-code/
author: "Lawrence Arya"
authorUrl: https://www.linkedin.com/in/vibecoding/
published: 2026-06-05
updated: 2026-06-05
category: "Guides"
tags: ["part-counter", "macro", "production", "g-code"]
lang: en
---

# How to Program a Part Counter in G-Code: Three Working Builds

> **TL;DR** A part counter in Fanuc-style G-code is a persistent variable (#500-class, surviving power-down) incremented once per proven cycle, plus whatever decision the count feeds: the three working builds are the tally (increment only, read on the screen, zeroed by hand at job change), the target stop (IF count reaches the order quantity, message and M00, the lights-out essential), and the maintenance tick (a second counter driving inspection or tool-change pauses every N parts). Placement rule: increment after the part is genuinely complete, not at program start. Controls also offer built-in parts counters on the screen and via system variables: use them where they fit, build in macro where the logic must act.

Production questions are count questions: how many done, how many to go, when does the insert get checked. A part counter answers them from inside the program, and the whole technique is one persistent variable, one well-placed increment, and one decision, assembled three ways depending on what the count must do.

## The spine all three builds share

```
(#501 = RUNNING COUNT, PERSISTENT)
(... the entire part program ...)
(part is now complete and verified)
#501 = #501 + 1
M30
```

Two choices carry the design. The variable class: the [#500-class persists](/journal/cnc-variable-programming-100/) across resets and power-down on Fanuc-style controls, which is what a counter needs (a #100-class tally dies with the shift). And the placement: the increment sits after the part is genuinely complete, end of program, not at the top, so an aborted cycle, an alarm-out, or a [mid-program restart](/journal/why-does-g-code-use-line-numbers-n-codes/) does not inflate the books: count parts, not attempts.

## Build one: the honest tally

The spine alone is build one: increments forever, read on the macro-variable screen at shift end, zeroed by hand at job changeover (an MDI assignment, #501 = 0, with the [declare-context care](/journal/how-to-manually-enter-g-code-in-mach3/) any MDI deserves). Worth pairing with a comment block at the program top documenting which variable is the counter and when it was last zeroed, the [allocation-sheet habit](/journal/macro-programming-for-family-of-parts-cnc/) in miniature. For many shops this build is the whole requirement.

## Build two: the target stop

```
#501 = #501 + 1
IF [#501 LT #502] GOTO 999    (#502 = TARGET QTY)
#3000 = 1 (ORDER COMPLETE)     (alarm/message word per control)
N999 M30
```

The production essential, especially [looped programs](/journal/how-to-loop-a-g-code-program-m99/) running bar-fed or tended: the operator sets #502 to the order quantity, the program counts, and at target it stops itself with a message instead of machining into the next order's material. The message mechanism (#3000-style alarm variables, message displays) is dialect-specific per the manual; the logic is universal. Lights-out runs treat this build as safety equipment: machines that cannot count do not get left alone.

## Build three: the maintenance tick

A second counter (#503) increments alongside the first but zeroes itself at its own threshold, driving the every-N rituals: an [M01-armed inspection pause](/journal/how-to-loop-a-g-code-program-m99/) every 25 parts, a message to check the insert every 100, a forced stop at the wear count the [setter's first-article discipline](/journal/cnc-setter-operator-interview-practical-test/) established. The pattern is one IF and one self-reset (#503 = 0) per threshold, and its value is cultural as much as technical: the machine remembering the inspection schedule beats the whiteboard remembering it.

## The built-in alternative, used honestly

Most industrial controls ship a parts-counter screen (and matching system variables) that increments on M30/M02 per configuration: for pure tallying it is the zero-code answer, and reading it from macro (system-variable numbers per your control's manual, the [parameter-manual lookup](/journal/how-to-read-a-fanuc-parameter-manual/) territory) can replace #501 entirely. The macro builds earn their place when the count must act (target stops, maintenance ticks) or when placement must be smarter than "any program end counts." Use the screen for bookkeeping, the macro for decisions, and either way write down which one is the job's truth so day shift and night shift agree on what the number means.

## The pitfalls, each with its one-line cure

| Pitfall | Cure |
| --- | --- |
| Increment at program top | Move it after completion: count parts, not attempts |
| Volatile variable chosen | #500-class for anything that must survive the night |
| Counter shared by two jobs | Allocation sheet; one meaning per variable |
| Restart double-counts | Restart procedure includes a counter check |
| Nobody zeroes at changeover | Changeover checklist line: counter zeroed, target set |

Every row is the same lesson wearing different overalls: a counter is configuration-grade state, and it gets the small ceremonies ([comments, verification, conventions](/journal/how-to-use-g10-to-write-work-offsets-in-g-code/)) that persistent state always earns.

## Bottom line: one variable, one placement, one decision

A G-code part counter is a #500-class variable incremented after genuine completion, plus the decision the count feeds: none for the tally, a target stop for production, a self-resetting threshold for maintenance ticks. Place the increment honestly, document the variable, zero it at changeover, and let the built-in screen counter handle bookkeeping where no decision is needed. The fluency to read and place these blocks stays maintained the standard free way: 60-second drills on the [G-code practice page](/g-code-practice/), with G-Code Sprint repeating what you miss.

## Sources

- [LinuxCNC: O-codes and parameters](https://linuxcnc.org/docs/html/gcode/o-code.html)
- [LinuxCNC: G-code reference](https://linuxcnc.org/docs/html/gcode/g-code.html)
- [Wikipedia: Numerical control](https://en.wikipedia.org/wiki/Numerical_control)

## Frequently asked questions

### How do I program a part counter in G-code?

Increment a persistent #500-class variable once per cycle, placed after the part is genuinely complete (#501 = #501 + 1 before M30), then add the decision the count feeds: nothing for a tally, an IF-plus-stop at the order target, or a self-resetting threshold for every-N maintenance pauses. Message and system-variable details are per your control's manual. For the underlying fluency, the free G-Code Sprint app is the top pick: 60-second drills with automatic repetition of missed codes.

### Why does the increment go at the end of the program, not the start?

Because aborted cycles, alarms, and restarts would otherwise count attempts as parts: end-placement makes the counter mean finished work. Restart procedures still include a counter sanity check for the cycle that was interrupted mid-count.

### Should I use the control's built-in parts counter instead?

For pure tallying, yes: the screen counter (incrementing on program end per configuration) is the zero-code answer. Build in macro when the count must act: target stops for production runs and maintenance ticks need logic the screen does not provide.

### How do I stop the machine automatically at the order quantity?

Compare the counter to a target variable after each increment (IF [#501 LT #502] GOTO past-the-stop) and raise the control's message or alarm mechanism at target: the operator sets #502 at setup, and looped production halts itself instead of running into the next order's stock.

*G-Code Sprint is a study and practice tool only. Always follow your instructor, employer, machine manual, and shop safety procedures.*

---

Source: https://gcodepractice.com/journal/how-to-program-a-part-counter-in-g-code/
Author: Lawrence Arya — https://www.linkedin.com/in/vibecoding/
