SiCAM WinCC Time Sync: Fix PLC Timestamp in S7-400 Alarms

David Krause14 min read
SCADA ConfigurationSiemensTroubleshooting
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 Overview

When integrating a SICAM I/O subsystem with WinCC Alarm Logging on an S7-400 station, the most common failure mode is that incoming alarms carry the HMI computer's local time stamp rather than the 1 ms-accurate time stamp captured by the SICAM DI module at the moment the process bit changed state. The visible symptom is that the alarm log line shows "14:23:07.482" (PC wall-clock granularity) instead of "14:23:07.126" (SICAM module granularity), and the PLC-side millisecond counter never appears in the message text.

This drift is unacceptable for substation automation, fault recording, sequence-of-events (SOE) reporting, and IEC 61850-compliant event lists, where regulatory resolution requires ≤1 ms between adjacent input transitions. The issue is not a bug in WinCC; it is the expected behaviour of the standard Alarm Logging service when the trigger tag is a Boolean mapped to a discrete digital input.

Root-cause summary: WinCC timestamps a message when the runtime tag's quality transition is detected on the server-side polling cycle. The SICAM 6MD1 module already contains its own 1 ms time stamp inside the input buffer, but the buffer is not exposed as a standard tag, so the time stamp is lost the moment you wire a plain I 0.0 external tag.

2. Hardware Components and Topology

The reference configuration that exhibits the issue is built from the following Siemens catalog numbers. All items must be present at the time of commissioning:

Catalog number Function Slot / role Key spec
6ES7 414-3EM06-0AB0 S7-400 CPU 414-3 PN/DP Central rack, slot 3 4 MB work memory, 0.05 ms bit-instruction time, OB40-capable
6MD1 010-0BA00 0AA0 SICAM Time-Sync / I/O master module SICAM sub-rack, slot 1 IRIG-B / DCF77 / NTP / 1PPS time source; supplies SICAM sub-rack
6MD1 021-0AA00 SICAM DI input module (32 DI, 1 ms time stamp) SICAM sub-rack, slot 2+ 1 ms event resolution, 1024-event FIFO buffer per module
6GK7 443-1EX30-0XE0 CP 443-1 Ethernet communications processor Central rack, slot 4 ISO-on-TCP / TCP / UDP / S7 communication; supports B_SEND / B_RCV
WinCC V7.x or TIA WinCC RT Professional V16+ SCADA runtime + Alarm Logging HMI server MSRT C-API available, configured via WinCC Alarm Logging editor

The SICAM sub-rack is connected to the S7-400 through the SICAM I/O bus. The CPU 414 reads the SICAM input buffer image inside OB40 (hardware interrupt), because the SICAM module asserts an interrupt line whenever a new event is captured. Skipping OB40 and reading only at OB1 cycle time will collapse all 1 ms resolution down to the OB1 cycle (typically 10–100 ms).

3. Root Cause: Why WinCC Uses PC Time

WinCC Alarm Logging works in one of two modes:

  1. Bit-message mode: Alarm Logging polls an external tag (e.g. I 0.0 of the SICAM DI module exposed through the S7 protocol). The stamp applied to the message is the polling time of the Alarm Logging thread on the HMI server, not the time at which the bit physically changed.
  2. PLC-acknowledged message mode: The WinCC "Alarm_S" / "Alarm_D" / "Alarm_SQ" / "Alarm_DQ" message FB calls are written into the PLC program. The PLC passes a time stamp to WinCC, which is then displayed as the event time.

In configuration #1 the timestamp is taken from the WinCC server's local clock. The PC's NTP-synced time may be accurate to ~10 ms in a controlled environment, but never to the 1 ms granularity that the SICAM DI module provides. In configuration #2 the CPU itself becomes the time source, which is what you need for SICAM.

Two further complications apply when using SICAM:

  • The SICAM DI module's 1 ms time stamp is stored inside the module-local event buffer, not directly in the process-image input word. Reading I 0.0 only tells you that the bit changed since the last OB1 scan, not when it changed.
  • WinCC Alarm Logging's internal buffer cannot be back-dated after the fact. If the message has already been created with PC time, no amount of "time synchronization" in WinCC will correct it. You must prevent the message from being created at all until the PLC-supplied time stamp has been retrieved from the SICAM buffer.

4. Available Solution Paths

Path What you build Skill required Achievable precision
A — Native SICAM library Siemens-supplied FB library (NRMS7PMC format) consumed by WinCC as a raw-data tag Wiring + parameter assignment only 1 ms (module time stamp preserved)
B — Custom buffer + WinCC API OB40 reads SICAM buffer → CPU DB → CP 443-1 B_SEND → WinCC Raw Tag → C-script parses NRMS7PMC → MSRTCreateMsg S7 STL/SCL + WinCC C / VB scripting 1 ms (module time stamp preserved)

