WinCC 7.4: Automatically Cycle 8 Pictures with Start/Stop Buttons

David Krause14 min read
HMI / SCADASiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

1. Problem Definition

A WinCC V7.4 Runtime is required to step through eight process pictures automatically while the operator holds a Start button. Releasing Stop must freeze the rotation on the currently displayed picture, and the next Start must resume from the following index (not jump back to picture 1). The application is a single-process HMI on a WinCC RT 1024 / 2048 / 4096 / 8192 station (WinCC V7.4 SP1 or later) and the cycle period is configurable, typically 5 s, 10 s, or 30 s.

WinCC V7.4 does not expose a native timer primitive comparable to the OnTime / OffTime attributes used in WinCC Unified or WinCC flexible. Cycle behaviour in V7.4 is therefore implemented with one of three patterns:

  1. Global script C action triggered cyclically by the WinCC scheduler.
  2. Global script C action triggered by a tag change in the PLC.
  3. Picture swap driven from the PLC by writing a picture index word; WinCC is a passive observer.
Why a Screen Window? Embedding a Screen Window in the main picture and changing its PictureName property is the recommended V7.4 pattern. The alternative PdlRtApi.ActivateScreen() opens a new full-screen picture, which destroys the operator's button bar, alarm line, and status bar on every change. The Screen Window approach keeps the buttons, alarms, and status bar persistent across all eight swaps.

2. Architecture Overview

Main.Pdl Screen Window PictureName = Picture_3 Start Stop Set Tag HMI_CycleRun = 1 WinCC Scheduler Cyclic Trigger e.g. 10 000 ms C Action gscAction() Read HMI_CycleRun Increment HMI_Index SetPictureName() 0..7 modulo 8 8 Process Pictures Picture_1.Pdl Picture_2.Pdl Picture_3.Pdl Picture_4.Pdl Picture_5.Pdl Picture_6.Pdl Picture_7..8.Pdl

3. Prerequisites

  • WinCC V7.4 (SP1 recommended), WinCC Explorer open with the active project.
  • Global Script Runtime license active on the HMI station (bundled with every WinCC RT package from RT 1024 upward; no separate license key required for C actions on a licensed RT).
  • Tag Logging is not required for this pattern. User Archive is not required.
  • Either the standalone HMI or the integrated WinCC/TIA configuration must be in Runtime to test the cycle; design-time Play-To-Test of the screen window is supported but the cyclic trigger only fires in real Runtime.
  • Operator authorization level 0 (no password) is sufficient; the Start/Stop logic itself does not require user administration.
Tag scope decision. Use WinCC internal tags for HMI_CycleRun and HMI_PictureIndex so the rotation works even if no PLC is connected or the PLC is in stop. If you want the Start/Stop to be authority- or process-controlled by the PLC, mirror them into the PLC and use external tags instead. The C action is identical.

4. Step 1 — Create the Eight Process Pictures

  1. In Graphics Designer, create eight new pictures: Picture_1.Pdl through Picture_8.Pdl. Keep names simple; they are referenced from the C action by string.
  2. If your eight screens have logical names (e.g. Overview, Drives, Alarms, Trends...) and not a running number, store the names in a switch instead of building the name from an index. This is a robustness measure: a picture rename in the project tree will not break the script.
  3. Set each picture's Geometry identical to the Screen Window on the main picture. Per the official Siemens KB on preventing automatic fitting on resolution change, you may want to disable Screen editor > Screen options > Settings > Fit screen and screen objects to new HMI in the Graphics Designer options to keep coordinates deterministic across the eight pictures.

5. Step 2 — Define the Internal Tags

Open WinCC Explorer > Tag Management > Internal Tags and add the following tags. The data type Word (unsigned 16) gives you up to 65 535 indices; a Signed 16 is also fine and what the script example below uses.

Tag Name Data Type Initial Value Scope Purpose
HMI_CycleRun Binary Tag 0 Internal Set by Start/Stop buttons; gates the C action.
HMI_PictureIndex Signed 16-bit 0 Internal Current picture 0..7. Persists across RT restart if configured retentive.
HMI_CyclePeriod_ms Unsigned 32-bit 10 000 Internal Optional: drives the period from the HMI instead of the scheduler.

For best behaviour across RT cold start, mark HMI_PictureIndex and HMI_CycleRun as Retentive in the tag properties. Without retention, every RT cold start begins at Picture_1 with Stop asserted.

