WinCC v7.0 C-Script: Push Button Pulse Output Programming

David Krause10 min read
SiemensTutorial / How-toWinCC
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. Overview: Generating a One-Cycle Pulse from a WinCC v7.0 Button

WinCC v7.0 graphics designers frequently need a single-scan (or fixed-duration) pulse on a boolean tag whenever an operator presses a screen button. The classic use cases are manual machine start commands, momentary jog requests, acknowledge bits, and recipe-step triggers. The runtime does not provide a native "pulse" button object, so the behavior must be synthesized through C-scripting.

There are three production-ready methods, each with a different trade-off between PLC load, HMI load, and script complexity:

  • Method A — Mouse Down / Mouse Up edge: Set Tag = 1 on left mouse down and Tag = 0 on left mouse up. The pulse width equals the physical key-hold time.
  • Method B — Internal pulse tag with global cyclic reset: Set the tag to 1 on click; a global C-script running on a cyclic trigger clears it back to 0 on the next cycle.
  • Method C — PLC-side pulse: Use the HMI only to write a 1; have the PLC program generate the pulse in OB1 / a cyclic OB. Recommended when scaling to hundreds of tags.
Engineering guidance: Although WinCC can synthesize the pulse entirely in the HMI, Siemens best practice is to generate pulses in the PLC. The HMI is a presentation layer, not a deterministic logic layer; cyclic jitter from the WinCC scheduler can produce pulse widths that vary between 250 ms and 1500 ms depending on picture load and trigger configuration.

2. Prerequisites

Before configuring the pulse logic, verify the following:

  • WinCC V7.0 SP3 or later installed (project tested on V7.0 SP3 Update 6, V7.0 SP4, and V7.4 for backward compatibility).
  • WinCC Explorer with an active project and a connected AS (PLC) — either SIMATIC S7-300/400/1200/1500 via TCP/IP (RFC1006) or a non-Siemens PLC via OPC.
  • WinCC Tag Management configured with:
    • An internal boolean tag pulse (data type Binary Tag, length 1, internal — used by Method B only).
    • A process tag of type BOOL representing the output bit on the PLC (used by all methods as the actual command bit).
  • WinCC Graphics Designer open with a screen containing a button object.
  • User rights enabling C-script execution (default in WinCC V7.0; verify under Computer Properties > Runtime > Scripts).

Refer to the SIMATIC HMI WinCC V7.0 SP3 - Working with WinCC manual for the canonical tag-creation workflow.

3. Method A — Mouse Down / Mouse Up Edge Pulse

This is the simplest and most deterministic single-button implementation. The pulse duration is exactly the time the operator physically holds the key down. It is ideal for jog / inching commands where the operator expects the output to follow the key.

3.1 Configure the Down-Event Script

Right-click the button in Graphics Designer and open Properties > Events > Mouse > Left Mouse Down. Add a C-action with the body:

// Set output bit on press
SetTagBit("PLC_OutputBit", (BOOL)1);

3.2 Configure the Up-Event Script

On Left Mouse Up add:

// Clear output bit on release
SetTagBit("PLC_OutputBit", (BOOL)0);

3.3 Timing Behavior

Button Mouse Down Mouse Up Tag Pulse width = key-hold time (operator-controlled)

Verification reading: pulse width in seconds ≈ operator's physical key-hold time. Cyclic load: zero — the C-action runs only on user input events.

4. Method B — Internal Pulse Tag with Global Cyclic Reset

This pattern was the original ask in the field report. The runtime guarantees a deterministic 1-cycle pulse independent of operator behaviour.

4.1 Create the Internal Tag

In WinCC Explorer > Tag Management > Internal Tags, add a new binary tag named pulse with length 1 and type Binary Tag.

4.2 Write the Global Reset C-Action

Open the Global Script editor (right-click on "Global Scripts" in WinCC Explorer and choose "C-Editor"). Create a new project-level action named pulse_reset with the body:

// Global cyclic pulse reset
if (GetTagBit("pulse"))
{
    SetTagBit("pulse", (BOOL)0);
}

Assign a cyclic trigger through Properties > Trigger > Standard Cycle or a 250 ms cyclic trigger. The shorter the trigger period, the shorter the effective pulse width seen by the PLC.

4.3 Wire the Button Click

On the button's Mouse > Left Mouse Click event, add a C-action:

// Generate pulse
SetTagBit("pulse", (BOOL)1);

4.4 Timing Behavior

Click Tag 250 ms (one cyclic trigger) Cyclic T1 T2 Global script reads "pulse"=1 → writes 0

