This repository has been archived on 2026-10-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
HiNC-2025-win-desktop-Deploy/App/wwwroot/HiAPI-docsite/technique/nc-dialects/controller-heidenhain.html
T
2026-09-11 03:46:11 +08:00

493 lines
28 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Heidenhain Controller Support | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Heidenhain Controller Support | HiAPI-C# 2025 ">
<link rel="icon" href="../../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../../public/docfx.min.css">
<link rel="stylesheet" href="../../public/main.css">
<meta name="docfx:navrel" content="../../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../../index.html">
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Controllers/HeidenhainSupport">
<h1 id="heidenhain-controller-support">Heidenhain Controller Support</h1>
<p>Heidenhain programs run on a single controller preset that reads <strong>both</strong> dialects — TNC klartext
(TNC 640 / TNC 530 conversational) and Heidenhain <strong>DIN/ISO</strong>. There is no separate selection to
make: pick Heidenhain as the project's controller and the program is read in whichever dialect it is
written in.</p>
<p>Coverage is stated in the same three states as
<a href="controller-iso.html#how-to-read-this-page">General NC Code Support</a> — supported, recognized but not
simulated, and not supported. <em>Recognized but not simulated</em> is a deliberate state: the construct is
consumed and reported under its own message id, so it can never be silently misread as something
else. A <code>PLANE AXIAL B+45</code> will never be mistaken for a rotary-axis command.</p>
<h2 id="program-format">Program format</h2>
<h3 id="separators-are-optional">Separators are optional</h3>
<p>Klartext is normally written with spaces between the letter instructions, and that is what the
control shows. Some post-processors emit the same program with no separators at all. <strong>Both forms
parse</strong>, and so does the detached feed spelling.</p>
<blockquote>
<p>Equivalent, all parsed:</p>
<ul>
<li><code>L X-26.3 Y+43.1 Z+100.3 A-90.0 C+13.123 FQ3</code> and <code>LX-26.3Y+43.1Z+100.3A-90.0C+13.123FQ3</code></li>
<li><code>L X+0 Y+0 R0 FMAX</code> and <code>LX+0Y+0R0FMAX</code></li>
<li><code>FMAX M03 M08</code> and <code>FMAXM03M08</code></li>
<li><code>F20000</code> and <code>F 20000</code></li>
</ul>
</blockquote>
<h3 id="multi-line-blocks">Multi-line blocks</h3>
<p>A statement broken across lines with the tilde continuation — the usual shape of a <code>CYCL DEF</code> body or
a long <code>PLANE</code> statement — is joined back into one block before parsing, so it is read as the single
statement it is.</p>
<h2 id="motion">Motion</h2>
<table>
<thead>
<tr>
<th>Construct</th>
<th>Support</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>L</code></td>
<td>Straight-line motion with its axis words, absolute or <code>I</code>-prefixed incremental. See <a href="#incremental-axis-words-i-prefix">Incremental axis words</a>.</td>
</tr>
<tr>
<td><code>LN</code></td>
<td>Surface-normal block — a straight line carrying the endpoint plus up to two normalized vectors, in the fixed element order <code>X,Y,Z</code> → <code>NX,NY,NZ</code> → <code>TX,TY,TZ</code>. The endpoint words take the <code>I</code> prefix; the vector words have no incremental form. See <a href="#vector-blocks-ln">Vector blocks</a>.</td>
</tr>
<tr>
<td><code>FMAX</code></td>
<td>Rapid traverse.</td>
</tr>
<tr>
<td><code>CC</code> / <code>C</code></td>
<td>Circular motion — <code>CC</code> sets the pole, <code>C</code> states the end point. <code>DR-</code> is clockwise and <code>DR+</code> counter-clockwise, the centre always comes from the modal <code>CC</code> rather than from the <code>C</code> block, and an arc that closes on its start point is a full circle. Both heads accept <code>I</code>-prefixed words — an incremental pole on <code>CC</code>, an incremental end point on <code>C</code>. See <a href="#arc-centres-cc">Arc centres</a>.</td>
</tr>
<tr>
<td><code>RL</code> / <code>RR</code> / <code>R0</code></td>
<td>Radius compensation left / right / off.</td>
</tr>
<tr>
<td><code>M91</code></td>
<td>One-shot machine-coordinate move for that block.</td>
</tr>
<tr>
<td><code>M126</code> / <code>M127</code></td>
<td>Shortest-path rotary traverse on / off. With neither stated, shortest path is the default. An <code>I</code>-prefixed rotary word is exempt either way — see <a href="#incremental-axis-words-i-prefix">Incremental axis words</a>.</td>
</tr>
<tr>
<td><code>M140 MB+n</code> / <code>M140 MB MAX</code></td>
<td>Tool-axis retract — by <code>n</code> mm, or to the positive Z stroke limit. Without a configured stroke limit, <code>MB MAX</code> reports <code>M140--NoStrokeLimit</code> and is skipped. The statement's own <code>F</code> drives the retract without entering the modal feedrate.</td>
</tr>
<tr>
<td><code>STOP</code></td>
<td>Program stop, alongside <code>M00</code> / <code>M01</code>.</td>
</tr>
<tr>
<td><code>CYCL DEF 32 TOLERANCE</code></td>
<td>Path-smoothing tolerance.</td>
</tr>
<tr>
<td><code>BLK FORM</code></td>
<td>Recorded as a stock declaration. It does <strong>not</strong> replace the workpiece configured in the project.</td>
</tr>
</tbody>
</table>
<h3 id="incremental-axis-words-i-prefix">Incremental axis words (<code>I</code> prefix)</h3>
<p>An axis word may carry the <code>I</code> prefix — <code>IX+20</code>, <code>IY-15</code>, rotary <code>IC+90</code> — and is then a relative
value rather than a coordinate. Five statement heads read the prefix: <code>L</code>, <code>C</code>, <code>CC</code>, <code>LN</code> and
<code>CYCL CALL POS</code>. On the first four it is a distance from the last programmed position; <code>CYCL CALL POS</code> spells it the same way but measures from the coordinates of the previous <code>CYCL CALL POS</code>, and
is described under <a href="#cycles-and-calls">Cycles and calls</a>. <code>L</code>, <code>C</code> and <code>LN</code> take the full axis set,
rotary letters included; <code>CC</code> and <code>CYCL CALL POS</code> take <code>X</code> / <code>Y</code> / <code>Z</code> only, because neither
positions a rotary axis.</p>
<p>The prefix is per word, not a mode — klartext has no modal <code>G90</code> / <code>G91</code> counterpart, and only the
<code>I</code>-marked words of a block are read as distances. Absolute and incremental words therefore mix
freely inside one block.</p>
<blockquote>
<p>Parsed:</p>
<ul>
<li><code>L IX+20 IY-15</code> — both axes relative</li>
<li><code>L X+60 IY-10</code> — to X 60, and by −10 in Y</li>
<li><code>LIX+20IY-15</code> — glued, exactly as the separator-free absolute form parses</li>
<li><code>L IX5</code> — the sign is optional</li>
<li><code>L IZ+Q2</code> and <code>L IY-Q2</code> — the value grammar behind the prefix is the shared one, so a <code>Q</code>
parameter or a bracket expression reaches it like any other value</li>
</ul>
</blockquote>
<p>A rotary <code>I</code> word is a chain dimension — a signed traverse — and keeps the value it accumulates
instead of being folded into the ±180° shortest-path window: <code>IC+270</code> from 75° ends at 345°, not at
−15°. That exemption is per word and per block. It does not turn shortest path off for the rest of
the block: an absolute rotary word on the very same block is still taken the short way round, and
<code>M127</code> remains the modal switch.</p>
<p>One further <code>I</code> spelling on this control is <strong>not</strong> this mechanism at all: the <code>CYCL DEF 7</code>
datum-shift words shift the active datum rather than positioning an axis, and are described under
<a href="#datums">Datums</a>.</p>
<h3 id="arc-centres-cc">Arc centres (<code>CC</code>)</h3>
<p>A <code>C</code> block never states its own centre. Each in-plane component is resolved from the modal <code>CC</code>
section: the <code>CC</code> block's own axis word first, then the same axis of the previous <code>CC</code>, and last the
arc's own start point. A <code>CC</code> stating no coordinates is the one spelling that supplies all three at
once — it takes the last programmed position, read at the <code>CC</code> block rather than at the arc, and
replaces the modal centre instead of inheriting it. That is what makes the manual's own shape work:
<code>CC</code> on the centre, a move out to the arc start, then the <code>C</code> block.</p>
<p>An incremental centre is not that spelling. <code>CC IX+0 IY+11</code> <strong>states</strong> a centre — a distance from
the last programmed <strong>tool</strong> position, never from the previous centre — and it is absolute by the
time the arc consumes it. Nor is a <code>CC</code> whose coordinates cannot be read: it leaves residue and
reports <code>UnparsedText--Remaining</code>, and because it states no centre every axis falls through the
modal chain — to the same axis of the previous <code>CC</code> where there is one, and only otherwise to the
arc's own start point as below. Either way the position of the unreadable <code>CC</code> block is never
read as the centre.</p>
<p>A centre that lands on the arc's own start point leaves the block with no radius and so no arc
geometry: it reports <code>Arc-CircleCenter--OnStartPoint</code> and is degraded to a straight move to the
endpoint. One in-plane coordinate is enough to escape that — an arc whose modal chain still leaves
the other coordinate to the start point keeps real geometry and plays normally, and is refused only
by the optimizer's splition, described under <a href="#optimized-output">Optimized output</a>.</p>
<h3 id="vector-blocks-ln">Vector blocks (<code>LN</code>)</h3>
<p>CAM-generated five-axis programs state the posture as vectors rather than as rotary words. An <code>LN</code>
block carries the endpoint plus the surface-normal vector <code>NX</code>/<code>NY</code>/<code>NZ</code> — the 3D tool-compensation
direction — and, optionally, the tool vector <code>TX</code>/<code>TY</code>/<code>TZ</code>. HiNC resolves whichever vector governs
into the machine's rotary axes and feeds the result through the same RTCP machinery the rotary-word
programs use, so there is no second motion path to reason about.</p>
<p>Which vector governs follows the control's own rules:</p>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Tool axis</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>T</code> present, <code>M128</code> or <code>FUNCTION TCPM</code> active</td>
<td>The <code>T</code> vector — the tool keeps the set orientation.</td>
</tr>
<tr>
<td><code>T</code> absent, RTCP active</td>
<td>The surface normal <code>N</code> — the tool is held perpendicular to the contour.</td>
</tr>
<tr>
<td>RTCP inactive</td>
<td>The <code>T</code> vector is <strong>ignored</strong>, exactly as the control ignores it. Reported as <code>Orientation-Vector--IgnoredNoTcpm</code>, with the posture left untouched.</td>
</tr>
</tbody>
</table>
<p>RTCP counts as active when the same block turns it on, so a block that both activates RTCP and
carries a vector is not skipped.</p>
<p>Two limits are worth knowing before trusting the result:</p>
<ul>
<li>The vector is read in the <strong>untilted</strong> program frame. An <code>LN</code> block under an active <code>PLANE</code> tilt is
reported as <code>Orientation-Vector--TiltedFrameAssumed</code> rather than remapped.</li>
<li>Compensation <strong>along</strong> the surface normal (<code>DR2</code> / 3D-ToolComp) is recognized, not simulated —
<code>SurfaceNormal--CompNotSimulated</code>, raised once per run.</li>
</ul>
<p>A vector that is not unit length is normalized and reported (<code>Orientation-Vector--NotNormalized</code>); a
zero vector is reported as <code>Orientation-Vector--ZeroVector</code>.</p>
<h2 id="tools">Tools</h2>
<p><code>TOOL CALL</code> performs the tool change on its own — klartext has no separate <code>M06</code> trigger. A tool
number or a quoted tool name is accepted.</p>
<blockquote>
<p>Parsed:</p>
<ul>
<li><code>TOOL CALL 1 Z S5000</code></li>
<li><code>TOOL CALL &quot;1&quot; Z S5000</code></li>
<li><code>TOOL CALL &quot;B40R&quot; Z S3000 DL+0.5</code></li>
</ul>
</blockquote>
<ul>
<li>The spindle speed <code>S</code> is recorded modally.</li>
<li><code>DL</code> is a length delta — the effective tool height is the tool-table height <strong>plus</strong> <code>DL</code>.</li>
<li><code>DR</code> is read and recorded but <strong>not applied</strong>: radius compensation uses the tool-table radius as-is,
and the block reports <code>ToolChange--DeltaUnsupported</code>.</li>
<li>A <code>DL</code>/<code>DR</code> that is not a literal value — an unevaluated variable, for example — is ignored and
reports <code>ToolChange--DeltaNotLiteral</code>.</li>
<li>A tool axis other than <code>Z</code> reports <code>ToolChange--AxisUnsupported</code>.</li>
<li>A <code>TOOL CALL</code> whose tool number could not be captured — an unevaluated variable, for example —
reports <code>ToolChange--MissingToolId</code>.</li>
</ul>
<h2 id="datums">Datums</h2>
<p><code>CYCL DEF 247</code> sets the datum preset and <code>CYCL DEF 7</code> is an <strong>additive</strong> shift on top of it, which is
the TNC semantic. The two compose as separate entries in the coordinate chain instead of replacing
each other.</p>
<blockquote>
<p>Parsed:</p>
<pre><code>CYCL DEF 247 Q339=+1
</code></pre>
<pre><code>CYCL DEF 7.0 DATUM SHIFT
CYCL DEF 7.1 X10.123
CYCL DEF 7.2 Y22.223
CYCL DEF 7.3 Z32.97
</code></pre>
</blockquote>
<p>A <code>CYCL DEF 7</code> axis word may itself carry the <code>I</code> prefix — <code>CYCL DEF 7.2 IY+5</code> shifts the datum by a
further 5 in Y on top of the shift last valid. Unlike the <code>L</code> / <code>C</code> / <code>CC</code> / <code>LN</code> words, this one is not a
distance from the tool position at all: it stays inside the cycle's own record and never becomes per-word
incremental positioning, so it can never reach the optimizer's incremental guard. Only <code>X</code> / <code>Y</code> /
<code>Z</code> are applied; a non-zero rotary word there, <code>IC+90</code> as much as <code>C+90</code>, is consumed and reported as
<code>Datum-Shift--Rotary</code>.</p>
<h2 id="q-parameters-and-fn">Q parameters and FN</h2>
<p><code>Q</code>, <code>QR</code>, <code>QL</code> and <code>QS</code> parameters are read wherever a value is expected, so <code>FQ1</code> reaches the
feedrate, <code>L X+Q2</code> reaches the program position and <code>TOOL CALL SQ3</code> reaches the spindle speed. <code>Q0</code>–<code>Q99</code>
free parameters and <code>QR0</code>–<code>QR499</code> permanent parameters are held as per-project data and saved with
the project.</p>
<table>
<thead>
<tr>
<th>Construct</th>
<th>Support</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>FN 0</code>–<code>FN 5</code></td>
<td>Assignment and arithmetic, including the <code>DIV</code> keyword of FN 4 and the prefix <code>SQRT</code> of FN 5.</td>
</tr>
<tr>
<td><code>FN 9</code>–<code>FN 12</code></td>
<td>Conditional jumps — <strong>executed</strong>, with a per-label iteration cap so a corrupt or hostile program cannot spin forever.</td>
</tr>
<tr>
<td>Other <code>FN</code> opcodes (<code>FN 14</code>, <code>FN 16</code>, <code>FN 18 SYSREAD</code>, …)</td>
<td>Recognized, not simulated. The statement is claimed and reported, so its target parameter stays empty instead of taking a fabricated value.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Parsed:</p>
<ul>
<li><code>Q1 = 5000</code></li>
<li><code>FN0: Q1 = 5000</code></li>
<li><code>FN1: Q1 = -Q2 + -5</code></li>
<li><code>FN2: Q1 = +10 - +5</code></li>
<li><code>FN3: Q2 = +3 * +3</code></li>
</ul>
</blockquote>
<h2 id="tilted-planes-and-rtcp">Tilted planes and RTCP</h2>
<table>
<thead>
<tr>
<th>Construct</th>
<th>Support</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>PLANE SPATIAL</code></td>
<td>Fully composed, including <code>SEQ+</code> / <code>SEQ-</code>, <code>COORD ROT</code> / <code>TABLE ROT</code>, and the <code>STAY</code> / <code>MOVE</code> / <code>TURN</code> positioning behaviours.</td>
</tr>
<tr>
<td><code>PLANE RESET</code></td>
<td>Cancels the tilt.</td>
</tr>
<tr>
<td><code>PLANE VECTOR</code></td>
<td>Structurally captured, not simulated.</td>
</tr>
<tr>
<td><code>PLANE EULER</code> / <code>POINTS</code> / <code>RELATIV</code> / <code>AXIAL</code> / <code>PROJECTED</code></td>
<td>Recognized, not simulated — consumed and reported as <code>HeidenhainPlane--Unsupported</code>, with the previous tilt retained.</td>
</tr>
<tr>
<td><code>FUNCTION TCPM</code></td>
<td>Supported, read as the default <code>REFPNT TIP-TIP</code>. A center-referenced reference point (<code>REFPNT CNT-CNT</code> / <code>TIP-CENTER</code>) is <strong>recognized, not simulated</strong>: the coordinates are still taken as tip-to-tip, so CNT-referenced CAM output simulates offset by the ball radius along the tool axis. Reported as <code>Orientation-RefPoint--CntNotSimulated</code>.</td>
</tr>
<tr>
<td><code>M128</code> / <code>M129</code></td>
<td>Tool centre point control on / off — real RTCP, the Heidenhain sibling of ISO <code>G43.4</code> and Siemens <code>TRAORI</code>.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Parsed:</p>
<ul>
<li><code>PLANE SPATIAL SPA-60.3 SPB+0 SPC-19.88 STAY SEQ- TABLE ROT</code></li>
<li><code>PLANE RESET STAY</code></li>
</ul>
</blockquote>
<h2 id="cycles-and-calls">Cycles and calls</h2>
<ul>
<li><strong><code>CYCL DEF 2xx</code></strong> bodies are read with their <code>Q</code> parameters mirrored into the block. Cycles <strong>200</strong>,
<strong>232</strong>, <strong>251</strong>, <strong>252</strong> and <strong>253</strong> are mapped onto the shared drilling machinery and simulated;
the mapping follows the cycle's own <code>Q</code> values, so a <code>Q202</code> peck increment routes to peck drilling
and a <code>Q211</code> bottom dwell to dwell drilling.</li>
<li>A <code>CYCL DEF</code> body that is not one of those is recognized, not simulated — reported as
<code>HeidenhainCycl--Unsupported</code>.</li>
<li><strong><code>CYCL CALL</code></strong> and <strong><code>CYCL CALL POS</code></strong> fire the cycle once; <code>M99</code> fires once and <code>M89</code> arms modal
firing.</li>
<li>A <strong><code>CYCL CALL POS</code></strong> position word takes the <code>I</code> prefix, and its reference is the control's own:
the coordinates last programmed by a <strong>previous <code>CYCL CALL POS</code></strong>, not the current tool position.
With no earlier call for that axis the increment has no reference and the control refuses the block
(its error <code>1A0-0108</code>); the simulation reports <code>HeidenhainCyclCall--IncrementalNoReference</code> and
resolves against the last programmed position instead. When the tool moved between the two calls
the two candidate references differ — the control's stated one is used, and the divergence is
reported as <code>HeidenhainCyclCall--IncrementalAfterMove</code>.</li>
<li><strong><code>CALL LBL n</code></strong> inlines the label body up to <code>LBL 0</code>; <strong><code>CALL LBL n REP m</code></strong> repeats that section
<code>m</code> times.</li>
<li><strong><code>CALL PGM</code></strong> resolves the called program by file name.</li>
<li><strong>Mirror image</strong> in both spellings — the klartext <code>CYCL DEF 8</code> form and the DIN/ISO <code>G28</code> form.</li>
</ul>
<h2 id="diniso-dialect">DIN/ISO dialect</h2>
<p>The same preset, with nothing to switch.</p>
<ul>
<li><code>%</code> tape header and <code>N</code> block numbers.</li>
<li><code>T</code> plus <code>M06</code> tool change.</li>
<li><strong>Arc centres <code>I</code> / <code>J</code> / <code>K</code> are absolute pole coordinates</strong>, not incremental offsets from the
start point. This is the Heidenhain reading, and the pole carries forward modally.</li>
<li>The ISO label family — <code>G98 L&lt;n&gt;</code> definitions, and the head-anchored <code>L&lt;n&gt;,&lt;m&gt;</code> call whose comma
count maps onto the repeat count.</li>
<li><code>G247 Q339</code> stamps the same datum preset as <code>CYCL DEF 247</code>.</li>
<li><code>G54</code> with axis words is read as a datum-shift declaration.</li>
<li><code>G70</code> / <code>G71</code> units.</li>
</ul>
<div class="WARNING">
<h5>Warning</h5>
<p><strong><code>G28</code> on Heidenhain is MIRROR IMAGE, not a reference-point return.</strong> The Fanuc reading of <code>G28</code>
is deliberately absent from the Heidenhain preset. Select the Heidenhain controller for a
Heidenhain DIN/ISO file — read as Fanuc, every mirror statement becomes a home move.</p>
</div>
<h2 id="optimized-output">Optimized output</h2>
<p>An optimized program is patched into the source text block by block rather than re-emitted, so it
comes back in the dialect it was written in, and two rules keep the result a program a TNC will
accept.</p>
<p>A feed the optimizer writes into a block that carried none lands after the coordinate words and
after <code>DR+</code> / <code>DR-</code> and <code>RL</code> / <code>RR</code> / <code>R0</code>, so the element order the control expects — coordinates,
rotation direction, radius compensation, <code>F</code>, <code>M</code> — holds on the patched block: <code>L X+10 Y+20 RL</code>
comes back as <code>L X+10 Y+20 RL F500</code>. A block that already states an <code>F</code> keeps that word where it
stands, and only its number changes — unless the feed is <code>FMAX</code>, <code>FAUTO</code> or a <code>Q</code> parameter, which
patch mode refuses to rewrite: the block is left exactly as written, reporting
<code>Writeback-Patch--KeywordValue</code> or <code>Writeback-Patch--VariableValue</code>.</p>
<p>The optimizer's embedded source note is written in the klartext comment grammar — a <code>;</code> comment,
never a parenthesized one, because a TNC reads parentheses as code:</p>
<pre><code>120 L X+35 Y-11.7 R0 F500 ;src(LineNo: 140, StepIndex: 256)
</code></pre>
<p>Re-interpolation itself is not refused for being klartext. A <code>C … DR±</code> arc splits like any other
when the modal <code>CC</code> chain supplies both in-plane centre coordinates <strong>and</strong> the <code>C</code> block states its
own words absolutely: no centre words are rebuilt, and each fragment carries the block's own words
with its own endpoint and feed, around the one <code>CC</code> line they all share unchanged. An incremental
<code>CC</code> does not disqualify the arc it feeds — the per-word mark sits on the <code>CC</code> block alone and never
carries forward, and the centre reaches the arc already resolved.</p>
<p>Two shapes are optimized as whole lines instead. Each reports its own id, once per run.</p>
<ul>
<li>The arc whose modal chain left an in-plane coordinate unstated — no <code>CC</code> ever gave it, so the arc's
own start point supplies it, and every fragment would re-derive that centre from its own start:
<code>NcOpt--SplitionStartPointCenterUnsupported</code>.</li>
<li>The piece that carries an incremental word of its own — a klartext <code>I</code>-prefixed word, as in the
legal and fully simulated <code>C IX+20 IY+0 DR-</code>, or a <code>G91</code> block in the DIN/ISO dialect. The fragment
rewrite emits absolute coordinates, so every fragment would re-apply the distance from its own
start: <code>NcOpt--SplitionIncrementalUnsupported</code>. The test reads the piece's own block only — the
state of the modal <code>CC</code> chain neither triggers this one nor exempts a piece from it.</li>
</ul>
<h2 id="not-supported">Not supported</h2>
<p><code>TOOL DEF</code>, <code>FK</code> free-contour programming, <code>SL</code> cycles, <code>PATTERN DEF</code>, and <code>TCH PROBE</code>. These are left
unconsumed, and the block that carried them reports <code>Parsing--Unconsumed</code> naming the words.</p>
<p>Machine-specific M-codes that are not part of the Heidenhain vocabulary above are declared on the
machine rather than built in — see the M-code note on
<a href="controller-iso.html#m-codes">General NC Code Support</a>.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="controller-iso.html">General NC Code Support</a> — Fanuc, Syntec, Mazak and Siemens SINUMERIK.</li>
<li><a class="xref" href="nc-parsing.html">NC Parsing Engine</a> — the pipeline behind these constructs, the
brand-by-brand support matrix in one table, and how a machine's own vocabulary is added without
changing HiNC.</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>