Path A is the recommended deployment. Path B is documented in detail below because the original Siemens library was not generally available before ~2002, and many installed substations still run on a self-maintained version of Path B.

5. Path A — Native SICAM Library Configuration

5.1 Prerequisites

  • SICAM Toolbox or SICAM SES product DVD containing the NRMS7PMC message-format library for the S7-400.
  • SIMATIC Manager Step 7 V5.5+ project with the CPU 414 and CP 443-1 configured.
  • WinCC V7.x project with CP 443-1 set as the S7 channel driver.
  • SICAM sub-rack configured via SICAM SES (or SICAM Toolbox) so that each DI module exposes an event-channel on the I/O bus and reports its module address to the CPU.

5.2 Step-by-step

  1. Insert the SICAM library FBs into the S7 project. The library normally supplies:
    – SICAM_INIT (called in OB100)
    – SICAM_POLL (called in OB1, low-priority polling of the SICAM sub-rack)
    – SICAM_EVT (called in OB40, reads the event buffer of the interrupting module)
    – SICAM_PACK (packs the event into NRMS7PMC format)
    – SICAM_SEND (transmits the packed buffer via CP 443-1 using AG_SEND / B_SEND equivalent)
  2. Create a global DB that holds the SICAM channel parameters and the message buffer (typical size: 256 bytes per event, 64 events deep).
  3. Configure the CP 443-1 ISO-on-TCP connection to the WinCC server. Use connection type "TCP native" or "ISO-on-TCP". Record the local TSAP (e.g. 10.01) and the partner TSAP (e.g. 10.02).
  4. In WinCC, create a Raw Tag of type "Raw data tag", 256 bytes, on the same connection. Wire SICAM_SEND in the CPU to write the NRMS7PMC-formatted frame into that tag.
  5. Configure the WinCC global script that parses the Raw Tag every 200 ms and creates individual alarm-logging entries through the C-API MSRTCreateMsg(), passing the 1 ms time stamp extracted from the NRMS7PMC frame.
  6. Compile and download to the CPU. Compile the OS and start runtime.

5.3 Verification

Force a transition on the SICAM DI module's first input channel using a calibrated pulse generator at 1 Hz. The alarm log should show timestamps with millisecond field varying by exactly 1000 ms between consecutive entries, and the timestamp should not change when the WinCC server clock is artificially set 30 seconds ahead. If the timestamp still drifts with the PC clock, Path A was wired incorrectly and Path B should be evaluated.

6. Path B — Custom Implementation (OB40 + B_SEND + MSRT API)

6.1 OB40 handler for the SICAM DI module

When a SICAM DI module captures a state change it triggers the hardware interrupt line of the S7-400. The CPU enters OB40. Inside OB40 you must:

  1. Read the OB40 starting information (OB40_MDL_ADDR) to identify which SICAM module raised the interrupt.
  2. Issue the SICAM-API read-buffer call for that module to copy the event(s) from the module-local FIFO into a CPU-side DB.
  3. Append the SICAM time stamp (1 ms resolution, IRIG-B- or DCF77-derived) to the DB entry.
  4. Mark the entry as "ready to send" by setting a handshake bit in the same DB.

Skeleton in SCL:

FUNCTION_BLOCK FB_SICAM_EVT
VAR
    evtDB : INT := 100;     // DB number for SICAM event buffer
    head  : INT;            // ring-buffer head index
END_VAR
BEGIN
    // 1. identify the interrupting module
    IF OB40_MDL_ADDR = W#16#0100 THEN          // 6MD1 021-0AA00, slot 2
        // 2. read 16-byte event from module FIFO into evtDB
        SICAM_READ(EADDR := W#16#0100,        // module I/O start address
                   DB    := evtDB,
                   OFFSET := head * 16);
        // 3. stamp it with the CPU time master clock for redundancy
        evtDB.timestamp[head] := SFC1(TOD := 0);   // SFC1 = READ_CLK
        // 4. handshake
        head := (head + 1) MOD 64;
    END_IF;
END_FUNCTION_BLOCK

6.2 Secondary CPU buffer and B_SEND dispatch

The OB40 routine must be short (≤500 µs typical). Bulk transmission is deferred to OB1, which calls FB_SICAM_SEND based on the IEC 61131-3 standard B_SEND block (FC5 / SFB 8 depending on CPU generation). Configure B_SEND as follows:

