Connecting Siemens PLCSIM to Third-Party Software via s7prosim

David Krause11 min read
SiemensTIA PortalTutorial / 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

Overview

Siemens S7-PLCSIM and the newer S7-PLCSIM Advanced are software-based PLC simulators that execute a TIA Portal or STEP 7 V5 project on a virtual CPU. The virtual CPU exposes two primary integration surfaces for external applications such as MATLAB, LabVIEW, custom C/C++ clients, or arbitrary .NET programs:

  1. The s7prosim COM automation interface (legacy PLCSIM V5.x and TIA-Portal integrated PLCSIM V13+).
  2. The built-in OPC UA server exposed by S7-PLCSIM Advanced (and the symbolic OPC DA server exposed by NetToPLCSIM/PLCSIM V5).

For fault-diagnosis workflows that need to read/write I/O, data blocks, and Merker (M) words in a closed simulation loop, the s7prosim interface is the lowest-latency path. OPC UA is the recommended path when the 3rd-party client already supports OPC (MATLAB OPC Toolbox, Ignition, Kepware, custom UA clients) or when you need cross-platform, language-agnostic access.

This reference covers both surfaces, with working C++, MATLAB, and SCL code, and the exact TCP ports, .NET assemblies, and TIA Portal project settings required for a clean integration.

Prerequisites