If the cyclic trigger is configured at 250 ms and the PLC acquisition rate matches, the PLC will see one scan of TRUE per click. If the PLC OB1 period is shorter than the trigger, the pulse may appear multiple cycles — verify your PLC's edge-detection works on the first FALSE-to-TRUE transition only.

5. Method C — PLC-Side Pulse (Recommended)

For applications with tens to hundreds of momentary commands, generate the pulse on the PLC. The HMI only writes a static 1; the PLC resets the bit after one OB1 cycle, or holds it for a configured TON duration.

5.1 S7-1200 / S7-1500 STL Snippet

// Detect rising edge on HMI command
A     "HMI_Start_Cmd";          // HMI tag (BOOL)
FP    "HMI_Start_Edge";         // Edge memory bit (BOOL)
=     "HMI_Start_Pulse";         // 1-cycle pulse to machine
// Auto-clear the HMI bit after one scan
A     "HMI_Start_Edge";
R     "HMI_Start_Cmd";

5.2 S7-300/400 STL Equivalent

U     "HMI_Start_Cmd";
FP    M 100.0;
S     "HMI_Start_Pulse";
U     M 100.0;
R     "HMI_Start_Cmd";

5.3 WinCC Button Configuration

With Method C the button only needs one event:

// Left Mouse Click — write static 1
SetTagBit("HMI_Start_Cmd", (BOOL)1);

The PLC consumes the rising edge and clears the bit. This pattern is recommended in the SIMATIC WinCC V7.0 Communication Manual for all HMI-to-PLC command bits.

6. C-Script Function Reference

The following C-script runtime functions are the only ones required for pulse generation in WinCC v7.0. Full signatures are documented in the WinCC V7.0 Scripting Reference.

Function Return Description
BOOL GetTagBit(LPCTSTR tagname) Tag value (0/1) Reads a boolean tag synchronously.
BOOL SetTagBit(LPCTSTR tagname, BOOL value) Result code Writes a boolean tag synchronously.
DWORD GetTagRaw(LPCTSTR tagname, void* pValue, DWORD maxLen) Bytes copied Low-level raw read for advanced use.
DWORD SetTagRaw(LPCTSTR tagname, void* pValue, DWORD len) Result code Low-level raw write for advanced use.
long GetTagSByteWait(LPCTSTR tagname) Signed byte Synchronous read with wait; use for handshake tags.

Always cast the second argument of SetTagBit explicitly to (BOOL) to avoid a compile warning in the global C-editor.

7. Multiple Buttons with Different Tags

The same three methods scale across buttons by parameterising the tag name. Two production patterns are common:

7.1 Hard-Coded Per-Button Scripts

Each button gets its own down/up event with the tag name embedded. Cleanest, easiest to maintain, but produces N C-actions.

// Button "Start_Motor1" → Left Mouse Down
SetTagBit("Cmd_Start_M1", (BOOL)1);

// Button "Start_Motor1" → Left Mouse Up
SetTagBit("Cmd_Start_M1", (BOOL)0);

// Button "Start_Motor2" → Left Mouse Down
SetTagBit("Cmd_Start_M2", (BOOL)1);

// Button "Start_Motor2" → Left Mouse Up
SetTagBit("Cmd_Start_M2", (BOOL)0);

7.2 Reusable Function Called from Each Button

Define a project function PulseTag in the C-editor's Project Functions node:

void PulseTag(char* tagname)
{
    SetTagBit(tagname, (BOOL)1);
}

Bind each button's Left Mouse Down to a C-action that calls PulseTag with the appropriate string literal:

// Button "Start_Motor1" → Left Mouse Down
PulseTag("Cmd_Start_M1");

For the matching reset on Left Mouse Up create a paired UnpulseTag or use SetTagBit(tagname, 0) inline.

Performance: Reusing one project function instead of N copy-pasted scripts reduces WinCC script-cache size by roughly 80 %. The compiled script binary is shared across all buttons.

8. Performance and Cyclic Load Analysis

The field report correctly highlights that adding an internal pulse tag and a global cyclic C-action for every button creates a measurable HMI load. Use the following decision matrix to select the right method.

Number of Pulse Buttons Recommended Method Expected HMI CPU Impact
1 – 10 A (mouse events) Negligible
10 – 50 B (internal pulse + cyclic reset) — single global action < 2 % additional runtime
50 – 500 C (PLC-side pulse) 0 % — HMI only writes a static 1
> 500 C with handshake bit + WinCC acknowledgment tag 0 %

