Problem Overview
When commissioning a Siemens SIMATIC S7-300 PLC as a Modbus TCP participant against a Modbus master simulator such as Win-Tech ModScan32, the application program compiles cleanly and the CP (typically a CP343-1 or CP343-1 Lean/Advanced) reports an established link, yet no data exchange occurs. The only diagnostic indication is a recurring status word bit pattern that decodes as error code A092. Because A092 is reported by the Modbus runtime rather than by the standard SIMATIC diagnostic buffer, it is frequently misread as a transport-layer fault (TCP, ISO-on-TCP, or CP firmware) when the actual fault is an application-layer addressing mismatch between the S7-300 program and the Modbus master polling map.
This article isolates the root cause of the A092 condition, walks through the corrected wiring of the Modbus function blocks on the S7-300, validates the DB222 instance parameterization, and configures ModScan32 (licensed build) for verification. The procedure applies to the legacy SIMATIC Modbus/TCP blocks distributed with the S7-300 CP product family: FB106 (MB_CPLI), FC10 (MB_HOLD), AG_CNTRL, and the standard instance DB (DB222 in the default example project). Field engineers integrating the S7-300 against third-party SCADA, Ignition, or a custom .NET/PC master will follow the same diagnostic path.
Decoding Error A092: Modbus Exception Code 2
The A092 status is generated when the Modbus client block receives an exception response from the partner with Modbus exception code 0x02 (ILLEGAL DATA ADDRESS). According to the Modbus Application Protocol Specification V1.1b3, exception code 2 is returned by a server when the request references a register coil or holding register that does not exist in the server's address space, or when the requested quantity plus starting address exceeds the implemented address range.
| Code (hex) | Name | Meaning | Typical S7-300 Cause |
|---|---|---|---|
| 0x01 | ILLEGAL FUNCTION | Function code not supported | MB_CPLI configured for a FC the server cannot service |
| 0x02 | ILLEGAL DATA ADDRESS | Address outside server map | A092 - Master polls outside DB222 range |
| 0x03 | ILLEGAL DATA VALUE | Value in request invalid | Quantity register exceeds PDU limit or start+quantity wraps |
| 0x04 | SLAVE DEVICE FAILURE | Unrecoverable server fault | DB222 missing, CP not ready, OB1 not cycling |
| 0x06 | SLAVE DEVICE BUSY | Server busy, retry later | Cycle time violation, AG_CNTRL busy too long |
The exception frame is encapsulated as follows on the wire (PDU):
Function Code | Exception Code
0x80 + FC | 0x02
Example (FC03 poll failure): 83 02
For the S7-300 CP343-1 the Modbus runtime translates the received 0x02 into status word bit pattern 0xA092, which the application sees in the STATUS output of FB106 / FC10. A092 can also be re-cast as decimal 41042 or, when viewed as individual flags, the following bits are set:
| Bit | Meaning |
|---|---|
| 0 | General error |
| 1 | Modbus protocol error |
| 4 | Exception code received |
| 7 | TCP connection broken since last call |
| 12 | Address check failed on partner |
| 15 | Function aborted by runtime |
The implication is unambiguous: the S7-300 is receiving a reply from the partner, the reply is a valid Modbus PDU, but the partner (ModScan32 in this case, when configured to simulate a server) is rejecting the request because the S7-300 client is asking for an address the simulator has not been configured to serve.
Root Cause Analysis: Three Failure Modes
Field experience with the S7-300 Modbus blocks yields three reproducible root causes for the A092 symptom. Any one is sufficient; in real commissioning work all three are often present.
Cause 1 - DB222 Modbus Map Mismatch
The default SIMATIC Modbus TCP example project configures DB222 with a Modbus address space that starts at offset 40001 (Holding Register 1) and extends for a fixed quantity, typically 100 words. The Modbus client's parameter block in DB222 contains the start address of the PLC data area (e.g., DB222.DBD0 = 400001), the quantity of registers, and the function code mask (read holding registers 03, read input registers 04, write single register 06, write multiple registers 16). If ModScan32 is configured to poll address 400101 (i.e., the 101st holding register) and the DB only exports 100 registers, the simulator will return exception code 2 and the S7-300 client will surface it as A092.
Cause 2 - FC Number Collision with AG_CNTRL
The Modbus blocks use an internal helper function that the application program must call repeatedly to drive the CP. In the Siemens example project this function is FC10. However, the user program may already declare its own FC10 in the symbol table, causing STEP 7 to silently substitute one symbol for the other when AG_CNTRL resolves its call target. If AG_CNTRL ends up calling the user's FC10 instead of the Modbus library FC10, the CP never receives a Modbus request and the connection sits idle; on the next master poll, the S7-300 side never responds, but the S7-300 client may itself be polling another node and seeing A092-style exceptions back. The recommended remediation is to rewire AG_CNTRL to a free FC number such as FC100 by editing its source in a separate, offline copy of the project.
Cause 3 - ModScan32 Trial Version Limitation
Win-Tech's ModScan32 was historically shipped as a 30-day trial that permitted only Modbus RTU/ASCII serial polling. The trial build rejects Modbus TCP client connections silently; the application starts, accepts the TCP connect, but never issues a request frame. The S7-300 therefore sees no exception, but also no successful response, and the application interprets the missing reply as a timeout. According to Prosoft Technology's published KB article on Modscan32 trial limitations, this is a licensing check rather than a protocol fault.
Step-by-Step Resolution
The remediation proceeds in five ordered steps. Each step is independently verifiable and may be skipped only after confirming the previous step is already satisfied.
Step 1 - Inventory the Modbus Library Blocks
- Open the S7 project in STEP 7 V5.5 or TIA Portal (with the legacy S7-300 CP block library imported).
- Navigate to the Blocks container and confirm the presence of: FB106 (
MB_CPLI), FC10 (MB_HOLD), FC100 (AG_CNTRLafter rewiring), DB222 (Modbus data instance), and UDTs if used. - Verify that no user-defined FC10 exists in the symbol table. If a user FC10 is present, right-click > Rename and move it to FC11 or similar; the symbol table update must propagate to all call sites.
Step 2 - Rewire AG_CNTRL to FC100
Open a separate, offline copy of the project (File > Save As with a suffix such as _AGCNTRL_REWIRE). In that copy:
- Open the AG_CNTRL source. The block is implemented as a wrapper that calls a Modbus-internal FC. Locate the call statement (e.g.,
CALL FC 10). - Change the FC number from 10 to 100. Recompile and download to the offline PLC only - never to the running production CPU.
- Verify that the FC10 instance DB and the FC100 instance DB are both present and correctly populated. In the symbol table, map
AG_CNTRLto FC100. - Re-download to the target PLC and observe the diagnostic buffer. Successful rewiring eliminates the symptom; failed rewiring produces W#16#8081 (resource problem) or W#16#80A1 (FC parameter assignment error).
Step 3 - Validate DB222 Instance Configuration
Open DB222 in STEP 7 and verify the following parameters against the S7-300 CP Modbus manual reference data. The exact layout depends on the Modbus block version; the canonical fields are:
| Offset | Field | Type | Valid Range | Example |
|---|---|---|---|---|
| DBW0 | EN_ENABLE | BOOL | TRUE to enable | TRUE |
| DBW2 | MB_MODE | INT | 0 = server, 1 = client | 0 (server) |
| DBW4 | MB_DATA_ADDR | DINT | Modbus start address (1-based) | 400001 |
| DBW8 | MB_DATA_LEN | INT | Quantity of registers (1..125) | 100 |
| DBW10 | MB_DATA_PTR | POINTER | Any DB or M area | P#DB100.DBX0.0 BYTE 200 |
| DBW14 | MB_TCP_PORT | INT | 502 default | 502 |
| DBW16 | MB_TCP_IP | STRING[15] | Partner IP | '192.168.0.10' |
| DBW32 | MB_TIMEOUT | TIME | 100ms..10s | T#2s |
The most common field engineer error is leaving MB_MODE = 1 (client) while the system architect intended server behaviour. A092 only manifests when the S7-300 is the Modbus client; if it is configured as a server, A092 should not appear, and the symptom is therefore a configuration/state inconsistency between DB222 and the runtime state. Realigning MB_MODE to 0 (server) typically eliminates A092.
Step 4 - Configure ModScan32
- Launch ModScan32 (licensed version). The trial build will not transmit Modbus TCP frames reliably.
- From the Connection menu, select Connect. In the dialog, set:
- Port:TCP/IP
- Remote IP: the S7-300 CP IP (e.g., 192.168.0.20)
- Remote Port:502(or the port configured in HW Config for the Modbus connection)
- Slave ID: 255 for Modbus TCP (TCP does not use a slave address; the field is ignored by most stacks but must be a valid byte) - Set Address = 400001, Length = 100, Device ID = 255, Function = 03 (Read Holding Registers).
- Confirm polling starts. The status bar at the bottom should read "Connected" and the register table should populate within one poll cycle.
Step 5 - Verify the TCP Connection in the CP
Open the S7-300 online diagnostics (PLCSIM or real CPU):
- Right-click the CP343-1 in the project tree > Diagnostics > Connection Diagnostics.
- Confirm the Modbus TCP connection shows state = Established and ID = the configured connection ID.
- Open DB222 online and observe the STATUS word. It should now read
W#16#0000(no error).
CP343-1 Hardware Configuration Reference
The CP343-1 Lean (6GK7343-1CX10-0XE0), CP343-1 (6GK7343-1EX30-0XE0), and CP343-1 Advanced (6GK7343-1GX30-0XE0) all support the Modbus/TCP protocol option, which must be enabled by a license key on the older firmware and is included by default on the -EX30 / -GX30 variants from firmware V2.0 onwards. The configuration path in HW Config is:
- Properties > CP343-1 > Modbus/TCP tab.
- Enable the Modbus/TCP option and assign a connection resource (local ID 1..16).
- Configure the partner IP, partner port (502 default), and the local port (any, 502 conventional).
- Set the keep-alive timer to 30s (recommended for SCADA masters).
On the firmware side, A092 is reported by the Modbus block version 4.0 (FB106 V4.0) and later. Earlier V3.x blocks used different status encodings (e.g., 8081, 80A1). When upgrading a working V3.x project, expect to remap STATUS handling logic.
Connection Topology and Data Flow
The S7-300 Modbus TCP architecture is layered as follows. The application calls FB106 (MB_CPLI) cyclically from OB1; FB106 internally calls FC10 (MB_HOLD) which performs the actual data marshalling; FC10 then calls the CP's Modbus function via AG_CNTRL. The CP maintains the TCP socket to the partner. AG_CNTRL is the link between the user program and the CP's firmware mailbox. If AG_CNTRL is misrouted, the CP never receives a request and the master sees only timeouts.
Modbus Address Map Validation
When A092 persists after Steps 1-5, the next investigation is the master polling range versus the S7-300 address map. ModScan32 supports four function codes; the table below summarizes which S7-300 area each function code maps to and the resulting Modbus address space:
| FC | Modbus Area | S7 Source Area | 1-Based Address Range |
|---|---|---|---|
| 03 | Holding Register | DB or M (read/write) | 400001..465536 |
| 04 | Input Register | DB or M (read-only mapping) | 300001..365536 |
| 06 | Write Single Register | DB or M (write) | 400001..465536 |
| 16 | Write Multiple Registers | DB or M (write) | 400001..465536 |
If the master polls FC04 against an area the S7-300 has not pre-mapped as input registers, or polls beyond MB_DATA_LEN, the simulator returns 0x02. To debug, set ModScan32 to poll address 1 with length 1 (i.e., the smallest possible valid request) and confirm the S7-300 replies. Incrementally extend the length until the failure re-occurs; the breakpoint is the configured boundary.
Connection Stability and Timeout Tuning
Beyond A092, intermittent disconnect events are a common Modbus TCP issue. The CP343-1 keep-alive default is 30 seconds, which can mask short network outages. If the master is sensitive to brief disconnects, lower the keep-alive to 10 seconds and the master's read timeout to 1 second. The companion issue is the Modbus block's MB_TIMEOUT (default 2s). A value below 500ms produces spurious A092 reads because the master has not yet had time to reply. Recommended field values:
| Parameter | Conservative | Aggressive |
|---|---|---|
| MB_TIMEOUT (DB222) | T#3s | T#1s |
| CP Keep-Alive | 30s | 10s |
| Master Poll Period | 1000ms | 200ms |
| ModScan32 Timeout | 3000ms | 1000ms |
Troubleshooting Matrix
| Symptom | Likely Cause | Action |
|---|---|---|
| A092 only, no timeout | Master polling outside server map | Reduce ModScan32 length to 1, then expand |
| A092 + timeout interleaved | AG_CNTRL rewired to wrong FC | Move AG_CNTRL to FC100, recompile |
| A092 + W#16#80A1 | FC parameter assignment error | Check MB_DATA_PTR POINTER syntax |
| No error, no data | ModScan32 trial version | Upgrade to licensed build |
| A092 only when polled | Modbus client mode with server address | Set MB_MODE = 0 (server) |
| Connection drops every 60s | Keep-alive mismatch | Tune keep-alive to master poll rate |
| A092 + W#16#8081 | DB222 not loaded | Download DB222 with initial values |
| A092 on first poll only | TCP connection not yet established at first call | Pre-condition EN_ENABLE on STATUS=0 |
Comparison: ModScan32 vs Ignition vs Vendor Masters
Field engineers often start with ModScan32 but quickly move to a SCADA master once commissioning is complete. Each tool surfaces A092 differently:
| Master | A092 Visibility | Trial Limitations |
|---|---|---|
| ModScan32 (Win-Tech) | Status bar error count | TCP/IP client disabled in trial |
| Modbus Poll (Witte Software) | Per-request error log | 10-min trial, full TCP |
| Ignition (Inductive Automation) | Diagnostics log + tag quality | Full Modbus TCP in trial |
| Prosoft MNET module | Internal event log via web UI | N/A (hardware master) |
According to Prosoft Technology's published knowledge base, Modscan32 trial versions from www.win-tech.com historically did not allow Modbus TCP/IP client connections without a license; this is the most common cause of "no data, no error" symptoms during initial setup. Always verify the ModScan32 build by clicking Help > About and confirming the TCP/IP Client option is enabled.
Verification Checklist
- DB222 STATUS word reads W#16#0000 after a poll cycle.
- ModScan32 status bar reads "Connected".
- ModScan32 register table updates at the configured poll interval.
- CP343-1 connection diagnostics show state = Established.
- S7-300 diagnostic buffer shows no new error entries.
- Write test: change a register in DB222, confirm ModScan32 reflects the change within one poll.
- Disconnect test: pull the Ethernet cable; observe that the S7-300 sets status bit 7 within keep-alive timeout; reconnect; confirm STATUS returns to 0 within one poll.
Common Field Pitfalls
- Mixing MB_MODE between projects. Copying DB222 from a client project into a server project flips the role silently. Always confirm MB_MODE matches the architecture.
- Port conflict with WinCC flexible / TIA HMI. The HMI panel may also bind to TCP/502. Move the S7-300 to TCP/503 or the HMI to another port.
- Firewall on the engineering PG. Windows Firewall blocks outbound TCP/502 by default on Windows 10+. Add a rule for STEP 7 and ModScan32.
- PLC time-of-day not synchronized. Out-of-range timestamps in the CP log may mask the actual Modbus fault. Synchronize via NTP or SFC.
- MB_DATA_PTR pointing to a DB that is not loaded. Download the DB with initial values, otherwise AG_CNTRL returns W#16#8081.
Frequently Asked Questions
What does Modbus TCP error A092 mean on an S7-300?
A092 means the S7-300 Modbus client received an exception response with code 0x02 (ILLEGAL DATA ADDRESS) from the partner. The master polled a register address that does not exist in the S7-300's Modbus map defined in DB222. Reduce ModScan32's address range or extend DB222's MB_DATA_LEN to match.
Why does the S7-300 program not communicate with ModScan32 at all?
Most often because AG_CNTRL is calling the wrong FC number (a user FC10 collides with the Modbus library FC10). Rewire AG_CNTRL to FC100 in an offline copy of the project and recompile. Secondary cause: ModScan32 is the trial build, which disables TCP/IP client connections.
Which CP343-1 firmware versions support the Modbus TCP blocks?
Firmware V2.0 and later on the CP343-1 (6GK7343-1EX30-0XE0), CP343-1 Lean (6GK7343-1CX10-0XE0), and CP343-1 Advanced (6GK7343-1GX30-0XE0) support the Modbus/TCP option. The Modbus block library (FB106 V4.0+) requires the option enabled in HW Config.
What is the default Modbus TCP port for S7-300?
Port 502 (IANA registered for Modbus TCP). The S7-300 may be configured to any port, but 502 is conventional and what ModScan32 defaults to. If a SCADA master uses a non-standard port, set MB_TCP_PORT in DB222 to match.
How do I distinguish A092 from a TCP socket fault?
A092 implies a Modbus-level reply was received; a TCP fault would surface as W#16#80A2 (connection broken) or W#16#80C4 (timeout). If the CP diagnostics show TCP state = Established and STATUS still reads A092, the fault is application-layer (address map), not transport.