6. Step 3 — Add the Screen Window to the Main Picture

  1. Open the start picture (e.g. Main.Pdl).
  2. From the Standard palette, drop a Screen Window object. Name it ScreenWindow1 in the object properties — this name is referenced from the script and from any colour/visibility dynamic.
  3. Set Picture Name (Static) to Picture_1.Pdl as a sensible fallback if the script has not yet fired.
  4. Set Sizing to Fit to picture if you want the embedded picture to scale; set to Original size if all eight pictures share an exact resolution. Mixed sizes with the same object work but produce a brief resize repaint on every swap.
  5. Drop a Button named btnStart and one named btnStop below or beside the screen window.

7. Step 4 — Author the C Action

Open WinCC Explorer > Global Scripts > C-Editor > Actions. Create a new action named acCyclePictures with the following body. This pattern uses an internal counter and a switch (Select Case equivalent) on the index, which is more maintainable than building the picture name from a sprintf string when the picture set grows or is renamed.

// acCyclePictures  --  WinCC V7.4 cyclic C action
// Trigger:  Cyclic, 10 000 ms (configurable)
// Reads:    HMI_CycleRun, HMI_PictureIndex
// Writes:   HMI_PictureIndex, Main.Pdl::ScreenWindow1.PictureName
#include "apdefap.h"

int gscAction( void )
{
    // 1. Gate: only advance while operator holds Start
    if ( GetTagBit("HMI_CycleRun") == 0 )
        return 0;

    // 2. Read & increment the index
    int nIdx = GetTagWord("HMI_PictureIndex");
    nIdx = (nIdx + 1) % 8;        // wrap 0..7
    SetTagWord("HMI_PictureIndex", (WORD)nIdx);

    // 3. Build the target picture name (or use switch for named pictures)
    char szPic[64];
    sprintf( szPic, "Picture_%d.Pdl", nIdx + 1 );

    // 4. Apply to the screen window on the start picture
    SetPictureName( "Main.Pdl", "ScreenWindow1", szPic );
    return 0;
}

The official WinCC V7.4 "Working with WinCC" manual documents SetPictureName and the action trigger concepts in chapter 3 "Process Picture Dynamics".

For named pictures (no running number) replace step 3 with a switch:

    const char* aszNames[8] = {
        "Overview.Pdl", "Drives.Pdl", "Alarms.Pdl", "Trends.Pdl",
        "Diagnostics.Pdl", "Recipe.Pdl", "Energy.Pdl", "Users.Pdl"
    };
    if ( nIdx < 0 || nIdx > 7 ) nIdx = 0;   // defensive
    SetPictureName( "Main.Pdl", "ScreenWindow1", (char*)aszNames[nIdx] );

8. Step 5 — Configure the Cyclic Trigger

  1. Right-click acCyclePictures in the C-Editor → Properties / Trigger → add trigger Cyclic and set the interval to e.g. 10s (10 000 ms). Valid range: 100 ms … 10 h.
  2. Compile (F7) and ensure no errors. If compilation fails with undefined symbol SetPictureName, the action needs to be placed under Actions rather than under a function header — only the action container has the WinCC picture API linked.
  3. Save the project. The C action is now part of the project; the next RT start will register it with the scheduler.
Avoid double triggers. Do not add both a Cyclic and a Tag trigger on the same action; the action will fire twice per cycle and skip pictures. Use Cyclic alone (the recommended pattern) or use a PLC tag change trigger alone (see Variant B).

9. Step 6 — Wire the Start and Stop Buttons

On Main.Pdl, configure the two buttons with the following mouse-click C actions.

Start button (btnStart):

#include "apdefap.h"
void OnClick( char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName )
{
    SetTagBit( "HMI_CycleRun", 1 );
}

Stop button (btnStop):

#include "apdefap.h"
void OnClick( char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName )
{
    SetTagBit( "HMI_CycleRun", 0 );
}

Optionally, reset the index on Stop so the next Start begins at Picture_1.Pdl:

    SetTagBit( "HMI_CycleRun", 0 );
    SetTagWord( "HMI_PictureIndex", 0 );
    SetPictureName( "Main.Pdl", "ScreenWindow1", "Picture_1.Pdl" );

10. Variant A — Trigger from a PLC Tag Change

For deterministic, scan-aligned cycling, let the PLC drive the trigger. The PLC owns a timer (e.g. SIMATIC S7-1500 TP / TON in OB1). The PLC toggles a Heartbeat bit on timer expiry, and a WinCC C action is set to fire on the rising edge of that bit.

  1. PLC: L "CycleTime_ms"; SD "Heartbeat_TON"; or use the TP IEC timer block.
  2. WinCC: add an external tag PLC_Heartbeat (Bool), pointer to the PLC bit.
  3. In acCyclePictures > Triggers, remove the Cyclic trigger; add a Tag trigger for PLC_Heartbeat, event On change, direction Rising edge.
  4. The C action body is unchanged from Step 4.

