Overview
The Siemens SINUMERIK 802D sl milling control system integrates a CNC keyboard and an operator panel front with a 10.4-inch color TFT display, 8 + 2 horizontal and 8 vertical softkeys. Custom operator screens running on this panel can read PLC bit, byte, and word variables and render dynamic content (icons, text, softkey states) without external SCADA software. This article documents a field-proven method to drive a screen graphic (for example, door open / closed) from a single PLC bit using the DialogGui XML dialect shipped with the 802D sl HMI runtime, using a <timer> tag to poll the bit and conditional <img> placement to swap graphics.
Prerequisites
- 802D sl control with HMI software version supporting
DialogGuiuser screens (refer to the 802D sl Function Manual for the exact version mapping of your CNC software). - PLC program compiled and downloaded; the bit you want to visualize must be reachable through the PLC-NC interface as a memory byte, input byte, or flag byte.
- Bitmap assets (24-bit or 8-bit BMP / PNG) copied to
F:\appl\on the CF card (path is case-insensitive on the 802D sl filesystem). - Read access to the addressing manual for the 802D sl PLC so the correct NCK/PLC address range is selected (default: MB0..MB127 for flag bytes; IB / QB for I/O).
DialogGui XML Building Blocks
The 802D sl user-screen interpreter consumes an XML document with the root tag <DialogGui>. The relevant tags for a status-driven screen are summarized below.
| Tag | Function | Typical attributes |
|---|---|---|
<let> |
Declares a screen-local variable |
name, value
|
<menu> |
Defines a screen entry point and its softkey bar | name |
<softkey> |
Configures a horizontal softkey |
POSITION, picture, caption, op, navigation
|
<open_form> |
Loads a form when the menu opens | name |
<form> |
Defines a layout container with init and timer blocks |
name, caption
|
<control> |
Places an I/O field bound to a PLC variable |
name, xpos, ypos, width, refvar, hotlink
|
<img> |
Renders a bitmap |
name, xpos, ypos
|
<op> |
Evaluates an expression and writes the result | expression body |
<if> |
Branches on a Boolean expression |
condition, then, else
|
<timer> |
Polled on every HMI tick (≈ 100 ms) | (none — body executes each tick) |
<data_access> |
Toggles write access to PLC variables from the form |
type="true" = write-enabled |
Bit-Masking Logic on Byte Variables
The 802D sl DialogGui runtime does not provide a native bit-test operator. To inspect a single bit you must read the entire byte, AND it with a mask that has a 1 in the target bit position, and compare the result against 0 (bit cleared) or 1 (bit set). The bit number 0..7 maps to the mask value 1, 2, 4, 8, 16, 32, 64, 128 respectively.
| Bit | Decimal mask | Hex mask | Test expression (bit set) |
|---|---|---|---|
| 0 | 1 | 0x01 | (plc/mb1 & 1) == 1 |
| 1 | 2 | 0x02 | (plc/mb1 & 2) == 2 |
| 2 | 4 | 0x04 | (plc/mb1 & 4) == 4 |
| 3 | 8 | 0x08 | (plc/mb1 & 8) == 8 |
| 4 | 16 | 0x10 | (plc/mb1 & 16) == 16 |
| 5 | 32 | 0x20 | (plc/mb1 & 32) == 32 |
| 6 | 64 | 0x40 | (plc/mb1 & 64) == 64 |
| 7 | 128 | 0x80 | (plc/mb1 & 128) == 128 |
To set a bit in a PLC byte from the HMI use the OR pattern: plc/mb1 = plc/mb1 | mask. To clear a bit use the AND-NOT pattern: plc/mb1 = plc/mb1 & (255 - mask). These are the only two ways to manipulate individual bits because no atomic bit-operation helper exists in the runtime.
Reference Implementation: Door Status Screen
The complete listing below is taken directly from the 802D sl HMI development reference. It uses flag byte mb1 as a stand-in for a real safety door input, bit 0 representing the door state (1 = closed, 0 = open). A horizontal softkey toggles the bit so an operator without a real PLC can exercise the screen during commissioning.
<DialogGui>
<let name="door_byte">0</let>
<let name="door_byte_old">0</let>
<menu name = "MAIN">
<open_form name = "main_form" />
<!-- soft-key displays and changes the door status -->
<if>
<condition>("plc/mb1" & 1) == 0</condition>
<then>
<softkey POSITION="1" picture="f:\appl\red_led_off.bmp">
<caption>close%ndoor</caption>
<op> "plc/mb1" = "plc/mb1" | 1 </op>
<navigation>main</navigation>
</softkey>
</then>
<else>
<softkey POSITION="1" picture="f:\appl\red_led_on.bmp">
<caption>open%ndoor</caption>
<op> "plc/mb1" = "plc/mb1" & (255 - 1)</op>
<navigation>main</navigation>
</softkey>
</else>
</if>
</menu>
<form name="main_form">
<init>
<caption>Show door </caption>
<data_access type="true" />
<control name = "door_test" xpos = "440" ypos = "212" width="80" refvar="plc/mb1" hotlink="true" />
<op> door_byte_old = 255 </op>
</init>
<timer>
<op> door_byte = "plc/mb1" & 1 </op>
<print text="%d">door_byte</print>
<if>
<condition>door_byte != door_byte_old </condition>
<then>
<op> door_byte_old = door_byte </op>
<if>
<condition>door_byte == 0 </condition>
<then>
<img name ="f:\appl\door_o.png" xpos ="10" ypos = "24" />
</then>
<else>
<img name ="f:\appl\door_c.png" xpos ="10" ypos = "24" />
</else>
</if>
</then>
</if>
</timer>
</form>
</DialogGui>
How the Timer Polling Loop Works
The HMI runtime calls the body of every <timer> tag on its internal tick (nominally 100 ms, but do not hard-code against that — the scheduler is also driven by PLC sign-of-life events). Inside the loop the screen performs three operations:
-
Read and mask.
door_byte = "plc/mb1" & 1extracts bit 0 of the flag byte.door_byteis now either 0 (bit clear → door open) or 1 (bit set → door closed). -
Compare with last state.
door_byte != door_byte_oldguards against re-rendering the same image on every tick. Only when the bit actually transitions does the inner<if>execute. -
Render the appropriate graphic. The inner
<if>placesdoor_o.pngat (10, 24) when the bit is 0, ordoor_c.pngat the same coordinates when the bit is 1. Because only one<img>tag is emitted per tick, the previous graphic is overwritten by the new one on the next repaint.
The door_byte_old = 255 seed in the <init> block guarantees that the first tick after the form opens will always trigger a redraw, even if the PLC bit is already 0.
Why Use the Softkey Toggle Pattern
Although the door input normally comes from a real PLC input wired to a limit switch, the <softkey> block in the listing doubles as a commissioning tool. By pressing horizontal softkey 1, the operator writes either plc/mb1 | 1 (set bit 0) or plc/mb1 & 254 (clear bit 0) back into the same flag byte. This is enough to validate:
- That the
<timer>body is firing (watch the<print>output if your build routes it to a log file). - That the image swap logic is wired to the correct polarity.
- That the
<data_access type="true" />directive is present in<init>; without it the HMI will reject the write and the softkey will appear to do nothing.
Scaling to Multiple Status Indicators on One Screen
Each move in a manual-cycle screen can be driven by its own bit. The standard pattern is:
- Reserve a flag byte per indicator. A contiguous block
mb10..mb19keeps the bit math easy. - For each indicator, add one
door_bytelocal variable and onedoor_byte_oldlocal variable (rename them:m1_byte,m1_byte_old, etc.). - In the
<timer>body, repeat the mask + compare +<img>triplet for each bit, with a distinct image file and x/y position per indicator. - Place a colored square or icon in a fixed grid; do not let the
<img>coordinates overlap, because the older image is repainted only when the new<img>tag is emitted, not cleared automatically.
For more than 8 indicators on the same screen consider switching from bit-level graphics to a numeric <control> field with a refvar bound to a status word, and translating the word to a colored bar via the standard 802D sl widget set. This avoids filling the <timer> with cascading <if> blocks, which can make the screen sluggish on older 802D sl panels.
Step-by-Step Commissioning Procedure
-
Prepare the assets. Copy the bitmap pair (
door_o.png,door_c.png) and the softkey icons (red_led_on.bmp,red_led_off.bmp) toF:\appl\on the CF card. Use 24-bit BMP for softkeys; the runtime expects uncompressed bitmaps for the horizontal softkey area. -
Reserve a flag byte. In the PLC program, allocate
MB1(or any unused flag byte) for the test input. In the real deployment, the bit comes from a real input such asI0.0mapped toMB1via a contact-and-coil network, or a direct input byte likeIB0. - Author the screen. Place the XML in the operator-area user-screen directory on the CF card; the runtime looks for files at every cold start.
-
Compile and download the PLC. Without a valid PLC program,
plc/mb1reads back undefined values and the<timer>may bounce between states. - Cold-restart the HMI. Navigate to the operator area, open the user screen, and observe the initial state of the door graphic. It should match the actual PLC bit within 100–200 ms (one or two HMI ticks).
-
Exercise the softkey. Press horizontal softkey 1; the graphic should swap, the bound
<control>field should show the new byte value (0 or 1), and the softkey caption should change from "close door" to "open door". -
Disconnect the softkey for production. Comment out or remove the
<softkey>block, and remove the<data_access type="true" />directive from<init>to lock the form back to read-only.
Verification Checklist
| Check | Pass criterion | Failure mode |
|---|---|---|
| Initial render | Image matches mb1 bit state within 2 ticks |
Wrong mask (bit position off by one) or wrong byte address |
| Toggle response | Softkey changes image within 1 tick of PLC write acknowledge |
<data_access> missing or hotlink="false" on the control |
| CPU load | Timer-driven screen < 5 % of HMI processor budget | Too many indicators or excessive <print> calls in <timer>
|
| Display flicker | No intermediate redraws on unchanging bits |
door_byte_old not initialized to 255, or comparison is inverted |
| Backwards compatibility | Same XML loads on 802D sl HMI versions documented in the function manual | Tag used that was introduced in a later build (check release notes) |
Troubleshooting Matrix
| Symptom | Likely root cause | Corrective action |
|---|---|---|
| Image never updates |
<timer> missing from <form> or body is empty |
Insert a single <op> door_byte = "plc/mb1" & 1 </op> and a <print> for diagnostic output |
| Image updates on every tick (flicker) |
door_byte_old not compared correctly |
Confirm door_byte_old = 255 in <init> and the != comparison is in the outer <if>
|
| Softkey does nothing |
<data_access type="true" /> missing |
Add the directive as the first child of <init>
|
| Image shows inverted state | Mask or polarity wrong (door open = 0 vs door open = 1) | Swap the <then> / <else> branches of the inner <if>
|
| Screen does not appear in operator area | Custom screen registered in wrong folder, or outside the operator area | Verify the file lives in the operator-area subdirectory per the 802D sl Function Manual |
| Bitmap not displayed (red X icon) | File path is wrong, case mismatch, or image is in a format the runtime does not decode | Use BMP for softkeys; PNG is supported for <img> only on recent builds |
| HMI becomes sluggish with multiple indicators | Each indicator is a separate <if> cascade inside one <timer>
|
Split indicators into multiple <form> blocks, or switch to status-word <control> fields |
Edge Cases and Field-Proven Caveats
- PLC sign-of-life dependence. On some 802D sl builds the timer tick is gated by the PLC cyclic sign-of-life (SVST/SAZ). If the PLC is in STOP, the timer may not fire and the screen freezes on the last rendered image. Always verify the PLC is in RUN before blaming the screen logic.
-
Path separators. The HMI filesystem uses DOS-style backslashes. The forward-slash form (
f:/appl/...) is sometimes accepted on newer HMI software versions but the manual shows the backslash form (f:\appl\...). Use backslashes for maximum compatibility. -
Integer overflow in masks. The pattern
plc/mb1 & (255 - mask)assumes a single-byte result. If you accidentally pass a word variable and a mask larger than 255, the subtraction underflows to a 32-bit value and the AND produces a 16- or 32-bit result that the runtime will silently truncate when writing back to the byte address, leaving stray high bits set. -
Hotlink vs poll.
hotlink="true"on the<control>only refreshes that single control when the underlying variable changes. It does not wake the<timer>. The timer fires on the HMI's own schedule regardless of PLC state changes. - Softkey position range. The horizontal softkey area supports positions 1 through 8 plus 2 horizontal extensions, matching the 8 + 2 hardware keys on the 802D sl operator panel front described in the control system overview. Position values outside 1..10 are rejected at parse time.
- Image coordinates. xpos and ypos are in pixels measured from the top-left of the 10.4-inch TFT panel. With a 640 × 480 native resolution the (10, 24) origin used in the listing leaves a 24-pixel margin from the top — typical for a status bar.
Alternatives Worth Considering
For a deployment that needs many boolean indicators, evaluate these alternatives before scaling the timer-driven <img> approach further:
- PLC alarm text. The 802D sl HMI displays PLC alarm messages with configurable text and acknowledge keys. This is the recommended path for operator-facing event notification, because the alarm log persists across power cycles and is filterable.
-
Status word with bar widget. Bind a 16-bit status word to a single
<control>field and use the runtime's built-in bit-to-icon mapping (introduced in later 802D sl HMI versions) instead of a hand-rolled mask-and-compare cascade. - External HMI panel. For very complex screens, supplement the 802D sl operator panel with a Siemens TP or Comfort panel that can be addressed over PROFINET, while keeping the 802D sl focused on CNC operating screens.
How do I read a single bit from a PLC byte on a 802D sl custom screen?
AND the byte with a mask that has a 1 in the target bit position and compare the result to 0 or 1. For bit 0 of mb1 the expression is (plc/mb1 & 1) == 0 (cleared) or (plc/mb1 & 1) == 1 (set). The runtime has no native bit-test operator, so this mask-and-compare is mandatory.
How often does the DialogGui timer fire on the 802D sl?
The timer is invoked on each HMI tick, which is approximately 100 ms on a healthy 802D sl panel. The exact cadence is also gated by the PLC sign-of-life; if the PLC is in STOP the timer will not advance until the PLC resumes RUN.
Why does my softkey toggle not change the PLC byte?
Almost always because the form is missing <data_access type="true" /> in the <init> block. Without that directive the HMI is read-only and silently rejects the write from the softkey's <op> element.
Can I drive several door or status indicators from one screen?
Yes. Reserve a separate door_byte / door_byte_old pair per indicator, repeat the mask + compare + <img> block inside the <timer>, and use distinct bitmap files and non-overlapping xpos / ypos coordinates. For more than roughly 8 indicators, switch to a status-word approach to keep the timer body short.
Where can I find the official list of supported DialogGui tags and attributes?
The 802D sl Function Manual and the operator panel front description in the control system overview are the primary references — see the 802D sl milling control system overview PDF for the hardware description, and the matching programming manual for the complete DialogGui XML schema.