B_SEND input Value Comment
REQ evtDB.send_request Rising edge from OB40 handshake
ID Connection ID of CP 443-1 From NetPro configuration (e.g. W#16#0001)
R_ID DW#16#DEAD_BEEF Any 32-bit, must match WinCC side
DONE / ERROR / STATUS internal Evaluate STATUS = W#16#0000 for success
SD_1 Pointer to evtDB P#DB100.DBX0.0 BYTE 256
LEN Number of bytes ready WORD_TO_INT(head) * 16

6.3 WinCC side: Raw Tag and C-script

On the WinCC side create a Raw-data tag of the same length as the SICAM event DB. Wire it to the CP 443-1 connection used by B_SEND. Add a global C-action triggered every 200 ms that:

  1. Reads the Raw Tag.
  2. Walks the 16-byte records and for each one extracts the 6-byte SICAM time stamp + 1-bit value + 1-bit quality.
  3. Calls MSRTCreateMsg() with the parsed time stamp as the message time stamp.

The MSRT-API C-functions are exported from WinCCRT.dll / WinCC_AlarmLoggingChn.dll depending on WinCC version. The canonical prototypes are:

BOOL  MSRTStartMsgService(LPCTSTR serviceName);
BOOL  MSRTCreateMsg(DWORD    dwMsgNr,
                     LPCTSTR  lpszMsgText,
                     DWORD    dwTimeStamp,    // seconds since 1970
                     DWORD    dwMillisec,      // 0..999
                     LPCTSTR  lpszUser,
                     DWORD    dwState,
                     LPCTSTR  lpszServerName);
BOOL  MSRTStopMsgService(LPCTSTR serviceName);

The dwTimeStamp/dwMillisec pair carries the SICAM time stamp into Alarm Logging, replacing the wall-clock read that the standard alarm pipeline would otherwise use.

7. WinCC Time-Synchronization Settings

Even with Path A or Path B in place, the WinCC server clock should be synchronized to the SICAM master clock so that operator-driven messages, value-change archives, and operator-action logs share the same time base as the SICAM events.

  1. In WinCC Explorer, right-click the computer → Properties → Time Synchronization.
  2. Select "Via WinCC system time" or "Via external time source (NTP / SICAM master)".
  3. For TIA Portal V16 / V17 / V18 / V21: open the RT Professional configuration → Runtime settings → Time synchronization. See the Siemens online help Activating time synchronization (RT Professional).
  4. If your time source is the SICAM 6MD1 010 master clock acting as an NTP server, point WinCC to it using the master-clock IP (default port 123). If it is acting as a DCF77 / IRIG-B source, the SICAM sub-rack distributes the time through the I/O bus; the CPU reads it via the SICAM API and the WinCC server is then slaved to the CPU clock using SET_CLKS on the CPU.
  5. Allow at least 5 minutes for steady-state. Activation takes effect "a few minutes after" runtime start, as noted in the Siemens RT Professional documentation linked above.
Setting WinCC time synchronization alone will not fix the original 1 ms issue described in this article. It only aligns the PC wall clock; the SICAM event time stamp remains inaccessible unless you also implement Path A or Path B.

8. OB40 Implementation Details

Parameter (in OB40 start info) Source Use
OB40_MDL_ADDR Bits 0..15 = slot address of interrupting module Identify which SICAM DI raised the event
OB40_POINT_ADDR Bit map of changed lines Identify the channel inside the module
OB40_DATE_TIME DATE_AND_TIME (8 bytes) CPU-side event time (already 1 ms resolution when CPU is slaved to SICAM master)
OB40_FLT_ID B#16#42 (OB40 entered) Sanity-check on driver behaviour

Two OB40 considerations specific to SICAM:

  • Event flooding: An 8 Hz chatter on one DI line generates 8 interrupts/second per channel. With 32 channels × multiple modules this can exceed OB40 capacity. Always read the entire module FIFO inside one OB40 invocation, not just the first event.
  • OB40 priority: SICAM FBs call SFCs that briefly disable interrupts. Set the OB40 priority class to 16–24 (higher than OB1 = 1) so it pre-empts the cyclic scan.

9. B_SEND / CP 443-1 Configuration Checklist

  1. In NetPro, add an ISO-on-TCP connection between CP 443-1 and the WinCC PC's CP 1613 / standard Ethernet adapter. Use port 5001 / TSAP 10.02 on the WinCC side.
  2. Set connection type to TCP native / ISO-on-TCP, not S7 communication — B_SEND requires raw transport.
  3. Set the keep-alive time to 30 s. B_SEND on the CP 443-1 firmware V3.x ships with default 10 s; reduce if you observe retransmits.
  4. Confirm B_SEND DONE returns TRUE within 50 ms for a 256-byte frame; if it lingers, the CP connection was not compiled into the CPU image (common mistake: connection configured in NetPro but not in the hardware configuration of the CP 443-1 itself).

10. Verification and Commissioning Procedure

  1. Force a single transition on SICAM DI channel 0 with a calibrated pulse generator (1 Hz, 50% duty, rising-edge only).
  2. In the WinCC Alarm Logging control, observe the message timestamp. It must show millisecond precision and must advance by exactly 1000 ms between consecutive messages.
  3. Disconnect the WinCC server from any NTP source for 5 minutes. The message timestamps must not drift. If they do, the time source is the PC clock — re-check OB40 wiring.
  4. With OB40 disabled, repeat step 1. The timestamp granularity should drop to the OB1 cycle (typically 10–50 ms), confirming that OB40 is doing the work.
  5. Force 8 DI channels simultaneously. All 8 messages must appear with monotonically increasing 1 ms time stamps (no duplicates, no losses).

11. Redundant WinCC Server Pair Considerations

When the WinCC project runs as a redundant server pair, the SICAM event buffer must be drained by exactly one server at a time; otherwise both servers will create duplicate Alarm Logging entries. Implement a "preferred server" handshake:

  • Use WinCC redundancy @RM_MASTER / @RM_STANDBY tags to gate the global C-script that consumes the Raw Tag.
  • Only the master server runs MSRTCreateMsg(); the standby server drains the Raw Tag silently to keep the SICAM-side handshake from stalling.
  • After a failover, the new master inherits the same ring-buffer position because the buffer index is stored in the CPU DB, not in the WinCC server.

12. Troubleshooting Matrix

Symptom Likely cause Remedy
All alarm timestamps = PC wall clock, no millisecond field Path A not deployed; alarm sourced from a polled I 0.0 tag Switch to Path A or Path B; never use a polled tag for SICAM events
1 ms field present but drifts with PC clock WinCC MSRT API call is overriding the SICAM time stamp with the local GetSystemTime Verify dwTimeStamp/dwMillisec are populated from the SICAM buffer before the API call
Some events missing under high load OB40 not reading the entire FIFO, only first entry Loop inside OB40 until the SICAM module returns "buffer empty"
B_SEND STATUS = 0x81A0 CP 443-1 connection not loaded Recompile the hardware configuration and download the CP, not just the CPU
B_SEND STATUS = 0x80C3 Partner (WinCC) not reachable Verify ISO-on-TCP TSAPs and that WinCC Runtime is running with the same connection ID
Duplicate messages on redundant pair Both servers consuming the Raw Tag Gate C-script with @RM_MASTER
Messages stop appearing after a few minutes Raw Tag overflow / Ring-buffer head overrun Increase DB size to ≥1024 entries; ensure OB1 cycle < 200 ms

13. Related Siemens Manuals and References

Why does WinCC timestamp my SICAM alarm with PC time instead of PLC time?

When you bind an alarm to a polled external tag such as I 0.0 from a SICAM DI module, Alarm Logging creates the message at the moment it polls the tag on the HMI server, and it stamps the message with the server's local time. The SICAM 1 ms time stamp is held inside the module-local FIFO buffer and is not exposed through that polled tag, so the high-resolution time is lost. The fix is to use the SICAM NRMS7PMC library (Path A) or an OB40 + B_SEND + MSRTCreateMsg() pipeline (Path B) so the time stamp reaches Alarm Logging through the WinCC MSRT API.

Do I need to enable time synchronization in WinCC as well?

Yes. Even with Path A or Path B in place, configure WinCC Runtime Professional time synchronization so the PC wall clock is slaved to the SICAM master clock. See the Siemens Activating time synchronization (RT Professional) documentation. Note that synchronization alone will not recover the 1 ms SICAM time stamp — it only aligns the wall clock.

Which OB should I use to read the SICAM DI module buffer?

Use OB40 (hardware interrupt). The SICAM 6MD1 021 module raises an interrupt on every state change; reading the FIFO only inside OB1 cycle will collapse the 1 ms resolution to the OB1 cycle (typically 10–100 ms). Inside OB40, read the entire module FIFO in a loop until the SICAM API returns "buffer empty", and set OB40 priority to 16–24 to pre-empt the cyclic scan.

What does B_SEND status 0x81A0 mean on CP 443-1?

Status W#16#81A0 indicates that the CP 443-1 connection resource was not loaded into the CP firmware. Recompile and re-download the CP hardware configuration, not just the CPU project; verify that the same connection ID is configured on the WinCC side.

Can the same SICAM event be reported twice on a redundant WinCC server pair?

Yes, if both servers consume the Raw Tag from the CPU buffer. Gate the WinCC C-script that calls MSRTCreateMsg() with the redundancy tag @RM_MASTER; let only the master server create Alarm Logging entries while the standby drains the tag silently to keep the buffer from stalling.

Back to blog