Heidenhain TNC7 Klartext & Q-Parameters

The TNC7 is HEIDENHAIN's flagship control (the smaller TNC7 basic and TNC7 go run the same software platform), and its Klartext language is the closest thing in the CNC world to a real programming language: typed variables, structured IF/ELSE and FOR/WHILE blocks, string handling, and Python-style format strings — alongside the classic FN functions carried over from earlier TNCs. This reference covers what you need to write macros on a TNC7, drawn from the 81762x-20 (10/2025) manuals.

Program Structure

A Klartext program (file extension *.h) is a list of numbered NC blocks. The first and last blocks are BEGIN PGM / END PGM with the program name and unit of measure (MM or INCH) — the control inserts them automatically and you cannot delete them (a program without END PGM is considered incomplete). Between them: blank definition, tool calls, movements, cycles.

0 BEGIN PGM EXAMPLE MM            ; Start of program
1 BLK FORM 0.1 Z X-50 Y-50 Z-20
2 BLK FORM 0.2 X+50 Y+50 Z+0      ; Workpiece blank definition (two NC blocks)
3 TOOL CALL 5 Z S3200 F300        ; Tool call
4 L Z+100 R0 FMAX M3              ; Straight-line traverse
...
11 M30                            ; End the NC program
12 END PGM EXAMPLE MM             ; End of program

Anatomy of a block: 4 TOOL CALL 5 Z S3200 F300 = block number + NC function; TOOL CALL is the syntax initiator, everything after it (5, Z, S3200, F300) are syntax elements. Always write the program as if the tool were moving — then it doesn't matter whether a head axis or table axis actually performs the motion. If you write programs off the control, spelling and element order must be exact.

Labels, Subprograms & Program Calls

Reusable machining goes into labels. LBL takes a number (0–65535) or a name up to 32 characters; LBL 0 marks the end of a subprogram and is the only label allowed to appear more than once.

FunctionSyntaxNotes
Within one program
Define labelLBL "UP1"LBL 0Subprogram body; place it after the block with M2/M30, otherwise it runs once uncalled
Subprogram callCALL LBL "UP1"Jumps to label, returns at LBL 0; a subprogram cannot call itself; CALL LBL 0 is not permitted
Program section repeatCALL LBL 1 REP2Repeats the section between LBL 1 and the call; total executions = REP + 1; up to 65 534 repeats; no LBL 0
Calling other programs
Direct callCALL PGM reset.hRuns the external program in place; it must NOT contain M2/M30 (replace with an unconditional jump to a label before program end)
Variable callSEL PGM "reset.h"CALL SELECTED PGMSEL PGM also accepts a QS parameter — this is how you call programs by computed name

Maximum nesting depth: 19 for subprogram calls and 19 for external program calls (a CYCL CALL counts as one); program-section repeats can be nested without limit. Variables are global across CALL PGM — changes made in the called program come back with you; use QL or named parameters when you want values contained to one program. Guard against a missing called file with FN 18: SYSREAD ID10 NR110/NR111 at program start. A nested example from the manual:

0 BEGIN PGM UPGMS MM
...
11 CALL LBL "UP1"                 ; Call subprogram "UP1"
...
21 L Z+100 R0 FMAX M30            ; Last block of main program
22 LBL "UP1"                      ; Start of subprogram "UP1"
...
31 CALL LBL 2                     ; Call subprogram 2 (one nesting level down)
...
41 LBL 0                          ; End of "UP1"
42 LBL 2                          ; Start of subprogram 2
...
51 LBL 0                          ; End of subprogram 2
52 END PGM UPGMS MM

Q-Parameter Types & Ranges

Five variable types. Numerical parameters accept −999 999 999 to +999 999 999 (up to nine digits before the decimal point); QS strings hold up to 255 characters. Values are stored IEEE 754 binary — expect rounding at the tenth decimal place, which matters for jump conditions on computed values.

