Fanuc Turning System Variables (Fanuc-T)

A Fanuc lathe control (Fanuc-T: 0i-T, 30i-T and kin) runs the same custom-macro machinery as the mill controls — the same #-variables, the same IF/GOTO/WHILE, the same read-into-a-variable, do-arithmetic, write-it-back pattern covered in the Fanuc System Variables reference. What changes is the tool-offset map, and it changes completely: a lathe offset station is not one length and one radius, it is X geometry, Z geometry, nose radius, and tip direction — each (except tip direction) with a separate geometry and wear value. That is up to seven numbers per station, and they live in variable blocks a mill programmer has never touched. This article maps them, then works the two problems every lathe macro runs into: diameter mode, and writing wear offsets from measured parts.

How the Lathe Numbering Is Organized

Same skeleton as the mill map — the number tells you the family. The two lathe-specific entries are the tool-offset block (same #2001 neighborhood as a mill, completely different interior) and the work shift:

RangeFamily
#1#33Local variables & macro call arguments
#100#999Common (general-purpose) variables
#2001#2964Tool offsets — wear and geometry blocks for X, Z, nose radius, tip direction, Y (the lathe-specific map below), with the work shift embedded at #2501/#2601
#3000#3902Alarms, timers, control switches, part counters
#4001#4130Modal information (active G-codes, T, S, F…)
#5001#5106Positions (previous block, machine, work, skip, deviation)
#5201#5208External workpiece zero-point offset (needs the workpiece-coordinate-system option on older T controls; not the Work Shift screen — that is #2501/#2601)
#5221#5328Work offsets G54–G59
#10001+Five-digit tool-offset map for high offset counts (documented since the 16i/18i era; table below)

The Lathe Tool-Offset Map

The layout below is the standard Fanuc-T map for controls with geometry/wear offset memory, and it is printed identically in the 0i-B (B-63834EN), 16i/18i-B (B-63524EN), and 30i-B Plus (B-64724EN) custom-macro chapters — these bases are stable across generations. Variable = block base + offset number, so X wear for offset 07 is #2007 and X geometry for offset 07 is #2707. One asymmetry to respect: the wear blocks and the nose-radius geometry block cover offsets 1–64, but the X and Z geometry blocks stop at offset 49 (the Y-axis blocks occupy the room above them) — offsets past those limits are reached through the five-digit map below.

VariableUsageR/W
Wear Offsets (base + offset number 1–64)
#2001#2064X-axis wear offsetR/W
#2101#2164Z-axis wear offsetR/W
#2201#2264Tool-nose radius wear offsetR/W
#2301#2364Tip direction (imaginary tool-nose number T, integer 0–9 — a code, not a dimension; one value per offset, shared by geometry and wear)R/W
#2401#2449Y-axis wear offset (mill-turn lathes with a Y axis)R/W
Geometry Offsets (base + offset number — note the 49 limit on X/Z)
#2701#2749X-axis geometry offset (offsets 1–49 only)R/W
#2801#2849Z-axis geometry offset (offsets 1–49 only)R/W
#2901#2964Tool-nose radius geometry offset (1–64)R/W
#2451#2499Y-axis geometry offset (1–49)R/W
Work Shift
#2501 / #2601Workpiece coordinate system shift amount, X / Z — the value on the lathe’s Work Shift screen, applied on top of every coordinate system. (The similarly-purposed #5201+ block is the external workpiece zero-point offset — a different register.)R/W
Five-Digit Map (base + offset number; same fields, no 49/64 ceilings)
#10001+ / #15001+X-axis wear / geometryR/W
#11001+ / #16001+Z-axis wear / geometryR/W
#12001+ / #17001+Nose-radius wear / geometryR/W
#13001+Tip direction (one value, as in the four-digit map)R/W
#14001+ / #19001+Y-axis wear / geometryR/W

The five-digit map is not a 30i invention — the 16i/18i-B manual documents it for 99-set configurations and the 0i-B for 64 — but on the 30i series it reaches offset 999 and is the safer base to program against: it is valid even for low offset numbers, and it has no 49-offset cliff on X/Z geometry. (30i controls also expose named aliases like [#_OFSXW[n]] and [#_OFSXG[n]] for the same registers.) Two configuration departures to know about: a control without the geometry/wear memory option keeps one combined value per field at the wear bases (#2001/#2101/#2201/#2301), and a machine with more offset sets than the four-digit blocks hold simply has no four-digit address for the excess — use the five-digit one. An MDI read compared against the offset screen still settles any doubt in thirty seconds.

Two consequences of this layout worth internalizing. First, updating a lathe tool after a measured drift is usually two writes, not one (X wear and Z wear move independently). Second, tip direction sits in the middle of the dimensional blocks but is an integer code — writing a length into #2301+ corrupts nose-radius compensation quietly.

Indirect addressing (#[expression]) works exactly as on the mill, and on a lathe it earns its keep immediately — one macro can pull every field of a station whose number arrives as an argument. A useful pattern is a pre-flight check that reads the whole station and alarms out before a finish pass runs with an unset nose radius:

(O8090 - SANITY-CHECK ONE OFFSET STATION, CALL: G65 P8090 A3.)
(#1 = OFFSET NUMBER)
#11 = #[2000 + #1]      (X WEAR)
#12 = #[2100 + #1]      (Z WEAR)
#13 = #[2200 + #1]      (NOSE RADIUS WEAR)
#14 = #[2700 + #1]      (X GEOMETRY)
#15 = #[2800 + #1]      (Z GEOMETRY)
#16 = #[2900 + #1]      (NOSE RADIUS GEOMETRY)
#17 = #[2300 + #1]      (TIP DIRECTION, INTEGER 0-9)
IF [[#16 + #13] LE 0] GOTO 90    (NO NOSE RADIUS - G41/G42 WOULD BE WRONG)
IF [#17 LT 0] GOTO 91
IF [#17 GT 9] GOTO 91            (TIP DIRECTION OUT OF RANGE)
GOTO 99
N90 #3000 = 102 (NOSE RADIUS NOT SET FOR THIS OFFSET)
N91 #3000 = 103 (TIP DIRECTION INVALID FOR THIS OFFSET)
N99 M99

Named Tool-Offset Variables (30i / Plus)

On a 30i-family lathe every register in the map above also has a name, written with the whole reference in brackets: [#_OFSXW[7]] is X wear for offset 7, unambiguously — where #2007 needs the map (and a check of the geometry/wear memory option) to decode. The mechanism — the [#_NAME[n]] syntax, expression subscripts, and the PS1098/PS1099 alarms for a misspelled name or bad index — is covered in the mill article’s named-variables section; the table below is the lathe-specific offset vocabulary. Note how the memory option is spelled out in the name: with geometry/wear memory the …W/…G forms address the two blocks separately, while a control without that option uses the plain #_OFSX-style names for its single combined values — at the same wear-block numbers.

NameNumber equivalentIndexR/WMeaning
Wear Offsets (with geometry/wear offset memory)
#_OFSXW[n]#2001#2064; #10001#10999n = offset number (1–64 / 1–999)R/WX-axis wear offset
#_OFSZW[n]#2101#2164; #11001#11999n = offset number (1–64 / 1–999)R/WZ-axis wear offset
#_OFSRW[n]#2201#2264; #12001#12999n = offset number (1–64 / 1–999)R/WTool-nose radius wear offset
#_OFSYW[n]#2401#2449; #14001#14999n = offset number (1–49 / 1–999)R/WY-axis wear offset
Geometry Offsets
#_OFSXG[n]#2701#2749; #15001#15999n = offset number (1–49 / 1–999)R/WX-axis geometry offset
#_OFSZG[n]#2801#2849; #16001#16999n = offset number (1–49 / 1–999)R/WZ-axis geometry offset
#_OFSRG[n]#2901#2964; #17001#17999n = offset number (1–64 / 1–999)R/WTool-nose radius geometry offset
#_OFSYG[n]#2451#2499; #19001#19999n = offset number (1–49 / 1–999)R/WY-axis geometry offset
Tip Direction
#_OFST[n]#2301#2364; #13001#13999n = offset number (1–64 / 1–999)R/WVirtual tool tip T position (the integer 0–9 tip-direction code)
Without Geometry/Wear Offset Memory (single combined value per field)
#_OFSX[n]#2001#2064; #10001#10999n = offset number (1–64 / 1–999)R/WX-axis compensation value
#_OFSZ[n]#2101#2164; #11001#11999n = offset number (1–64 / 1–999)R/WZ-axis compensation value
#_OFSR[n]#2201#2264; #12001#12999n = offset number (1–64 / 1–999)R/WTool-nose radius compensation value
#_OFSY[n]#2401#2449; #14001#14999n = offset number (1–49 / 1–999)R/WY-axis compensation value
Second Geometry Tool Offsets
#_OFSX2G[n]#5801#5832; #27001#27999n = offset number (1–32 / 1–999)R/WSecond geometry tool offset, X axis
#_OFSZ2G[n]#5833#5864; #28001#28999n = offset number (1–32 / 1–999)R/WSecond geometry tool offset, Z axis
#_OFSY2G[n]#5865#5896; #29001#29999n = offset number (1–32 / 1–999)R/WSecond geometry tool offset, Y axis
Workpiece Shift
#_WKSFTX (the manual’s explanation pages also spell it #_WZ_SFTX)#2501— (scalar)R/WX-axis workpiece coordinate system shift amount
#_WKSFTZ (also spelled #_WZ_SFTZ)#2601— (scalar)R/WZ-axis workpiece coordinate system shift amount
#_WZ_SFT[n]#100751#100800n = axis number (1–50)R/Wnth-axis workpiece shift amount
Active Tool Offset (what is applied to the tool right now — read-only reporters, not the offset table)
#_TOFSWX / #_TOFSWZ / #_TOFSWY#5081, #100201 / #5082, #100202 / #5083, #100203— (scalar)RX- / Z- / Y-axis tool offset (wear) of the active tool
#_TOFS[n]#5084#5100 (n = 4–20); #100204#100250 (n = 4–50)n = axis numberRTool offset (wear) for an arbitrary axis
#_TOFSGX / #_TOFSGZ / #_TOFSGY#5121, #100901 / #5122, #100902 / #5123, #100903— (scalar)RX- / Z- / Y-axis tool offset (geometry) of the active tool
#_TOFSG[n]#5124#5140 (n = 4–20); #100904#100950 (n = 4–50)n = axis numberRTool offset (geometry) for an arbitrary axis

Where the numbers make you memorize that #2007 is wear and #2707 is geometry — and remember the 49-offset cliff — the names carry both facts in the token and accept the full 1–999 subscript wherever the expanded ranges exist. The tip-direction trap flagged above reads even louder in named form: #_OFST is visibly not a dimension field.

Everything That’s the Same as the Mill

Outside the tool-offset blocks, the map matches the mill reference — see Fanuc System Variables for the full table with R/W flags. The short version, with the one lathe-specific trap flagged:

FamilyVariablesLathe note
Positions#5001+ (previous block end), #5021+ (machine), #5041+ (work)Axis order is X, Z, … per the machine’s axis configuration — and X reads come back as a diameter on a diameter-programmed lathe (next section)
Skip / probe#5061+ (position where G31 tripped, work coordinates)Same diameter caveat on the X value
Modal data#4001+ G-code groups, #4120 modal T#4120 returns the whole T word (T0312 → 312): station and offset number packed together
Common variables#100#199 (volatile), #500#999 (retained)Identical
Alarms & stops#3000 (alarm), #3006 (stop with message)Identical
Part counters#3901 (machined parts), #3902 (required parts)Identical — the usual home of bar-feeder “count and stop” logic
Timers & clock#3001/#3002 (timers), #3011/#3012 (date/time)Identical
Work offsets#5221+ (G54) … #5321+ (G59)Identical numbering (option-gated on older T controls, along with the external offset #5201+); many lathes run everything from the work shift (#2501/#2601) plus geometry offsets instead

Read-Only vs Read/Write at a Glance

The mill rule of thumb carries over unchanged: variables that report state are read-only, variables that hold setup data are writable. On a lathe the practically important consequence is that the entire offset map above — all seven fields per station, plus the work shift — is writable, which is exactly what makes in-process wear compensation a macro-sized job.

Read-only (report state)Read/write (you can assign to them)
Positions #5001–#5106 (previous-block end, machine, work, skip, deviation)Tool offsets #2001–#2964 and #10001+ (wear + geometry, X/Z/R/T/Y)
Modal codes #4001–#4130 (incl. #4120 modal T)Work shift #2501/#2601, external offset #5201+, work offsets #5221–#5328
Clock #3011/#3012, null #0Commons #100–#199, #500–#999; counters #3901/#3902; timers #3001/#3002; alarm/stop #3000/#3006 (write-only)

Diameter Mode Bites Macros

Almost every lathe is diameter-programmed: X50. means a 50 mm diameter, not 50 mm from centerline. The control extends that convention into the system variables — #5041 (and #5021, #5061) return the X axis as a diameter value. Any macro doing real geometry — trigonometry on a taper, comparing a probe trip to a radial clearance — must halve the X read first:

#101 = #5041 / 2      (CURRENT X AS A RADIUS - #5041 IS DIAMETER)
#102 = #5061 / 2      (SKIP X AS A RADIUS)

The same ambiguity hits writes — and here the manual is explicit. Suppose a post-process gauge says the finished part is 0.04 mm big on diameter. The physical correction is to bring the tool 0.02 mm closer to centerline — but what number goes into the X wear variable depends on how the control stores X offsets, and that is a documented parameter: the operator’s manual’s diameter-programming table says the tool-offset component follows bit 1 (ORC) of parameter No. 50040 (the factory default) stores offsets for a diameter-programmed axis as diameter values, 1 as radius values. So on a standard diameter-mode lathe the write is -0.04, matching what the operator would key into the offset screen. Two footnotes: ORC only applies to diameter-programmed axes (a radius-programmed axis always takes radius values), and on an ORC=1 machine, bit 0 (OWD) of parameter No. 5040 can put wear offsets back on diameter while geometry stays radius. A test cut remains the right acceptance check of the whole chain — cut, measure, write a known correction, cut again, and confirm the diameter moved by the full amount you wrote (diameter storage) or twice it (radius) — but you are verifying a parameter setting now, not guessing at one.

(PART MEASURED 0.04 MM OVERSIZE ON DIAMETER, TOOL OFFSET 3)
#[2000 + 3] = #[2000 + 3] - 0.04   (ORC=0, THE DEFAULT: X WEAR IS A DIAMETER VALUE)
(OR - 0.02 ON AN ORC=1 RADIUS-ENTRY MACHINE - PARAM 5004#1)

Worked Example: In-Process Gauging Loop

The bread-and-butter lathe macro: after a finish pass, a measured diameter (from an in-process gauge, a probe routine, or the operator keying it into a retained common variable) is compared to target, and the X wear offset for the active tool drifts to compensate. The offset number is resolved from the modal T word (#4120), the correction is clamped so one bad reading cannot crash the next part, and anything outside the scrap band raises #3000 instead of “correcting” it. Assumes a 2+2 T format (T0303) and the default diameter-value offset storage (ORC=0) — adjust if your machine is set to radius entry.

(O8100 - UPDATE X WEAR FROM MEASURED DIAMETER)
(#510 = MEASURED DIAMETER  - GAUGE OR OPERATOR ENTRY)
(#511 = TARGET DIAMETER)
#1 = #510 - #511                    (DIAMETER ERROR, + = OVERSIZE)
IF [ABS[#1] GT 0.25] GOTO 90        (OUTSIDE SCRAP BAND - DO NOT CORRECT)
IF [ABS[#1] LE 0.005] GOTO 99       (INSIDE DEADBAND - LEAVE OFFSET ALONE)
IF [#1 GT 0.06] THEN #1 = 0.06      (CLAMP CORRECTION PER CYCLE)
IF [#1 LT -0.06] THEN #1 = -0.06
#2 = #4120 - [FIX[#4120 / 100] * 100]   (WEAR OFFSET NO. = LOW 2 DIGITS OF T)
IF [#2 LT 1] GOTO 91                (NO OFFSET ACTIVE - T??00)
#[2000 + #2] = #[2000 + #2] - #1    (SHIFT X WEAR, DIAMETRAL STORAGE)
GOTO 99
N90 #3000 = 100 (PART OUT OF TOLERANCE - CHECK TOOL AND GAUGE)
N91 #3000 = 101 (NO WEAR OFFSET ACTIVE - CHECK T WORD)
N99 M99

On a 30i control the X-wear write reads better in the named form — the name carries the axis and the wear/geometry meaning, the subscript carries the offset number, and the same pattern works on the read side (#5 = [#_OFSZG[#2]] pulls Z geometry for the same station):

[#_OFSXW[#2]] = [#_OFSXW[#2]] - #1  (SAME X-WEAR WRITE AS #[2000 + #2] ABOVE, NAMED FORM)

Getting the measurement in. Where #510 comes from depends on the shop. The zero-hardware version pauses the cycle and asks the operator to key the gauge reading into a retained common variable before pressing cycle start:

(OPERATOR-ENTRY VARIANT)
#3006 = 1 (MIC THE PART - PUT DIAMETER IN NO. 510 - CYCLE START)
G65 P8100                 (RUN THE WEAR-UPDATE MACRO ABOVE)

With a spindle probe, a G31 skip move onto the turned diameter captures the trip position instead — and because the X read is diametral (previous section), a probe touching a centerline-symmetric OD hands you a diameter-mode value directly. Probe radius and trigger calibration still have to be folded in (that is what the stylus-calibration constant in a retained variable is for):

(PROBE-CAPTURE VARIANT)
G00 X[#511 + 4.] Z-10.    (CLEAR OF THE TURNED DIAMETER)
G31 X[#511 - 2.] F100.    (SKIP MOVE ONTO THE OD)
#510 = #5061 + #520       (SKIP X, DIAMETRAL + STYLUS CAL FROM #520)
G00 X[#511 + 4.]          (RETRACT)
G65 P8100                 (RUN THE WEAR-UPDATE MACRO ABOVE)

One timing note: a wear value written mid-program is stored immediately, but the axis does not move — the new value takes effect when the offset is next applied (the next T call, in the next part cycle). That is exactly what you want for drift compensation.

Gotchas Worth Knowing

  • Diameter vs radius, everywhere. X position reads (#5021/#5041/#5061) are diametral on a diameter-programmed lathe; X offsets are diameter values by default and radius values if bit 1 (ORC) of parameter No. 5004 is set. Halve for geometry, and confirm the offset-storage chain with a test cut before trusting a correction macro.
  • Write wear for drift, geometry for setup. Geometry offsets describe where the tool is (set at touch-off); wear offsets absorb how it changes (insert wear, thermal growth). An in-process loop should only ever touch the wear blocks — a macro that “corrects” geometry destroys the setup reference and hides how much the insert has actually worn.
  • Tip direction (#2301+) is an integer, not a dimension. It selects the imaginary tool-nose quadrant (0–9) for nose-radius compensation. Indirect-addressing loops that sweep “all offset variables” must skip this block, or they will write fractional lengths into a code field.
  • The T word maps to offsets differently across machines. The example above assumes T0303-style 2+2 format where the low two digits are the offset number — but some builders use 1+2 or 2+1 formats, and turret station and offset number need not match (T0315 runs station 3 with offset 15). Gang-tool and multi-turret lathes complicate it further. Resolve the offset number from #4120 the way your T format packs it, and never assume station = offset.
  • Skip moves want comp cancelled. Run G31 in G40 — a skip move under active nose-radius compensation is either rejected or hands you a trip position skewed by the comp vector. Cancel, probe, re-apply.
  • Look-ahead buffering applies here too. A block already read into the buffer keeps the old value of an offset you just wrote, and position reads can be evaluated before the preceding motion finishes. Where a read or write must line up with motion, drain the buffer first (G04 dwell is the common idiom) — same rules as the mill article details.
  • Check units before writing corrections. A gauge reading keyed in millimeters against a program running G20 writes a 25× oversized correction. If the macro can be run in either mode, read #4006 (20 = inch, 21 = metric) and convert — or alarm out.
  • Mind the edges of the four-digit map. The bases themselves are stable from 0i-B through 30i-B Plus, but the X/Z geometry blocks (#2701/#2801) end at offset 49 and the wear blocks at 64 — a loop that walks offsets 1–80 through four-digit addresses walks off the map. Use the five-digit bases (#10001+) for anything general, and remember that a control without geometry/wear offset memory collapses each field to a single value at the wear bases. One MDI read against the offset screen settles any residual doubt in thirty seconds.

Try these in the Macro Playground — pick the Fanuc control, paste the gauging loop, set #510/#511 and #4120 as inputs, and watch the wear-offset write happen live.

See also: Fanuc Turning Programming for the lathe G-code context these macros live in, Fanuc System Variables for the full mill-side #-number map shared by both control families, and Reading & Writing System Variables for the same read/compute/write pattern across every control.

References

  • FANUC, Series 30i/31i/32i-MODEL B Plus Operator’s Manual (Common), B-64724EN/01, ch. 16 (system variables, lathe tool-compensation and work-shift tables) and §8.4 (diameter/radius programming).
  • FANUC, Series 16i/18i-TB Operator’s Manual, B-63524EN/01, ch. 15, and Series 0i-TB Operator’s Manual, B-63834EN/01, ch. 15 (legacy-generation variable tables).
  • FANUC, Series 30i/31i/32i-MODEL B Plus Parameter Manual, B-64730EN/01 (Nos. 5004 ORC, 5040 OWD).
  • Peter Smid, Fanuc CNC Custom Macros, Industrial Press, 2004.

Have a question or want to contribute?

Contact us with corrections, additions, or topics you'd like covered.

Get in Touch