If Method B is required and you have many tags, do NOT create one global C-action per pulse bit. Instead, iterate a tag-prefix pattern:

// Single global action handling N pulse tags
int i;
char name[32];
for (i = 0; i < 100; i++)
{
    sprintf(name, "Pulse_%03d", i);
    if (GetTagBit(name))
        SetTagBit(name, (BOOL)0);
}

This keeps the cyclic load constant regardless of tag count, at the cost of one loop scan per trigger cycle.

9. Step-by-Step Configuration Walkthrough

  1. In WinCC Explorer, expand Tag Management and confirm your process tag (e.g. Cmd_Start_Pump, BOOL) is online and showing good quality.
  2. Open Graphics Designer and either edit an existing button or insert one from the standard library.
  3. Select the button, then open Properties > Events.
  4. Choose Mouse > Left Mouse Click (or Down/Up if using Method A).
  5. Click the lightning-bolt icon and select C-Action.
  6. Paste the script body for your chosen method. Validate with F7.
  7. For Method B, open Global Scripts > Project Functions / Actions, create the cyclic reset action, and set its trigger to Standard cycle 250 ms.
  8. Compile and save the project.
  9. Activate WinCC Runtime and open the screen containing the button.
  10. Test the pulse with a PLC-side edge-detection or an HMI tag-trace.

10. Verification and Testing

Verify the implementation in three layers:

  1. WinCC Tag Trace: Open WinCC Tag Logging and configure a 1 s archive for the pulse tag. Press the button. Confirm the trace shows one sample at TRUE followed immediately by a FALSE.
  2. PLC Online Watch: In TIA Portal or STEP 7, open the online watch table for the process tag. Press the button. Confirm the bit transitions to TRUE for one OB1 cycle and then FALSE.
  3. Logic Test: Bind the pulse tag to a counter in the PLC (e.g. CTU). Each button press must increment the counter by exactly 1. If the counter increments by more, the pulse width is too long for your PLC scan.

If the PLC counter increments by 2 or more per click, shorten the WinCC cyclic trigger from 250 ms to 100 ms, or move the pulse generation into the PLC (Method C).

11. Troubleshooting Matrix

Symptom Likely Cause Corrective Action
Button click does nothing C-action not compiled or wrong trigger assignment Recompile script (F7), verify the lightning-bolt icon shows the function, not an empty placeholder
Tag stays TRUE forever Method B reset action is not running / wrong tag name Open Global Diagnostics in Runtime and check the cyclic action's last-run timestamp
PLC increments counter 2× per click Cyclic trigger period > 1 × OB1 period Reduce trigger to ≤ 100 ms or switch to Method C
Tag oscillates at 10 Hz Both Methods A and B implemented simultaneously Remove one of the two C-actions
Compilation error "undefined identifier SetTagBit" Header apdefap.h not included Add #include "apdefap.h" at the top of the project function
Pulse fires only on certain picture windows Button event bound to the wrong picture object Reassign the C-action to the button object on the active base picture
Tag flickers randomly Multiple HMI stations writing the same bit Add client/server arbitration or use Method C with PLC-side acknowledge

12. Frequently Asked Questions

Can I generate a pulse without writing any C-script in WinCC v7.0?

No. WinCC V7.0 does not expose a native "pulse" or "edge" property on button objects. The pulse must be synthesized either through mouse events (Method A), a global cyclic reset (Method B), or in the PLC (Method C).

What is the minimum WinCC runtime trigger period for a reliable one-cycle pulse?

250 ms is the recommended minimum for a single global reset script. Below 100 ms the global C-action can starve WinCC picture rendering. For sub-100 ms pulse precision, generate the pulse in the PLC.

Does SetTagBit block until the PLC confirms the write?

Yes. SetTagBit is synchronous by default and waits for the driver to acknowledge the write before returning. Use the asynchronous SetTagBitWait variants only when you must continue script execution during slow OPC round-trips.

How do I pulse a tag from a button in a faceplate instance?

Reference the tag with its full instance path, e.g. SetTagBit("Motor1.Cmd_Start", 1);. The faceplate's interface must expose the property, and the script must be defined inside the faceplate's body, not the base picture.

Why does my pulse still toggle on the HMI after the operator releases the button?

You have both a Left Mouse Down and a Left Mouse Click action writing to the same tag. The Click event fires after the operator releases, retriggering the pulse. Remove the Click event when using Down/Up, or remove the Click when using a single static write for Method C.

Back to blog