Advantage: the cycle period is also paused when the PLC goes to STOP (comm loss) and resumes from a defined state. Disadvantage: WinCC scheduling latency adds 100–500 ms jitter.

11. Variant B — Picture Index Fully Owned by the PLC

For the most decoupled architecture, expose PLC_PictureIndex (Int) to WinCC as a struct tag (S7-1500 DB word), and let WinCC read-only mirror it into the screen window:

int gscAction( void )
{
    int nIdx = GetTagWord("PLC_PictureIndex");
    if ( nIdx < 0 || nIdx > 7 ) nIdx = 0;

    char szPic[64];
    sprintf( szPic, "Picture_%d.Pdl", nIdx + 1 );
    SetPictureName( "Main.Pdl", "ScreenWindow1", szPic );
    return 0;
}

Trigger this action with a Tag trigger on PLC_PictureIndex (On change). The PLC does the wrap-around in the OB1 cyclic interrupt. This is the cleanest pattern when the picture selection is part of process control (e.g. lead/lag overview, multi-area summary).

12. State Machine (Truth Table)

State at trigger tick HMI_CycleRun HMI_PictureIndex (before) HMI_PictureIndex (after) ScreenWindow1.PictureName
Idle, RT just started 0 0 0 Picture_1.Pdl (static default)
Start pressed, tick 1 1 0 1 Picture_2.Pdl
Tick 2 1 1 2 Picture_3.Pdl
… 1 … … …
Tick 7 1 6 7 Picture_8.Pdl
Tick 8 (wrap) 1 7 0 Picture_1.Pdl
Stop pressed, freeze 0 3 3 Picture_4.Pdl (held)
Start pressed again 1 3 4 Picture_5.Pdl (resume from 4)

13. Performance and Resource Notes

  • CPU cost. A 10 s cyclic action doing one modulo and one SetPictureName is negligible (sub-millisecond). C actions in V7.4 run inside the RT scheduler's standard 250 ms tick, so a 100 ms cyclic trigger will be quantised to ~250 ms granularity on busy systems. Use 500 ms or larger for deterministic behaviour.
  • Memory cost. SetPictureName unloads the previous picture's instance from the screen window and instantiates the new one. If each Picture_n.Pdl is < 5 MB graphics, the working set settles quickly. Anything > 20 MB per picture should be reviewed for redundant embedded process pictures or large background bitmaps.
  • Pre-compile. V7.4 RT supports a pre-compile of all scripts. Right-click the project → Generate Runtime Files. The pre-compile embeds the action as p-code so the first RT cycle is faster and the script is not source-recompiled on every RT cold start.
  • Resolution change. If the operator changes the HMI screen resolution at runtime (multi-monitor stations), the screen window's coordinate frame may not match. Set the Screen Window object property Adapt Picture to Fit picture to window and use the V7.4 Graphics Designer setting documented in Siemens KB 42713776 to keep the eight embedded pictures at the same coordinates.
  • Alarm line overlap. If the operator bar at the bottom of the main picture is covered by the embedded screen window, the screen window's bottom edge is moving on top of the alarm line; constrain the screen window height to leave 32–40 px above the alarm line.

14. Verification Checklist

  1. Compile the C action (F7). The output window should show acCyclePictures: 0 error(s), 0 warning(s).
  2. Start WinCC Runtime. Confirm Main.Pdl is loaded and ScreenWindow1 shows Picture_1.Pdl.
  3. Click btnStart. Use a stopwatch: the screen window must show Picture_2.Pdl at the next trigger tick. The period must equal the configured cyclic interval, plus or minus the scheduler jitter (typically < 1 s).
  4. Verify wrap: with cycle period set to 5 s, the 9th picture after Start must be Picture_1.Pdl again (8 ticks × 5 s = 40 s, then 5 s more brings you to Picture_1 after 8 visible changes).
  5. Click btnStop. The current picture must remain visible and the index must stop advancing. Re-arm btnStart and verify the next picture is the one after the last shown (no reset to 1 unless explicitly configured).
  6. Power-cycle the RT station. With the tags marked retentive, the index must persist; without retention, it must start at 0.
  7. Force a script error: rename Picture_5.Pdl to PictureFive.Pdl and confirm the GSC Runtime log records SetPictureName: picture not found and the screen window shows the default background. This is your smoke test for picture-rename robustness.
  8. Open WinCC Explorer > Tools > Channel Diagnosis to confirm no tag errors are reported on the internal tags.

