Heidenhain TNC 320: Klartext & Q-Parameters
If you know Fanuc Macro B, the TNC 320 gives you the same power under different names: Q parameters are your #-variables, FN functions are your math and IF/GOTO statements, and LBL / CALL LBL replaces M98 subprograms. The big differences: variables are typed by letter (Q, QL, QR, QS), formulas read like normal algebra (Q25 = ATAN (Q12/Q13)), and a large block of Q numbers is reserved for HEIDENHAIN cycles — stray into it and cycles will overwrite your data.
Klartext Program Structure
Every NC program is bracketed by BEGIN PGM and END PGM, each carrying the program name and unit of measure (MM or INCH). Directly after the header you normally define the workpiece blank with BLK FORM — only needed if you want graphic simulation, but the simulation's Advanced checks use it for workpiece monitoring. Program files use the extension .H (Klartext) or .I (ISO); the control numbers NC blocks automatically.
0 BEGIN PGM NEW MM ; program start, name, unit of measure
1 BLK FORM 0.1 Z X+0 Y+0 Z-40 ; spindle axis, MIN point
2 BLK FORM 0.2 X+100 Y+100 Z+0 ; MAX point
3 END PGM NEW MM ; program end
Besides the rectangular blank there are BLK FORM CYLINDER (radius, length, optional inside radius), BLK FORM ROTATION (contour in a subprogram) and BLK FORM FILE (an STL file as blank, optionally with a finished-part STL — handy for CAM work). Note the control's full range of functions is only available with tool axis Z.
Subprograms, Repeats, and Program Calls
Labels are set with the LBL SET key: a number 1–65535 or a name up to 32 characters. LBL 0 is reserved — it marks the end of a subprogram and is the only label you may use repeatedly. Each other label number/name may be set only once per program.
| Technique | Klartext | Fanuc analogy | Rules |
|---|---|---|---|
| Subprogram | CALL LBL 1 … LBL 1…LBL 0 | M98 P… / M99 | Write subprograms after the M2/M30 block, or they execute once uncalled. A subprogram cannot call itself. CALL LBL 0 is not permitted. |
| Program-section repeat | LBL 2 … CALL LBL 2 REP 2 | WHILE loop | Up to 65,534 repeats; the section runs REP + 1 times total (first pass counts). |
| External program call | CALL PGM TNC:\ZW35\PGM1.H | M98 to O-number in memory | Called program must not contain M2/M30 (replace with FN 9: IF +0 EQU +0 GOTO LBL 99) and must not call its caller. Add file type .I to call an ISO program. |
| Variable program call | SEL PGM … CALL SELECTED PGM | — | SEL PGM accepts QS string parameters → dynamic program calls. Check paths first with FN 18 ID10 NR110/NR111. |
Nesting depth is 19 for subprograms and 19 for external program calls; program-section repeats nest without limit. Q parameters are global across CALL PGM — changes in the called program come back with you. Use QL parameters when you want values that stay local to one NC program.
Classic manual example — a hole group programmed once, called at three positions (M99 is the per-block cycle call, exactly like Fanuc):
5 CYCL DEF 200 DRILLING ... ; define drilling cycle
6 L X+15 Y+10 R0 FMAX M3 ; start point, group 1
7 CALL LBL 1
8 L X+45 Y+60 R0 FMAX ; group 2
9 CALL LBL 1
10 L X+75 Y+10 R0 FMAX ; group 3
11 CALL LBL 1
12 L Z+250 R0 FMAX M2 ; end of main program
13 LBL 1 ; subprogram: the hole group
14 CYCL CALL ; hole 1
15 L IX+20 R0 FMAX M99 ; hole 2 (incremental move + cycle call)
16 L IY+20 R0 FMAX M99 ; hole 3
17 L IX-20 R0 FMAX M99 ; hole 4
18 LBL 0 ; end of subprogram
19 END PGM UP1 MM
Q-Parameter Types and Reserved Ranges
This table is the one to pin above the desk. Q parameters are global across all NC programs in memory; QL are local to one program; QR are global and retentive (survive a restart, included in backups); QS hold text (up to 255 characters, 2000 QS parameters available). Values range ±999,999,999 with 16 digits max (9 before the decimal point). Numbers are stored IEEE 754 binary — remember rounding when using computed values in jump conditions.
| Type | Range | Who owns it |
|---|---|---|
| Q / QS parameters (global, 0–1999) | ||
Q0–Q99 | User — if no overlap with HEIDENHAIN SL cycles | Inside macros/cycles these act locally; changes are not returned to the caller |
Q100–Q199 | Control special functions (read-only for you) | Preassigned values: tool data, probe results — see below. Never use as calculated parameters. |
Q200–Q1199 | HEIDENHAIN (cycle transfer parameters) | e.g. Q200 set-up clearance, Q201 depth |
Q1200–Q1399 | Machine manufacturer cycles | Hands off |
Q1400–Q1999 | User — the safe sandbox | Put your own macro variables here |
| QL parameters (local to the NC program) | ||
QL0–QL499 | User | All free — like Fanuc local #1–#33, but without argument mapping |
| QR parameters (global + retentive, like Fanuc #500s) | ||
QR0–QR99 | User | Survive power-off; saved to SYS:\runtime\sys.cfg unless the OEM redirects the path |
QR100–QR199 / QR200–QR499 | HEIDENHAIN / machine manufacturer | Reserved |
A variable can also be explicitly de-initialized: FN 0: Q5 SET UNDEFINED. Positioning with an undefined Q parameter is silently ignored; using one in a calculation stops the program with an error. Test with FN 9: IF +Q5 IS UNDEFINED GOTO LBL …. To inspect or edit values at the control, press Q INFO (ranges 100–199 and 1200–1399 are not editable there).
Assignments and Arithmetic: FN 0–5, Trig, and the Formula Editor
| Function | Example | Means |
|---|---|---|
| Basic arithmetic | ||
| FN 0: Assign | FN 0: Q5 = +60 | Q5 = 60 (also assigns SET UNDEFINED) |
| FN 1: Add | FN 1: Q1 = -Q2 + -5 | Q1 = –Q2 + (–5) |
| FN 2: Subtract | FN 2: Q1 = +10 - +5 | Q1 = 10 – 5 |
| FN 3: Multiply | FN 3: Q2 = +3 * +3 | Q2 = 9 |
| FN 4: Divide | FN 4: Q4 = +8 DIV +Q2 | Q4 = 8 / Q2 (divide by 0 not allowed) |
| FN 5: Square root | FN 5: Q20 = SQRT 4 | Q20 = √4 (negative input not allowed) |
| Trigonometry & circles | ||
| FN 6 / FN 7 | FN 6: Q20 = SIN -Q5 | Sine / cosine of an angle in degrees |
| FN 8: Length | FN 8: Q10 = +5 LEN +4 | Q10 = √(5²+4²) — hypotenuse |
| FN 13: Angle | FN 13: Q20 = +25 ANG -Q1 | arctan(25/–Q1), result 0–360° |
| FN 23 / FN 24 | FN 23: Q20 = CDATA Q30 | Circle center + radius from 3 (FN 23) or 4 (FN 24) points stored from Q30 up; results land in Q20/Q21/Q22 |
The FORMULA soft key (or just pressing Q with a USB keyboard attached) lets you write whole expressions in one block with normal precedence — parentheses, then sign, functions, ^, * /, + –. Available functions include SQ, SQRT, SIN, COS, TAN, ASIN, ACOS, ATAN, ^, PI, LN, LOG, EXP, NEG, INT, ABS, FRAC, SGN and modulo %. Two gotchas straight from the manual: INT truncates (round by adding 0.5 * SGN Q1 first), and chained powers evaluate right-to-left (2^3^2 = 512).
37 Q25 = ATAN (Q12/Q13) ; angle from opposite/adjacent side
12 Q1 = 5 * 3 + 2 * 10 ; = 35
5 Q11 = INT (Q1 + 0.5 * SGN Q1) ; correct commercial rounding
11 Q12 = 400 % 360 ; modulo -> 40
Jumps and Conditions: FN 9–12
If the condition is true, the control jumps to the label; otherwise it continues with the next block. The target can be a label number, a label name, or a QS parameter holding the name. Abbreviations: EQU equal, NE not equal, GT greater, LT less.
| Function | Example | Jumps when |
|---|---|---|
| FN 9 | FN 9: IF +Q1 EQU +Q3 GOTO LBL "UPCAN25" | Values equal |
| FN 9 | FN 9: IF +Q1 IS UNDEFINED GOTO LBL "UPCAN25" | Variable undefined (also IS DEFINED) |
| FN 10 | FN 10: IF +10 NE -Q5 GOTO LBL 10 | Values not equal |
| FN 11 | FN 11: IF +Q1 GT +10 GOTO LBL QS5 | First greater than second |
| FN 12 | FN 12: IF +Q5 LT +0 GOTO LBL "ANYNAME" | First less than second |
An unconditional jump is simply a condition that is always true: FN 9: IF +10 EQU +10 GOTO LBL 1. The manual's counter loop — note that unlike CALL LBL … REP, jump loops need no LBL 0:
0 BEGIN PGM COUNTER MM
2 Q1 = 0 ; initialize counter
3 Q2 = 3 ; number of passes
5 LBL 99
6 Q1 = Q1 + 1 ; increment
7 FN 12: IF +Q1 LT +Q2 GOTO LBL 99 ; passes 1 and 2
8 FN 9: IF +Q1 EQU +Q2 GOTO LBL 99 ; pass 3
10 END PGM COUNTER MM
String Processing with QS Parameters
QS parameters feed variable text into FN 16 logs, dynamic program calls (SEL PGM), and jump targets. Assign with DECLARE STRING, then process with the STRING FORMULA / FORMULA functions (string indices start at 0):
| Function | Example | Does |
|---|---|---|
| DECLARE STRING | DECLARE STRING QS10 = "workpiece" | Assign text |
|| | QS10 = QS12 || QS13 | Concatenate strings |
| TOCHAR | QS11 = TOCHAR ( DAT+Q50 DECIMALS3 ) | Number → string, 3 decimals |
| SUBSTR | QS13 = SUBSTR ( SRC_QS10 BEG2 LEN4 ) | Copy 4 chars starting at position 2 |
| TONUMB | Q82 = TONUMB ( SRC_QS11 ) | String → number (must be purely numeric) |
| INSTR | Q50 = INSTR ( SRC_QS10 SEA_QS13 BEG2 ) | Find substring; returns position, or full length if not found |
| STRLEN | Q52 = STRLEN ( SRC_QS15 ) | Length; –1 if QS undefined |
| STRCOMP | Q52 = STRCOMP ( SRC_QS12 SEA_QS14 ) | Lexical compare: 0 equal, ±1 order |
| SYSSTR | QS25 = SYSSTR ( ID10010 NR1 ) | Read text system data (program path, tool name, date/time formats…) |
| CFGREAD | Q50 = CFGREAD ( KEY_QS11 TAG_QS12 ATR_QS13 ) | Read a machine parameter (key/entity/attribute defined in QS parameters first) |
FN 14: ERROR — Stopping the Program with a Message
FN 14: ERROR interrupts program run (or simulation) and displays a predefined message — your guard clause for macros. Message numbers 0–999 and 3000–9999 are machine-manufacturer dialogs; 1000–2999 and 10,000+ are HEIDENHAIN-defined. The 1000-series covers classics like 1000 Spindle?, 1003 Tool radius too large, 1010 Feed rate is missing, 1030 Q202 not defined.
180 FN 14: ERROR = 1000 ; "Spindle?" -- stop if spindle not running
Related output functions — FN 16: F-PRINT (formatted logs), FN 18: SYSREAD (system data), FN 26–28 (freely definable tables), SQL, and FN 38: SEND — are covered in the companion article TNC 320: Tables & System Data.
Preassigned Q Parameters (Q100–Q199)
The control keeps these loaded for you — read them, never write them. Q108 and Q114–Q117 follow the active program's unit of measure.
| Parameter | Content |
|---|---|
Q100–Q107 | Values from the PLC |
Q108 | Active tool radius (R + DR table + DR from TOOL CALL); retained across restart |
Q109 | Tool axis: –1 none, 0=X, 1=Y, 2=Z, 6=U, 7=V, 8=W |
Q110 | Spindle state: 0=M3, 1=M4, 2=M5 after M3, 3=M5 after M4 |
Q111 | Coolant: 1=M8 on, 0=M9 off |
Q112 | Overlap factor for pocket milling |
Q113 | Unit of the main program: 0=mm, 1=inch |
Q114 | Active tool length (L + DL) |
Q115–Q119 | Touch point X/Y/Z/4th/5th axis from probe cycles (no stylus compensation) |
Q115/Q116 | After TT tool measurement: length / radius deviation actual-vs-nominal |
Q120–Q122 | Calculated A/B/C rotary-axis angles |
Q150–Q160 / Q161–Q167 / Q180–Q182 | Probe cycle actual values / deviations / good-rework-scrap status — see the probing-cycles article |
Q199 | Tool-measurement status: 0 in tolerance, 1 worn, 2 broken |
Worked example — ellipse macro (from the manual)
The full pattern of a Klartext macro in one program: parameters up front, machining in a subprogram, geometry from trig, loop via FN 12. The ellipse is approximated by Q7 line segments; milling direction follows start vs. end angle.
0 BEGIN PGM ELLIPSE MM
1 FN 0: Q1 = +50 ; center X
2 FN 0: Q2 = +50 ; center Y
3 FN 0: Q3 = +50 ; semiaxis X
4 FN 0: Q4 = +30 ; semiaxis Y
5 FN 0: Q5 = +0 ; starting angle
6 FN 0: Q6 = +360 ; end angle
7 FN 0: Q7 = +40 ; number of segments
9 FN 0: Q9 = +5 ; milling depth
...
17 CALL LBL 10 ; call machining
18 L Z+100 R0 FMAX M2
19 LBL 10 ; subprogram
20 CYCL DEF 7.0 DATUM SHIFT ; shift datum to ellipse center
21 CYCL DEF 7.1 X+Q1
22 CYCL DEF 7.2 Y+Q2
25 Q35 = (Q6 - Q5) / Q7 ; angle increment
26 Q36 = Q5 ; running angle
27 Q37 = 0 ; counter
28 Q21 = Q3 * COS Q36 ; start point X
29 Q22 = Q4 * SIN Q36 ; start point Y
30 L X+Q21 Y+Q22 R0 FMAX M3
32 L Z-Q9 R0 FQ10 ; plunge
33 LBL 1
34 Q36 = Q36 + Q35 ; next angle
35 Q37 = Q37 + 1
36 Q21 = Q3 * COS Q36
37 Q22 = Q4 * SIN Q36
38 L X+Q21 Y+Q22 R0 FQ11 ; move to next point
39 FN 12: IF +Q37 LT +Q7 GOTO LBL 1 ; loop until done
42 CYCL DEF 7.0 DATUM SHIFT ; reset datum shift
43 CYCL DEF 7.1 X+0
44 CYCL DEF 7.2 Y+0
46 LBL 0
47 END PGM ELLIPSE MM
DIN/ISO Equivalents: The D-Functions
In ISO programs on the TNC 320, the same engine runs under D-numbers with P01/P02/P03 operand slots: FN 0→D00, FN 1–5→D01–D05, trig D06/D07/D08/D13, circles D23/D24, jumps D09–D12 (P03 = label), errors/output D14/D16/D18/D19. Labels are set with G98 L, a subprogram is called with L n,0, a repeat with L n,m, and an external program with %. Formula blocks (Q1 = 5 * 3 + 2 * 10) are identical in both dialects. Side by side:
; Klartext ; DIN/ISO
15 FN 0: Q10 = 25 N150 D00 Q10 P01 +25*
25 L X+Q10 N250 G00 X+Q10*
7 FN 12: IF +Q1 LT +Q2 GOTO LBL 99 N70 D12 P01 +Q1 P02 +Q2 P03 99*
5 LBL 99 N50 G98 L99*
References
- HEIDENHAIN, TNC 320 Klartext Programming User's Manual, NC software 77185x-18, 10/2023, ID 1096950-25.
- HEIDENHAIN, TNC 320 ISO Programming User's Manual, NC software 77185x-18, 10/2023, ID 1096983-25.
Have a question or want to contribute?
Contact us with corrections, additions, or topics you'd like covered.
Get in Touch