Overview: WinCC Runtime Serial Port Integration
WinCC Runtime Professional and WinCC V7.x do not expose a native serial I/O driver for ASCII/RS232 devices on the engineering station or the OS client. To read data from a barcode scanner, scale, GPS, or any RS232 endpoint without a CP340/CP341 hardware module, the standard field-proven path is to embed the Microsoft MSComm32.ocx ActiveX control inside a WinCC picture, drive it with VBScript (preferred) or a C action, and route the received bytes into a WinCC internal tag. The ActiveX speaks directly to the Win32 COMM API (\Device\Serial0..n), bypassing the need for a SIMATIC S7 CP module or an OPC server wrapper.
This guide focuses on the documented pattern Siemens publishes in the WinCC Knowledge Base: Entry ID 28378296 - How can you send or receive data via the serial interface in WinCC Runtime?. The pattern works on WinCC V7.0 SP3 through V7.5 SP2 on Windows 7 SP1 / Windows 10 LTSC / Windows Server 2012 R2 / 2019. It is not supported on WinCC Unified (V16+), which has its own SysSerial namespace and does not require an OCX.
mscomm32.ocx. Treat it as a legacy COM component and lock down the engineering station accordingly. On 64-bit Windows you must register the 32-bit OCX because WinCC Runtime is a 32-bit process.Prerequisites and Architecture
Before configuring the picture, verify the following hardware and software prerequisites.
| Item | Requirement | Notes |
|---|---|---|
| WinCC version | V7.0 SP3 or later, RT or RT + ES on same node | Tested against V7.1, V7.2, V7.3, V7.4 SP1, V7.5 SP2 |
| OS | Windows 7 SP1 / 10 LTSC 2019 / Server 2012 R2 / 2019 (32- or 64-bit) | 64-bit hosts must run 32-bit registration |
| MSComm32.ocx | Version 6.1.98.16 (mscomm32.ocx) shipped with VB6 SP6 runtime | Redistributable, ~104 KB |
| Physical COM port | Native RS232 DB-9, USB-to-RS232 (FTDI FT232, Prolific PL2303), or PCI multi-port card | Appears as COM1..COMn in Device Manager |
| Barcode scanner | RS232 output, ASCII framing, terminator CR (0x0D) or CR+LF (0x0D 0x0A) | Most industrial scanners default to 9600-8-N-1 |
| User rights | Local administrator for OCX registration, then standard user for Runtime | Lock down after install |
The runtime data flow is:
- Scanner emits ASCII frame terminated by CR/LF on the physical COM1.
- The MSComm32 ActiveX control inside the WinCC picture raises an
OnCommevent when bytes are buffered. - A VBScript handler reads the
Inputproperty, strips the terminator, validates the payload, and writes the cleaned string to a WinCC internal tag (e.g.,Barcode_Last). - A WinCC timer (or scheduled VBS action) triggers scans every 5 minutes by pulsing the scanner's trigger line through
MSComm.CommPortRTS/DTR, or simply by waiting on the next autonomous scan. - Optional: a tag logging frame persists the value to a circular archive at
TagLoggingSlow.
Installing and Registering MSComm32.ocx
On a 64-bit Windows host, the WinCC Runtime process is 32-bit. The OCX must therefore be registered in the WOW6432 node.
- Copy
mscomm32.ocxto%SystemRoot%\SysWOW64\(64-bit OS) or%SystemRoot%\System32\(32-bit OS). - Open an elevated command prompt.
- Register the 32-bit OCX:
cd C:\Windows\SysWOW64 regsvr32.exe mscomm32.ocx - Expected dialog:
DllRegisterServer in mscomm32.ocx succeeded. - Verify the COM registration:
reg query "HKCR\CLSID\{648A5600-2C6E-101B-82B6-0000C0BBA6B5}"
mscomm32.ocx to the AV exclusion list before running regsvr32, otherwise the ActiveX will appear in the WinCC insert dialog but fail to instantiate with error 0x80040112 (CLASS_E_CLASSNOTREG).Configuring the COM Port Parameters
Match the serial parameters on the scanner to the values written into the MSComm control. The defaults below cover 95% of industrial 1D/2D imagers.
| Property | Typical value | Description |
|---|---|---|
CommPort |
1 | COM1. For USB-to-serial use Device Manager to map a stable COM number (e.g., COM4). |
Settings |
"9600,N,8,1" | 9600 bps, no parity, 8 data bits, 1 stop bit |
Handshaking |
comNone (0) or comRTSXOnXOff (3) | comNone = no flow control. Use RTS/CTS for noisy panels. |
InputMode |
comInputModeText (0) | Returns VB string. Use comInputModeBinary (1) for non-ASCII. |
RThreshold |
1 | Fire OnComm after every byte. Use N for fixed frame length scanners. |
SThreshold |
0 | Disable transmit buffer events |
InputLen |
0 | Read whole buffer. Set 13 if scanner emits fixed 13-char code39. |
PortOpen |
True | Open the port. Closing the picture should close it. |
Adding MSComm to the WinCC Graphics Designer
- Open Graphics Designer and load the target picture (e.g.,
Start.pdl). - Right-click the empty area, choose Smart Objects > ActiveX Control, or use the toolbar Insert > ActiveX Control.
- In the Insert ActiveX Control dialog, scroll to Microsoft Communications Control, version 6.0. If absent, the OCX is not registered correctly.
- Place the control. Rename the object to
MSComm1via the Properties pane (Object Name field). - Set the initial properties on the Properties tab:
MSComm1.CommPort = 1 MSComm1.Settings = "9600,N,8,1" MSComm1.Handshaking = 0 'comNone MSComm1.InputMode = 0 'comInputModeText MSComm1.RThreshold = 1 MSComm1.PortOpen = True - Set Visible to
Noif the control is purely a data conduit and should not appear in Runtime.
VBScript Implementation for Barcode Reading
Create the internal tags first in the WinCC Tag Management. Right-click Internal Tags > New and create the following.
| Tag name | Data type | Length | Purpose |
|---|---|---|---|
Barcode_Last |
Text tag, 8-bit char set | 32 | Last accepted scan |
Barcode_Count |
Unsigned 32-bit | - | Monotonic counter for sequence |
Barcode_Status |
Signed 16-bit | - | 0=OK, 1=No data, 2=Parity, 3=Overrun, 4=Framing, 5=Break |
Barcode_Timestamp |
Date/Time | - | Server time of last good read |
Barcode_Trigger |
Binary tag | - | Edge 0->1 fires a trigger pulse to the scanner |
Attach a global VBScript action to the picture. Open the picture's Event tab and configure the OnComm event of MSComm1 to call a project function OnSerialData().
' ---------------------------------------------------------------
' WinCC Global Action: OnSerialData
' Trigger: MSComm1.OnComm (every time bytes arrive)
' Purpose: parse ASCII barcode line, validate, write to internal tags
' ---------------------------------------------------------------
Function OnSerialData()
Dim sIn, sClean, i
Const MAX_LEN = 32
If HMIRuntime.SmartTags("Barcode_Status").Read = 0 Then
' already OK, fall through
End If
On Error Resume Next
sIn = HMIRuntime.SmartTags.Item("MSComm1").Input
If Err.Number <> 0 Then
HMIRuntime.Trace "MSComm1.Input failed: " & Err.Number & " " & Err.Description & vbCrLf
Err.Clear
Exit Function
End If
On Error Goto 0
If Len(sIn) = 0 Then Exit Function
' Strip CR / LF / NUL / STX / ETX framing characters
sClean = sIn
For i = 1 To Len(sClean)
Select Case Asc(Mid(sClean, i, 1))
Case 2, 3, 10, 13, 0 ' STX ETX LF CR NUL
sClean = Replace(sClean, Mid(sClean, i, 1), "")
End Select
Next
' Validate: alphanumeric only, max MAX_LEN
Dim re
Set re = New RegExp
re.Pattern = "^[A-Za-z0-9\-\.]{1," & MAX_LEN & "}$"
If Not re.Test(sClean) Then
HMIRuntime.SmartTags("Barcode_Status").Write 2 ' parity / validation
HMIRuntime.Trace "Barcode validation failed: [" & sIn & "]" & vbCrLf
Exit Function
End If
' Commit to internal tags
HMIRuntime.SmartTags("Barcode_Last").Write sClean
HMIRuntime.SmartTags("Barcode_Status").Write 0
HMIRuntime.SmartTags("Barcode_Timestamp").Write Now
HMIRuntime.SmartTags("Barcode_Count").Write _
HMIRuntime.SmartTags("Barcode_Count").Read + 1
HMIRuntime.Trace "Barcode OK: " & sClean & vbCrLf
End Function
HMIRuntime.SmartTags.Item("MSComm1") when the control was placed on a picture with object name MSComm1. Do not reference the control from a global VBS action that runs without picture context - the object is not in scope. Use the picture-level Event action of the control itself.Polling on a 5-Minute Cycle
There are two common scan modes: autonomous (scanner fires on object detect) and host-triggered (the WinCC picture pulses the trigger line). For the user's "scan every 5 minutes" requirement, host-triggered mode is more deterministic.
- In the picture add a WinCC Timer control (or a global C action) with a 5-minute interval (300,000 ms).
- On Timer Event, run the VBScript snippet below to send a 50 ms trigger pulse through the MSComm
Outputproperty or by toggling RTS viaMSComm1.RTSEnable:Sub On5MinTick() ' Method A: software trigger via serial command (Honeywell, Zebra, Datalogic) HMIRuntime.SmartTags.Item("MSComm1").Output = Chr(13) ' <CR> HMIRuntime.SmartTags("Barcode_Trigger").Write 1 ' Method B: hardware trigger on RTS (Pin 7) ' HMIRuntime.SmartTags.Item("MSComm1").RTSEnable = True ' HMIRuntime.SmartTags.Item("MSComm1").RTSEnable = False End Sub - If the scanner is configured to presentation mode (continuous trigger when enabled), the timer is redundant - simply let
OnCommdrive the storage and let the scanner's own internal beeper confirm the read. - Use
HMIRuntime.SmartTags("Barcode_Trigger").Write 0from a separate 200 ms timer to clear the trigger tag for edge detection upstream.
Storing Scans in Internal Tags and Archives
The Barcode_Last internal tag can be consumed by:
-
I/O field on the picture - bind an I/O Field output to
Barcode_Last. Set Update to "On change" so Runtime refreshes the moment the tag is written. -
Tag Logging - in the Tag Logging editor, create a new archive BarcodeArchive of type TagLoggingSlow (1 s cycle) and add
Barcode_Last,Barcode_Count,Barcode_Statuswith event-based acquisition on tag change. -
User Archives - for SQL-style persistence, route the value through a UA field using
HMIRuntime.SmartTags.Item("UA_Barcode").Value = sCleanafter binding the user archive column. -
Alarm Logging - raise a message of class System, With Acknowledgement with process value
Barcode_Lastto get a chronological scan log in the WinCC AlarmView control.
Verification and Runtime Testing
- From the engineering station, open HyperTerminal, PuTTY (serial mode 9600-8-N-1) or the free WinCC Tag Simulator to confirm the scanner itself is emitting data on COM1.
- In Graphics Designer, press F5 to test the picture locally. Click in the I/O field bound to
Barcode_Lastto confirm output updates. - Open the WinCC ApDiag tool (Apdiag.exe in the WinCC installation directory) and filter the Connection view. Verify that the MSComm control initializes without error 0x800A0E7A (ADO could not find provider).
- Trigger a scan and inspect the Runtime trace (WinCC Explorer > Tools > Trace): the line Barcode OK: 12345678 should appear in WinCC_Sys_
.log on the diagnostics path. - Check the internal tag value with the online tag table (Tag Management > right-click > Display Tag Values). Verify
Barcode_Countincrements by exactly 1 per good read. - Verify the archive using WinCC Archive Viewer or SQL Viewer. The BarcodeArchive should show 1 row per accepted scan with timestamp.
- Stress test: trigger 200 scans in 60 seconds and confirm the Runtime CPU stays below 25% on a Core i5 and the tag archive has no gaps. This validates the
RThreshold/InputLentuning.
Troubleshooting Matrix
| Symptom | Likely cause | Diagnostic | Fix |
|---|---|---|---|
| MSComm missing from Insert ActiveX dialog | OCX not registered, or 32/64 bit mismatch | Run regsvr32 mscomm32.ocx from elevated CMD |
Re-register in SysWOW64 on 64-bit OS |
| Runtime error 0x80040112 (CLASS_E_CLASSNOTREG) | AV stripped the CLSID key | Check HKCR\CLSID\{648A5600-2C6E-101B-82B6-0000C0BBA6B5} | Add mscomm32.ocx to AV exclusion, re-register |
| PortOpen fails with error 8005 | COM port in use, wrong number, or USB device detached | Device Manager; check mode COM1 from CMD |
Close HyperTerminal; assign a stable COM number via Device Manager |
| OnComm fires but Input is empty | Scanner using binary mode, RThreshold too high, wrong terminator | Capture traffic with HHD Free Serial Port Monitor | Set InputMode=0, RThreshold=1, terminator CR/LF |
| Garbled characters (e.g. Ø instead of A) | Baud / parity / data bit mismatch | Verify scanner configuration sheet | Match Settings string to scanner config |
| Triggers fire continuously, CPU at 100% | RThreshold=0 with high noise | Watch process explorer | Set RThreshold=1 and decouple via internal tag |
| Tag value never updates | Global action cannot see picture-bound ActiveX | Trace shows nothing | Move handler to picture's OnComm event |
| Works in Graphics Designer, not in Runtime client | OCX not installed on client; WinCC client is 32-bit | Check client log | Deploy mscomm32.ocx to every RT client |
| Error 8020 in trace (comPortInUse) | Two pictures opening the same COM port | Search project for CommPort=1 | Open COM in only one master picture; consume the tag globally |
| Data appears with leading 0x02 0x30 bytes | Scanner adds AIM/ID symbology identifier | HHD dump | Disable symbology ID in scanner config or strip in VBS |
Security and Hardening Notes
Because mscomm32.ocx is a Win32 COM component, it operates in-process with the WinCC Runtime. The following hardening steps are recommended on a production deployment.
- Use a dedicated USB-to-RS232 adapter (FTDI FT232H) and physically disable the COM port enumeration for any non-essential serial device via Group Policy.
- Set the scanner to inter-character timeout ≥ 50 ms and disable all symbologies that are not used (Code 39, Code 128, QR, DataMatrix as applicable). This shrinks the attack surface for malicious barcode injection.
- Whitelist the barcode format in the VBS validator (e.g., only allow 10-13 digit numeric for shipping labels). Anything else is rejected and logged to
Barcode_Status. - Apply Windows Defender Application Control (WDAC) to permit only signed OCX components.
mscomm32.ocxis signed by Microsoft but the signing certificate chain is now legacy - plan a migration to WinCC Unified'sSysSerialor to a vendor-supported OPC UA bridge long term. - Lock the engineering station so users cannot right-click the picture and use the Properties dialog to inject arbitrary VBScript.
Alternatives and Migration Path
If the mscomm32.ocx path is blocked by corporate security, the following alternatives deliver the same result with a cleaner architecture.
| Approach | Mechanism | Pros | Cons |
|---|---|---|---|
| CP340 / CP341 in S7-300/400/1500 | Point-to-point module on PLC, expose to WinCC via S7 driver | Industrial, isolated, deterministic | Requires a free slot in the PLC, more hardware |
| SIMATIC RF/RFID serial gateway | Vendor gateway converts RS232 to S7 / OPC UA | No OCX | Cost, single vendor lock-in |
| Third-party OPC UA serial bridge (Kepware, Softing, KEPServerEX) | Daemon reads COM, exposes OPC UA server | Modern, signed, supports many devices | Extra license, extra service to maintain |
| WinCC Unified (V16+) SysSerial namespace | Native RT scripting API, no ActiveX | Long-term supported, no OCX dependency | Requires V16+ project migration |
| Custom Windows service in C# / .NET | Service reads COM, writes to WinCC internal tag via WinCC ODK | Full control | More development effort, requires WinCC ODK license |
Frequently Asked Questions
Why does my COM1 read return only garbage characters in WinCC Runtime?
Baud rate, parity, data bits, or stop bits on the scanner do not match the MSComm1.Settings string. Verify the scanner's actual configuration via its programming barcodes or serial console (most Honeywell, Zebra, and Datalogic devices reply to a CR/LF query at 9600-8-N-1 by default), then set MSComm1.Settings = "9600,N,8,1" to match.
How do I trigger a barcode read every 5 minutes automatically?
Place a WinCC Timer with interval 300,000 ms on the picture. On its event, write a CR (Chr(13)) to MSComm1.Output or toggle MSComm1.RTSEnable for 50 ms. Most industrial scanners interpret either as a manual trigger pulse.
Can the same COM port be opened from multiple WinCC pictures?
No. A single physical COM port can only be opened by one MSComm instance at a time. Open the port in one master picture (e.g., Start.pdl) and consume Barcode_Last from any other picture via the standard tag interface.
Is mscomm32.ocx supported on 64-bit Windows with WinCC 7.x?
Yes, but you must copy the OCX to %SystemRoot%\SysWOW64\ and register it from an elevated command prompt using the 32-bit regsvr32.exe. The WinCC Runtime process is 32-bit, so it loads the WOW6432 registration. Do not place the OCX in System32 on a 64-bit host.
How do I migrate from mscomm32.ocx to WinCC Unified?
WinCC Unified (V16 and later) exposes SysSerial.open(), SysSerial.read(), and SysSerial.close() directly in JavaScript and C, eliminating the ActiveX dependency. Migration is project-by-project: redefine the barcode tag as an internal Unified tag, replace the VBScript handler with a Unified script, and remove the OCX installation step from the deployment image.