15. Troubleshooting Matrix

Symptom Likely Cause Fix
Picture never changes, no script error Cyclic trigger not configured on the action Right-click the action → Properties → Triggers → add Cyclic
Pictures change but very fast / every 250 ms Both Cyclic and Tag trigger on the same action Keep only one trigger
Screen window stays on initial picture, no error Wrong picture name in the script, or screen window object name mistyped Compare SetPictureName("Main.Pdl", "ScreenWindow1", ...) with the actual screen window name on Main.Pdl
"Function … undefined" on compile Action body placed in a function, not in an action Move code under Global Scripts > Actions, not Functions
Start does nothing, but Stop sets the tag SetTagBit with swapped polarity on a hold-style button Check the button's Press / Release event mapping
Cyclic action runs but pictures appear in wrong order Index not modulo-wrapped Use nIdx = (nIdx + 1) % 8;
RT cold start shows the wrong picture (not Picture_1) Tags not retentive and Stop was not pressed Set Retentive on HMI_PictureIndex and HMI_CycleRun
Screen window resize flicker on every change Picture sizes differ; Sizing = Fit to picture Set all 8 pictures to identical geometry or set Sizing = Original size
Alarm line obscured by the screen window Screen window height too large Reduce window height by 32–40 px to clear the alarm line
Script logs No picture with the name … Picture file path or extension mismatch Verify the picture exists in Graphics Designer tree and extension is .Pdl
Cycle continues after Stop Stop button writes to a different tag than the C action reads Both must reference HMI_CycleRun

16. Field-Proven Caveats

  • Mixing ActivateScreen and the Screen Window approach in the same project creates a hidden trap: any dynamic configured on the original picture may not fire when the screen window swaps internally, because the parent picture (the one configured in Graphics Designer) is still considered the active one by WinCC diagnostics. Pick one model and stick to it per project.
  • When the eight pictures contain their own buttons that drive tag writes, do not assume the C action is in the same scope as those button events. The action is a Global Script Action; it runs against the WinCC data manager. Button events run against the picture in which the button is configured. Internal tags written from either side are visible to both.
  • If the HMI station runs a redundant WinCC Server pair, both servers will fire their own cyclic action. Use a process tag from the PLC (the "Master" / "Standby" status) to gate HMI_CycleRun on the standby server to a constant 0, or use a tag trigger fired only by the master PLC connection.
  • The C action is recompiled on every graphics designer save of the project if the project setting Recompile actions on save is enabled. Disable it on large multi-engineer projects to avoid the "works on my machine" symptom where one engineer sees picture swaps and the other does not.

17. FAQ

Does WinCC V7.4 have a built-in timer for picture changes like WinCC Unified?

No. WinCC V7.4 does not expose the OnTime / OffTime picture-object attributes that WinCC Unified and WinCC flexible offer. Use a Global Script C action with a Cyclic trigger (typical interval 5–30 s) or a Tag trigger driven by a PLC timer. Both patterns are documented in the official WinCC V7.4 "Working with WinCC" manual.

How do I keep the Start/Stop buttons visible while the eight pictures rotate?

Embed a Screen Window in the main picture and place the Start/Stop buttons outside the window on the same main picture. The screen window swaps its PictureName property while the parent picture (with the buttons) remains loaded. Using ActivateScreen would destroy the operator bar on every change.

Can the cycle period be changed at runtime from the HMI?

Yes. Reconfigure the C action's Cyclic trigger to a non-standard interval and recompile, or switch to Variant A (PLC-driven heartbeat) and expose the period as an HMI tag written from an input field. The PLC-based pattern is the only one that supports a period change without recompiling the C action.

Why does the screen window show the previous picture name for a split-second after Start?

The Cyclic trigger fires only at the next scheduler tick, not on the rising edge of the Start button. If you need the first picture to change immediately on Start, also call SetPictureName from the Start button's OnClick event with the incremented index, and let the cyclic action take over from there.

How do I make the picture index survive a power-cycle of the RT station?

Open the internal tag HMI_PictureIndex in WinCC Explorer and set the property Retentive to Yes. Also set HMI_CycleRun to Retentive so the cycle does not auto-restart on cold boot. The values are then held in the WinCC internal database file across RT cold starts.

Back to blog