TypeScopeRangeFree for the user?
Q — numeric, global to all NC programs
QGlobal (0–99 act locally inside macros/cycles; changes there don't come back)Q0–Q99Yes — if no overlap with HEIDENHAIN SL cycles
Q100–Q199No — control special functions, readable (probe results, tool data)
Q200–Q1199No — HEIDENHAIN functions (cycles)
Q1200–Q1599No — machine-manufacturer functions
Q1600–Q1999Yes — user-defined
QL — numeric, local to the NC program
QLLocalQL0–QL499Yes — all user-defined
QR — numeric, global AND retained through power-off (backed up)
QRGlobal, nonvolatileQR0–QR99Yes — user-defined
QR100–QR199No — HEIDENHAIN
QR200–QR499No — machine manufacturer
QS — strings, global
QSGlobal (0–99 local in macros/cycles)QS0–QS99Yes — if no overlap with HEIDENHAIN cycles
QS100–QS199No — control special functions
QS200–QS1399No — HEIDENHAIN / machine manufacturer
QS1400–QS1999Yes — user-defined
Named parameters — local, like QL
{NAME}LocalUp to 31 chars, letters/digits/underscore, must start with a letterYes — numeric or string, e.g. {DEPTH} = -10

Q100–Q199 and Q1200–Q1399 can't even be edited in the Q parameter list window (Q info button). SET UNDEFINED assigns the undefined status — a positioning block using an undefined Q parameter is simply ignored, but using one in arithmetic stops program run with an error. Preassigned parameters worth knowing: Q100Q107 PLC values, Q108 active tool radius, Q109 tool axis (−1 none, 0=X, 1=Y, 2=Z), Q110 last spindle M function (0=M3, 1=M4, 2=M5 after M3, 3=M5 after M4), Q111 coolant (1=M8, 0=M9), Q113 unit of measure (0=mm, 1=inch), Q114 active tool length, Q120Q122 calculated A/B/C rotary coordinates.

Assignments & Arithmetic — FN 0–5 and Formulas

FunctionExampleMeaning
Basic arithmetic
FN 0: AssignmentFN 0: Q5 = +60Assign a value (or SET UNDEFINED)
FN 1: AdditionFN 1: Q1 = -Q2 + -5Sum of two values
FN 2: SubtractionFN 2: Q1 = +10 - +5Difference of two values
FN 3: MultiplicationFN 3: Q2 = +3 * +3Product of two values
FN 4: DivisionFN 4: Q4 = +8 DIV +Q2Quotient — division by 0 not allowed
FN 5: Square rootFN 5: Q20 = SQRT 4Root — negative values not allowed
Trigonometry & geometry
FN 6 / FN 7FN 6: Q20 = SIN -Q5Sine / cosine of an angle in degrees
FN 8: Root of sum of squaresFN 8: Q10 = +5 LEN +4c = √(a²+b²) — third side of a triangle
FN 13: AngleFN 13: Q20 = +25 ANG -Q1arctan from opposite/adjacent side (0–360°)
FN 23 / FN 24: Circle dataFN 23: Q20 = CDATA Q30Circle center + radius from 3 (FN 23) or 4 (FN 24) points stored in consecutive parameters from Q30; results land in Q20/Q21/Q22

The Formula NC function packs several operations into one block with normal precedence (parentheses → sign → functions → ^* /+ ; chained powers evaluate right-to-left: 2^3^2 = 512). Available operators: + - * / ( ) SQ SQRT SIN COS TAN ASIN ACOS ATAN ^ PI LN LOG EXP NEG INT ABS FRAC SGN % (modulo). Note INT truncates — it does not round.

11 Q1 = 5 * 3 + 2 * 10            ; Result = 35
12 Q2 = SQ 10 - 3^3               ; Result = 73
13 Q4 = SIN 30 ^ 2                ; Result = 0.25 (function before power)
14 Q12 = 400 % 360                ; Result = 40 (modulo)

Part-family idiom straight from the manual — dimensions as variables, one value change per workpiece:

11 LBL "Z1"
12 FN 0: Q50 = +30                ; Cylinder radius
13 FN 0: Q51 = +10                ; Cylinder height
...
21 L X +Q50                       ; Behaves like L X +30

Jumps & Conditions — FN 9–12 and Structured Control

FunctionExampleJump when…
FN 9: IF EQUFN 9: IF +Q1 EQU +Q3 GOTO LBL "UPCAN25"values equal
FN 9: IS UNDEFINED / IS DEFINEDFN 9: IF +Q1 IS UNDEFINED GOTO LBL "UPCAN25"variable undefined / defined
FN 10: NEFN 10: IF +10 NE -Q5 GOTO LBL 10values not equal
FN 11: GTFN 11: IF +Q1 GT +10 GOTO LBL QS5first value greater
FN 12: LTFN 12: IF +Q5 LT +0 GOTO LBL "ANYNAME"first value less

The classic unconditional-jump trick — FN 9: IF+0 EQU+0 GOTO LBL1 — is how you skip over subprograms in a called program that isn't allowed to contain M30. But on the TNC7 you usually don't need FN jumps at all: the control has real structured control, and it indents the contained blocks for you. Conditions support ==, !=, <, >, <=, >= for numbers, and ==, !=, IN (substring, case-sensitive) for strings. One caveat: FN 9–12 jump commands are not allowed inside IF blocks or loops — the control errors out.

11 IF Q50 < Q60                   ; Case analysis
...
21 ELSE IF Q50 > Q60
...
31 END IF

11 FOR Q50 = 4 TO 10 STEP 2       ; Counted loop (integers only)
...
21 END FOR

13 WHILE Q50 <= Q60               ; Conditional loop
14   Q50 = Q50 + +1
...
21 END WHILE

BREAK aborts the enclosing FOR/WHILE loop; CONTINUE skips to the next repetition — e.g. IF Q182 == +1 (probing says scrap) BREAK END IF. Program BREAK only inside a case analysis so the abort happens only in the intended case.

String Processing — QS Parameters

Syntax elementPurposeExample
AssignmentAssign text (also DECLARE STRING)QS10 = "workpiece"
||Concatenate stringsQS10 = QS12 || QS13
TONUMBString → numberQ82 = TONUMB ( SRC_QS11 )
TOCHARNumber → stringQS11 = TOCHAR ( DAT+Q50 DECIMALS3 )
SUBSTRCopy substringQS13 = SUBSTR ( SRC_QS10 BEG2 LEN4 )
INSTRFind substring (returns char position, counting from 0; returns total length if not found)Q50 = INSTR ( SRC_QS10 SEA_QS13 BEG2 )
STRLENString length (−1 if undefined)Q52 = STRLEN ( SRC_QS15 )
STRCOMPLexical compare (0 identical, ±1 order)Q52 = STRCOMP ( SRC_QS12 SEA_QS14 )
SYSSTRRead alphanumeric system data (string twin of FN 18)QS25 = SYSSTR( ID 10950 NR1 )
CFGREADRead a machine parameter via key/entity/attribute QS parametersQ50 = CFGREAD( KEY_QS11 TAG_QS12 ATR_QS13 )

Format strings (requires code number 555343): the FMT syntax element embeds variables Python-f-string-style, killing most TOCHAR/concatenation chains: QS2 = FMT"ENJOY {QS1}{Q1}"ENJOY TNC7. Formatting after a colon — {Q1:+.2f} gives a signed fixed-point number with two decimals; alignment/fill like {QS1:X>10}; types d e E f g G.

Error Output with FN 14

FN 14: ERROR interrupts program run (also in simulation) and shows a predefined message; the program must be restarted. 11 FN 14: ERROR=1000 displays “Spindle must be turning”. Number ranges:

Error numberDialog
0–999Machine-dependent (defined by machine manufacturer)
1000–2999Control-dependent, preassigned by HEIDENHAIN (e.g. 1000 “Spindle must be turning”, 1004 “Range exceeded”, 1014 “Touch point inaccessible”)
3000–9999Machine-dependent
10 000+Control-dependent

The full preassigned list lives in the separate Overview of the Machine Parameters, Error Numbers and System Data document (ID 1445456-xx). Related: FN 38: SEND writes fixed/variable values to the log or an external app such as StateMonitor (FN 38: SEND /"Q1: %F" / +Q1, up to seven placeholders).

Worked Example — Part Counter Loop

From the manual: FUNCTION COUNT drives the control's built-in workpiece counter (shown on the PGM tab of the Status workspace, survives a restart, readable via FN 18: SYSREAD ID920 NR1). One shared counter serves Program Run and MDI — check before machining whether another program's counter is active.

11 FUNCTION COUNT RESET           ; Reset counter value
12 FUNCTION COUNT TARGET10        ; Target count = 10 parts
13 LBL 11                         ; Jump label
...                               ; Machining
21 FUNCTION COUNT INC             ; Count this part
22 FUNCTION COUNT REPEAT LBL 11   ; Repeat until target reached

References

  • HEIDENHAIN, TNC7 User's Manual — Programming and Testing, NC software 81762x-20, 10/2025, ID 1358773-24.
  • HEIDENHAIN, TNC7 series — Overview of the Machine Parameters, Error Numbers and System Data, 10/2025, ID 1445456-xx.

Have a question or want to contribute?

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

Get in Touch