The request comes up often enough that it is worth writing down clearly: a manufacturing team has an existing Siemens S7-1200 or S7-1500 PLC program, typically running for years, well-tested, and nobody wants to touch the ladder logic. Now there is a new requirement, usually from an IT team or a cloud analytics initiative, to get PLC coil states and data block values up to an MQTT broker so they can feed a dashboard or a digital twin platform.
The question is always: can we get the data without modifying the PLC program? The answer is yes, but the mechanism matters. This post explains how we approach it in Sancho, and what you need to understand about S7 communication to do this safely.
The S7 Communication Model: What Is Exposed Without PLC-Side Changes
Siemens S7 PLCs support two main remote access mechanisms that do not require changes to the PLC program. The first is S7comm (also called S7comm-plus on newer firmware), which is the native Siemens protocol used by TIA Portal, WinCC, and third-party tools like snap7. The second is Modbus TCP, which S7-1200 and S7-1500 firmware supports natively since TIA Portal V13.
S7comm access to a data block variable works by referencing the variable's DB number and byte offset within that data block. For example, to read a BOOL at DB1.DBX0.0, you issue an S7comm read request specifying DB1, byte offset 0, bit offset 0. You do not need to add any function block to the PLC program to support this read; it is handled at the firmware level. The critical requirement is that the data block's "Optimized block access" property must be disabled in TIA Portal. With optimized access enabled, STEP 7 reorganizes data block contents and the classic absolute addressing does not work. This is the first thing to check in any existing program before assuming S7comm reads will work.
snap7 is the most widely used open-source S7 communication library. It implements the S7comm protocol over TCP and supports reading DB variables, output image area (Q memory), input image area (I memory), and marker memory (M memory). For the MQTT bridging use case, snap7 is our starting point in the Sancho S7 connector.
The Architecture: S7 Connector Reading, MQTT Bridge Publishing
Sancho runs as a process near the PLC, either on a local industrial PC or on an edge device on the same Ethernet segment. The S7 connector polls the configured data block addresses at a configurable interval (typically 100ms to 500ms for status data, longer for process parameters). It normalizes the values into Sancho's internal event bus using typed payloads.
The MQTT bridge connector subscribes to those normalized events and publishes them to a configured broker. The topic structure is configurable in the cell map, so the topic hierarchy matches whatever the downstream system expects. A coil state that maps to a production cycle completion event might publish as factory/cell-3/cycle/complete with a JSON payload containing the timestamp and coil value. The PLC program never knows any of this is happening.
There are several things to be careful about in this architecture. First, the polling interval creates a minimum latency between the PLC state change and the MQTT publish. If you are publishing an event that something downstream will act on within tens of milliseconds, this approach is not appropriate. It is appropriate for monitoring, analytics, and MES integration where sub-second precision is acceptable. If you need sub-100ms event detection from a PLC state change, you need a different mechanism, typically an interrupt-driven approach that uses the PLC's built-in MQTT client (available on S7-1500 firmware 2.9 and above).
Second, the S7 connection consumes a CPU connection slot on the PLC. S7-1200 CPUs have a limited number of these (the exact count depends on the CPU model and firmware version, but typically 3 to 8). If the PLC already has a TIA Portal programming connection, a WinCC connection, and one or two device connections, adding another S7comm client may hit the limit. Monitor the PLC's diagnostic buffer when adding the connection; a "connection limit exceeded" event will appear there before you see any client-side errors.
Handling the Data Type Mapping
STEP 7 data types and JSON-serializable types do not have a one-to-one correspondence. BOOLs are straightforward. INTs map cleanly to JSON numbers. REALs (32-bit float) map to JSON numbers with a precision consideration. But S5TIME, TON/TOF timer values, DATE_AND_TIME structures, and user-defined structures require explicit mapping rules.
In the Sancho S7 connector configuration, you declare each data block variable with its address, type, and an optional transform function. For a REAL that represents a temperature in tenths of a degree (a common convention on older German-designed systems), you declare the type as REAL and add a scale transform: multiply by 0.1, unit is degrees_celsius. The MQTT payload then carries the interpreted value, not the raw register value. Downstream consumers get temperature, not a number that requires knowing the vendor convention to decode.
For BOOL arrays packed into bytes, you declare the byte address and specify a bit map that names each bit. The connector unpacks the byte and publishes each named bit as its own topic or as fields in a structured payload, depending on the configuration. This is more useful than publishing a raw byte value that the consumer has to mask.
What Stays in the PLC Program
One concern we hear from controls engineers is whether adding an S7 communication client creates any risk to PLC program behavior. The answer is that passive reads via S7comm do not affect PLC scan time in any measurable way for a well-sized CPU. The CPU handles S7 communication at the operating system level, not within the scan cycle. A continuous poll of 20 to 30 data block variables at 200ms intervals typically adds 0.1ms to 0.3ms to PLC response time under load, well within acceptable margins for any standard cell controller application.
The exception: if you are writing to the PLC via S7comm, the story is different. Writes from external clients do affect program behavior, and writes to variables that PLC logic is also writing to create race conditions. We do not recommend write paths via the S7 connector for production cell control. Read-only from PLC, write if necessary via a dedicated field interface that the PLC program owns.
We are not claiming this approach replaces native PLC-side MQTT clients for all use cases. If you are deploying new S7-1500 hardware and have the option to configure the built-in MQTT client, that is often the cleaner solution for event-driven publishing. The S7-to-MQTT bridge approach is specifically for situations where modifying the PLC program is not an option, which is a very common situation in production environments where the ladder logic is production-critical and change-controlled.
Read next: Modbus TCP on the Factory Floor in 2025: Still Everywhere, Still Annoying