Component Version / Notes
STEP 7 / TIA Portal V13 SP1 minimum for PLCSIM inside TIA; V15.1+ for PLCSIM Advanced integration
S7-PLCSIM V5.4 SP5 (STEP 7 V5) or integrated PLCSIM in TIA Portal (matches TIA version)
S7-PLCSIM Advanced V2.x (TIA V15.1) through V6.0 (TIA V18/V19). Adds native OPC UA server and Softbus mode
Siemens SIMATIC Automation Tool SDK Not required for s7prosim; PLCSIM Advanced ships its own .NET API (S7PLCSIMAdvancedApi.dll)
3rd-party runtime MATLAB R2018a+ (Data Acquisition or OPC Toolbox), Visual Studio 2015+ (C++/C#), LabVIEW 2018+
Windows privileges Local administrator for first-run PLCSIM registration and for opening the Softbus / virtual Ethernet adapter
Network adapter note. PLCSIM Advanced uses a Softbus driver and may install a virtual Ethernet adapter (Siemens PLCSIM Virtual Ethernet Adapter). If your 3rd-party client is on the same PC and the project uses S7-1500 CPU, leave the TCP/IP interface at the default 192.168.0.1 / 255.255.255.0 and add a route or static IP in the Windows adapter so the client can reach 192.168.0.1 on port 102.

Method 1 - s7prosim (COM Automation) for Legacy PLCSIM

s7prosim is a COM in-process server installed automatically with the PLCSIM plug-in inside TIA Portal (V13 SP1 and later) and the standalone PLCSIM V5.4 SP5 used with STEP 7 V5. The registered ProgID is S7ProSim.S7ProSim.1 and the type library is s7prosimoax.tlb. Any language that can call into COM (C++, C#, VB.NET, Python via win32com, MATLAB via actxserver) can read or write PLC tags while the simulation is in RUN.

Connecting s7prosim from MATLAB

MATLAB does not need the OPC Toolbox to use s7prosim; the standard actxserver function opens the COM object directly.

obj = actxserver('S7ProSim.S7ProSim.1');
obj.Connect;
obj.SetState('RUN');

% Read an input bit (I 0.0)
val = obj.GetInput(0, 0, 0);  % byte, bit, return type (0=Bool)

% Write to a marker (M 10.3)
obj.SetOutput(2, 0, 3, 1, 1);  % memory area 2 = M, byte 0, bit 3, val 1

% Read a data block word (DB1.DBD0)
obj.ReadTagValue('DB1.DBD0');

obj.Disconnect;

Connecting s7prosim from C++ (ATL / MFC)

Import the type library once with #import "s7prosimoax.tlb" in a single header. The CLSID resolves to the COM object registered by PLCSIM. Sample minimal C++ console code:

#import "s7prosimoax.tlb" rename_namespace("PS")
#include 
int main() {
    CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    PS::IS7ProSimPtr sim;
    HRESULT hr = sim.CreateInstance(__uuidof(PS::S7ProSim));
    if (FAILED(hr)) { std::cerr << "PLCSIM not running\n"; return 1; }
    sim->Connect();
    sim->SetState(L"RUN");
    sim->SetOutput(2, 0, 4, 1, 1);            // M 0.4 = TRUE
    VARIANT_BOOL b = sim->GetInput(0, 0, 0);  // I 0.0
    std::wcout << L"I0.0 = " << b << std::endl;
    sim->Disconnect();
    CoUninitialize();
    return 0;
}

Build with the PLCSIM installed type library referenced as s7prosimoax.tlb. The binary requires the COM registration from the PLCSIM install (or regsvr32 s7prosimoaxax.dll on developer machines).

Connecting s7prosim from C# (.NET)

C# does not need the TLB import step. Add a reference to Siemens.Simatic.S7ProSim (registered by the PLCSIM add-in) and use the late-bound dynamic type when the assembly is not on the build path:

Type t = Type.GetTypeFromProgID("S7ProSim.S7ProSim.1");
dynamic ps = Activator.CreateInstance(t);
ps.Connect();
ps.SetState("RUN");
ps.SetOutput(2, 0, 4, 1, 1);          // M 0.4 = 1
bool i00 = ps.GetInput(0, 0, 0);      // I 0.0
ps.Disconnect();

s7prosim Method Reference

Method Signature Description
Connect long Connect() Attach to the running PLCSIM instance. Returns 0 on success.
Disconnect void Disconnect() Detach from PLCSIM
GetState String GetState() Returns "RUN", "STOP", "RUN-P", "RUN-H"
SetState void SetState(String) Force CPU to RUN / STOP / RUN-P
GetInput BOOL GetInput(Byte b, Byte bit, Byte returnType) Read input process image
SetInput void SetInput(Byte b, Byte bit, Byte returnType, BOOL val) Force an input
GetOutput BOOL GetOutput(Byte b, Byte bit, Byte returnType) Read an output
SetOutput void SetOutput(Byte mem, Byte b, Byte bit, Byte returnType, BOOL val) Memory area 0=I, 1=Q, 2=M, 3=PIB, 4=PQB, 5=MB; force value
ReadTagValue VARIANT ReadTagValue(String name) Read any symbolic or absolute tag e.g. "DB1.DBD0", "Tag_1"
WriteTagValue void WriteTagValue(String name, VARIANT val) Write a tag
ExecuteScan void ExecuteScan() Single-step the OB1 scan (legacy)

Method 2 - OPC UA Server Inside PLCSIM Advanced

S7-PLCSIM Advanced (V2.0+, shipped with TIA Portal V15.1 and later, and maintained through V6.0 for TIA V19) embeds an OPC UA server inside the simulated CPU. The default endpoint port is 4840 (changed only in the virtual CPU's hardware configuration). This is the same OPC UA stack exposed by a physical S7-1500/S7-1200 CPU, so any OPC UA client that talks to a real S7-1500 will talk to PLCSIM Advanced with no client-side changes.

Enabling the OPC UA server in the virtual CPU

  1. In the TIA Portal project, open Device configuration of the S7-1500 CPU used in PLCSIM.
  2. Navigate to Properties > OPC UA > Server.
  3. Enable "Activate OPC UA Server".
  4. Set the desired port (default 4840).
  5. Under "Runtime permissions", grant the client user "Read" and (if required) "Write" on the data blocks or tags you want to exchange.
  6. Compile and download the project to PLCSIM Advanced (F5 in TIA, or use the PLCSIM Advanced control panel).

Connecting a UA client

Configure the UA client with the following parameters:

Parameter Value
Endpoint URL opc.tcp://<IP-of-PLCSIM>:4840
Security None (default) or Sign / SignAndEncrypt with a cert you load into the simulated CPU
Authentication Anonymous (default) or Username/Password if the simulated CPU has users configured
Namespace index 1 (Siemens), 2..n for user DBs

MATLAB UA example (read DB1.DBD0 every 100 ms)

ua = opcua('192.168.0.1', 4840);
connect(ua);
node = opcuanode(ua, 'ns=3;s="DB1"."Static_1"'); % symbolic path
da = opcda(ua, node);
grp = addgroup(da);
additem(grp, node);
grp.UpdateRate = 0.1;            % 100 ms
grp.Subscription = 'on';
start(grp);

Method 3 - NetToPLCSIM (OPC DA for Legacy PLCSIM)

For engineers who need an OPC DA bridge to a TIA-integrated PLCSIM (not Advanced), NetToPLCSIM (originally by nettoplcsim.sourceforge.net) listens on TCP/102 and re-routes S7 comms to the local PLCSIM instance. Combined with the SIMATIC NET OPC server (S7.OPC.DA.1 ProgID) this exposes the same tag namespace as a real S7-1500. NetToPLCSIM is the practical path for LabVIEW DSC, iFIX, WinCC user-defined clients, and any tool that insists on OPC DA rather than OPC UA.

Architecture: PLCSIM in a Closed-Loop Fault-Diagnosis Model

The typical research workflow couples a fault-detection algorithm (Petri-net reachability analysis, parity-check residuals, observer-based FDI) to PLCSIM in a single process. The recommended architecture is:

TIA Portal ProjectOB1 / FB / DBcompiled HW+SW PLCSIM / PLCSIM Advvirtual CPURUN cycle ~ 100 ms 3rd-Party ClientMATLAB / VC++ / LabVIEWFault-Diagnosis algo download s7prosim / OPC UA set inputs / markers (fault inject) Comparison:expected vs observed

Data flow per scan:

  1. Fault-detection algorithm (MATLAB/VC++) writes a fault-trigger word to DB1.DBW10 via s7prosim/OPC.
  2. PLCSIM executes the ladder/SCL logic on the next cycle.
  3. Algorithm reads the new DB1.DBW0, DB1.DBW2, and MW100 (residuals) and compares against the Petri-net reachability graph.
  4. A pass/fail signal is written back to M 50.0 for the HMI to visualize.

Step-by-Step: Building a PLCSIM <-> MATLAB Closed Loop

Step 1 - Build the TIA project

  1. Create a new TIA Portal V17/V18 project and insert an S7-1500 CPU (e.g. CPU 1515-2 PN 6ES7515-2AM02-0AB0).
  2. Add OB1 with the SCL snippet in the next section.
  3. Compile and select Start simulation (the PLCSIM button). The virtual CPU opens with default IP 192.168.0.1 and starts in STOP.

Step 2 - SCL block to expose test points

// FB1 - FaultDiagnosisTestPoint
// Drops the inputs and the integrator state into a struct that
// MATLAB can read in a single ReadTagValue call.
DATA_BLOCK "DB_Diag" "FB1"
  STRUCT
    InRaw : ARRAY[0..7] OF BOOL;   // mirrors IB0
    OutRaw : ARRAY[0..7] OF BOOL;  // mirrors QB0
    Counter : INT;                  // counts scan cycles
    FaultFlag : BOOL;              // set by MATLAB
    Residual : REAL;               // exposed for verification
  END_STRUCT;
END_DATA_BLOCK

Step 3 - Run the closed loop from MATLAB

sim = actxserver('S7ProSim.S7ProSim.1');
sim.Connect;
sim.SetState('RUN');
for k = 1:1000
    % Inject a fault on M 50.0 at k = 200
    if k == 200, sim.SetOutput(2,50,0,1,1); end
    v = sim.ReadTagValue('"DB_Diag".Counter');
    f = sim.ReadTagValue('"DB_Diag".FaultFlag');
    r = sim.ReadTagValue('"DB_Diag".Residual');
    fprintf('scan=%d counter=%d fault=%d residual=%.3f\n', ...
        k, v.uint16, f.bool, r.single);
    pause(0.1);     % match PLCSIM scan
end
sim.SetState('STOP');
sim.Disconnect;

Verification

After the loop runs, validate that the integration is healthy using the following checks:

Check Expected result
sim.GetState() returns "RUN" CPU is running inside PLCSIM
Counter increments by 1 every scan PLCSIM cycle is alive; if it stalls, COM call hangs
FaultFlag = TRUE after k=200 Write path works
Residual matches the MATLAB-computed value Read path works
MATLAB CPU usage < 30% Cycle is healthy; 100 ms loop is realistic for s7prosim

Troubleshooting Matrix

Symptom Root cause Fix
actxserver('S7ProSim.S7ProSim.1') throws "server creation failed" PLCSIM not running, or COM not registered Start PLCSIM, then run regsvr32 s7prosimoaxax.dll from the PLCSIM install dir (admin shell)
Connect returns non-zero Another process already holds the s7prosim channel Close other TIA / OPC clients; PLCSIM allows exactly one s7prosim client at a time
ReadTagValue returns VARIANT_EMPTY Tag name is wrong, or the DB is not optimized (must be accessible by absolute path) Use symbolic name only if "optimized block access" is OFF, otherwise use DB1.DBD0
OPC UA client gets BadCommunicationError Port 4840 blocked, or wrong endpoint IP Verify with PowerShell: Test-NetConnection 192.168.0.1 -Port 4840
PLCSIM Advanced "Softbus" not visible Driver install requires admin on first run Launch PLCSIM Advanced as admin once; Softbus adapter appears in Network Adapters
3rd-party software receives no data despite PLCSIM RUN CPU's cycle/clock is set to "no cycle time" in PLCSIM Advanced Open PLCSIM Advanced UI > set "Scan time" to e.g. 100 ms
C++ build fails on s7prosimoax.tlb Wrong platform target, or Visual Studio not running as admin during first build Rebuild the project as x64 to match PLCSIM; re-run tlbimp if symbolic binding breaks

Field-Commissioning Notes

Real CPU vs simulated CPU behavior. PLCSIM faithfully executes STL/SCL/GRAPH logic but does not simulate analog noise, bus propagation delays, or hardware watchdog faults. For fault-diagnosis research that targets sensor and actuator faults, inject the faults in the simulator (write to IB/PII) rather than expecting the simulator to model them physically.
Optimized DB access. S7-1500 DBs default to "optimized" which hides absolute addresses. Either disable optimized access on the test DB or use the symbolic name in s7prosim.
PLCSIM Advanced licensing. V5.0+ requires a purchased license; V2.x has a free 7-day trial via the TIA Start menu. For a research lab, use the trial license on a dedicated VM to avoid disturbing other engineers' machines.
Port collisions. If port 4840 is already used by another OPC UA server (e.g. an Ignition gateway on the same host), change the virtual CPU's port in hardware configuration; the same change must be propagated to all clients.

Performance Considerations

For high-throughput fault-diagnosis loops (> 1000 I/O points per second), s7prosim tops out around 200-300 single tag reads/s from a single MATLAB session because every call is a COM round-trip. Two optimizations help:

  1. Bulk into a single DB and call ReadTagValue('DB_Bulk') for the whole struct, parsing locally.
  2. Subscribe via the OPC UA MonitoredItems API with a 50 ms publishing interval. PLCSIM Advanced V4+ can sustain > 5000 monitored items at this rate.

For real-time HIL, keep MATLAB's loop in normal priority; PLCSIM itself is not real-time and a Windows host with power-management throttling can stretch the cycle to 200 ms or more.

FAQ

Can I connect PLCSIM to a custom C++ program?

Yes. Use the s7prosim COM automation interface imported via #import "s7prosimoax.tlb" in MSVC, or call the registered COM object from any language that supports COM (C++, C#, Python win32com, MATLAB actxserver, LabVIEW .NET).

Which port does the PLCSIM Advanced OPC UA server use?

Default is TCP/4840. The port is configured in TIA Portal under Device configuration > Properties > OPC UA > Server of the virtual CPU. If changed, every UA client must use the new port.

Is s7prosim supported in PLCSIM Advanced?

No. s7prosim is the legacy COM API for PLCSIM V5 and the TIA-integrated PLCSIM V13+ (single-CPU, single-client). PLCSIM Advanced replaces s7prosim with a .NET API (S7PLCSIMAdvancedApi.dll) plus the embedded OPC UA server; the workflow above uses the OPC UA surface for compatibility with MATLAB, LabVIEW, and custom clients.

Why does my PLCSIM cycle appear to freeze?

PLCSIM Advanced defaults to "no automatic cycle" until you set a scan time in its control panel, and the integrated PLCSIM can be paused by the breakpoint button. Open the PLCSIM UI, set the scan time to e.g. 100 ms, and verify GetState() returns RUN from your client.

Can multiple clients connect to the same PLCSIM simultaneously?

Only one s7prosim client at a time is allowed on the integrated PLCSIM. PLCSIM Advanced's OPC UA server accepts many concurrent clients and several s7prosim connections to separate instances; the limit is set by the CPU's max connection resources in the hardware configuration (default 32 for S7-1500).

Back to blog