Resolving S7-1500 Modbus RTU Single-Bit Write Errors on CM 1541-1

David Krause18 min read
ModbusSiemensTroubleshooting
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

Resolving S7-1500 Modbus RTU Single-Bit Write Errors on CM 1541-1

Engineers integrating a Siemens S7-1500 CPU (S7-1511, S7-1513, S7-1515, S7-1516, S7-1518) with a third-party Modbus RTU slave through a CM 1541-1 or CP 1541-1 module frequently hit a stubborn fault: single-bit coil writes fail, multi-bit writes work, and word-level reads/writes are stable. The fault traces to a Modbus FC05 implementation gap in the slave. This reference documents the exact cause, the diagnostic procedure to confirm it, and the configuration change that resolves it without swapping hardware or firmware on the PLC.

1. Problem Statement

Configuration: TIA Portal V14 SP1 (also applies to V15, V15.1, V16, V17, V18, V19, V20), S7-1500 family CPU, CM 1541-1 (RS485/422, 6GK7541-1AB00-0AA0) or CP 1541-1 (RS485/422, 6GK7541-1AX00-0XE0), Modbus_Master instruction from the standard MODBUS (RTU) library.

Observed behavior on the master:

  • Read Holding Registers (MODE=5) — OK
  • Write Single Register (MODE=6, LEN=1) — OK
  • Write Multiple Registers (MODE=7, LEN=1..123) — OK
  • Read Coils (MODE=0, LEN=1..2000) — OK
  • Write Single Coil (MODE=1, LEN=1) — ERROR on slave addresses 1..9999
  • Write Single Coil (MODE=1, LEN=2) — OK on most slave firmware revisions (non-standard behavior, not guaranteed)
  • Write Multiple Coils (MODE=2, LEN=1..1968) — OK

The Modbus_Master instruction raises ERROR=TRUE with a STATUS code that pins the failure to the slave. The most common STATUS seen on the S7-1500 is 0x8180 (slave returned exception 01, ILLEGAL FUNCTION), followed by 0x8380 (exception 03, ILLEGAL DATA VALUE) on slaves that silently parse the FC05 PDU and reject it downstream.

Field note: The "OK with LEN=2 on MODE=1" symptom is misleading. The Modbus specification mandates that FC05 carries exactly one coil in its request PDU. A slave that accepts FC05 only with LEN>1 is non-conformant; the S7 master cannot guarantee which function code is actually issued for a non-standard length on MODE=1. Do not rely on this behavior. Use MODE=2 instead.

2. Affected Hardware and Firmware

Hardware and firmware matrix
Component Order number Firmware Notes
CM 1541-1 (RS485/422) 6GK7541-1AB00-0AA0 ≥ V1.0 Discontinued, replaced by CP 1541-1
CP 1541-1 (RS485/422) 6GK7541-1AX00-0XE0 ≥ V1.0, full MODE 0..14 from V2.0 Current product
CP 1542-1 (RS232) 6GK7542-1AX00-0XE0 ≥ V1.0 RS-232 only, no bus termination
S7-1500 CPU 6ES751x-xxx..-AB0 ≥ V1.8 for full instruction set All S7-1500 / ET 200MP CPUs
TIA Portal — V14 SP1 .. V20 Modbus (RTU) library ships with all versions

Confirm the installed module firmware with the online diagnostics in TIA Portal (online → accessible nodes → module → diagnostics → module information). For the CP 1541-1, the firmware can be updated using the Siemens support tool. Refer to the module's product page and the TIA Portal Help entry "Modbus (RTU) (S7-1200, S7-1500)" for the firmware dependency of the diagnostic instructions.

3. Technical Background: Modbus Function Codes for Coil Writes

The Modbus protocol defines two separate function codes for writing coils. They are not interchangeable on the slave side; each has its own PDU encoding and parser:

Modbus function code comparison
Property FC05 — Write Single Coil FC15 — Write Multiple Coils
PDU request size 4 bytes (fixed) 5 + N bytes (variable, N = byte count of bit-packed data)
Coils written per request Exactly 1 1..1968
Value encoding 0xFF00 = ON, 0x0000 = OFF 1 bit per coil, packed LSB-first into bytes
Response echo Echo of the request PDU Coil address + quantity, no data echo
Slaves that implement it Subset (often buggy) Virtually all

Wire-level RTU frames for the two function codes look like this (slave address 0x01, coil address 0x000A = 10):

FC05 write of one coil at address 10, value = ON
[01] [05] [00] [0A] [FF] [00] [CRC_LO] [CRC_HI]    (8 bytes total)

FC15 write of one coil at address 10, value = ON
[01] [0F] [00] [0A] [00] [01] [01] [01] [CRC_LO] [CRC_HI]   (10 bytes total)

Both frames achieve the same end state: a single coil flips at address 10. The FC15 frame adds two bytes (quantity + byte count) plus one byte of bit-packed data, but it is functionally equivalent for a single bit. The inter-frame silent interval of 3.5 character times (t3.5) is the same.

4. Siemens Modbus_Master MODE Mapping

The Modbus_Master FB from the MODBUS (RTU) library in TIA Portal accepts a MODE input that selects the underlying Modbus function code. The mapping is fixed in firmware and cannot be modified by the user:

MODE parameter mapping (CP 1541-1 / CM 1541-1, FW ≥ V2.0)
MODE Modbus FC Function DATA_LEN range DATA_PTR type
0 01 Read Coils 1..2000 BOOL array / DBX
1 05 Write Single Coil 1 BOOL
2 15 (0x0F) Write Multiple Coils 1..1968 BOOL array / DBX
3 02 Read Discrete Inputs 1..2000 BOOL array / DBX
4 04 Read Input Registers 1..125 WORD / INT array
5 03 Read Holding Registers 1..125 WORD / INT array
6 06 Write Single Register 1 WORD / INT
7 16 (0x10) Write Multiple Registers 1..123 WORD / INT array
8 23 (0x17) Read/Write Multiple Registers R 1..125, W 1..121 WORD / INT array
9..14 Various Diagnostic / vendor-specific FW-dependent FW-dependent

Refer to the TIA Portal Help topic "Modbus_Master / Modbus_Comm_Load" and the Communicate as Modbus master (S7-1200, S7-1500) manual for the exact FW dependency of MODE 8 and beyond. The CP 1541-1 product page on the Siemens support portal (search order number 6GK7541-1AX00-0XE0) lists the current firmware release and the supported function code set.

5. Root Cause Analysis

The S7-1500 master transmits the request and waits for a response. With MODE=1 and DATA_LEN=1, the master correctly issues an FC05 request. The slave's response falls into one of three categories:

  1. Exception 01 (ILLEGAL FUNCTION, 0x81): Slave does not implement FC05 at all. This is the most common cause in the field. The S7 master translates this into STATUS 0x8180.
  2. Exception 02 (ILLEGAL DATA ADDRESS, 0x82): Slave has a separate handler for FC05 that performs an address-range check; the address is outside the slave's coil map for FC05 but inside it for FC15. STATUS 0x8280.
  3. Exception 03 (ILLEGAL DATA VALUE, 0x83): Slave receives the FC05 PDU and tries to parse the value field but fails (often because the engineer hard-coded the parser to expect 0xFF00 in big-endian and the slave is little-endian, or the parser mis-handles the response echo). STATUS 0x8380.

All three causes point to the same conclusion: the slave's FC05 path is broken or absent. Switching the master to FC15 (MODE=2) routes the request through the slave's FC15 handler, which is almost always present and well-tested.

Why does LEN=2 sometimes "work" with MODE=1? Some legacy slaves have a guard in their FC15 handler that checks the quantity field before entering the bit-pack loop. When the master is configured with MODE=1, the slave's request parser may detect the value 0x0001 in the LEN field, treat it as a misrouted FC15 request, and respond with a success even though the function code on the wire is 0x05. This is non-conformant behavior. The S7 master does not deliberately downgrade MODE=1 to FC15 internally — the slave is taking liberties. Do not depend on it.

6. Wire-level Sequence Diagram

MODE=1 (FC05) — LEN=1 — Fails S7-1500 + CM/CP 1541-1 Modbus RTU slave FC05 [addr=10, val=0xFF00] Exception 0x81 (ILLEGAL FUNCTION) STATUS = 0x8180 MODE=2 (FC15) — LEN=1 — OK S7-1500 + CM/CP 1541-1 Modbus RTU slave FC15 [addr=10, qty=1, bits=0x01] Normal response [addr=10, qty=1] STATUS = 0x0000, DONE = TRUE Solid arrow: request, dashed arrow: response. Time runs top-to-bottom.

7. Diagnostic Procedure

  1. Verify the physical layer. Confirm RS-485 2-wire (half-duplex) vs 4-wire (full-duplex) vs RS-232. The CP 1541-1 supports both 2-wire and 4-wire via the on-board DIP switch; the CP 1542-1 is RS-232 only. Confirm 120 Ω termination at both ends of an RS-485 trunk. Confirm bias resistors are enabled on at most one device (the CP 1541-1 has a DIP switch for this).
  2. Match baud, parity, and framing. The CP 1541-1 supports 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200 baud with 7E1, 8E1, 8N1, 8N2. The slave's DIP switches or configuration software must match exactly. A parity mismatch produces STATUS 0xC091 on the master.
  3. Capture STATUS on the failing job. Add a WORD tag in a non-optimized DB to receive Modbus_Master.STATUS. On a rising edge of ERROR, copy STATUS to a buffer for trend analysis. The reference for STATUS values is the MODBUS (RTU) (S7-1200, S7-1500) error messages help topic.
  4. Reproduce on a PC-based Modbus tool. Disconnect the S7-1500 from the bus (or pause its Modbus_Master cycle), connect a USB-to-RS485 converter to a laptop, and run a Modbus RTU master utility (Modbus Poll, QModMaster, or a libmodbus-based script). Issue an FC05 write to the same coil address with quantity=1.
    • If the utility also reports exception 01, the slave does not support FC05. Continue to step 5.
    • If the utility reports exception 02 or 03, the slave implements FC05 but rejects this specific request; verify the coil address range in the slave documentation.
    • If the utility reports success, the S7 master has a separate problem (cabling, timing, address translation). Continue to step 6.
  5. Test FC15 on the same utility. With the S7-1500 still disconnected, issue an FC15 write to the same coil with quantity=1. If this returns success, the slave's FC15 handler is the only working code path. Reconfigure the S7 master to MODE=2 with DATA_LEN=1.
  6. If the utility reports success for FC05 but the S7 master still fails, check the t3.5 inter-frame gap. Some slaves tolerate the master's gap; others require a longer or shorter gap. Adjust the port's inter-frame delay in the CM/CP 1541-1 properties. Also verify that the slave ID in MB_ADDR matches the slave's address (1..247), that the offset is 0-based, and that the DB used for DATA_PTR is non-optimized.

8. Solution A — Use MODE=2 (FC15) for Single-Bit Writes

Reconfigure the failing Modbus_Master call as follows:

  • MB_ADDR = slave station address (1..247)
  • MODE = 2 (FC15, Write Multiple Coils)
  • DATA_ADDR = target coil address. Siemens uses 0-based addressing for coil offsets 0..9998. If the slave vendor documents 1-based addresses, add 1 to convert. For example, vendor coil "10" → S7 offset 9 (or 10 if the slave is also 0-based; check the slave's map).
  • DATA_LEN = 1
  • DATA_PTR = address of a BOOL tag or a DBX bit that holds the desired state (TRUE = ON, FALSE = OFF). The data block must be non-optimized.

Functionally, the wire-level request is a single-bit write. The slave writes the bit, returns a normal response, and the S7 master raises DONE for one scan. STATUS remains 0x0000 on success.

Important: DATA_PTR for MODE=2 must point to a non-optimized data block or a bit in a standard memory area (M, Q, I). Optimized access DBs are not permitted and produce STATUS 0x0003. See the MODBUS (RTU) error reference.

9. Solution B — Legacy LEN=2 Workaround (Not Recommended)

If the slave rejects FC05 with quantity=1 but accepts FC05 with quantity=2, you can keep MODE=1 and set DATA_LEN=2. Bit 0 is the real coil, bit 1 is a "don't care" coil that flips with every write. This is brittle:

  • It only works on slaves with a non-conformant FC05 parser that actually treats LEN=2 as a multi-coil request.
  • It mutates an adjacent coil on every write, which can corrupt the slave's state if that coil controls a real output.
  • It is not portable across slave firmware revisions.

Use this only as a temporary bridge while the slave vendor patches the FC05 handler. Permanent fix is Solution A.

10. Solution C — Compatibility Mode (Not a Fix for FC05 Issues)

The Compatibility mode checkbox in the CM 1541-1 / CP 1541-1 port properties changes the inter-frame response timeout and the silent interval behavior. It does not change the function code selected by the MODE parameter. A slave that does not implement FC05 will still reject the request when Compatibility mode is on. Enable it only when the slave documentation explicitly requires it, or when integrating with very old equipment (pre-2000) that uses a non-standard gap.

11. Configuration Procedure in TIA Portal

  1. Insert the module. Open the S7-1500 device configuration, drag the CP 1541-1 (or CM 1541-1) from the hardware catalog under "Communications modules" → "Modbus" into a free slot. Confirm the firmware version in the catalog matches the module's installed firmware.
  2. Configure the port. Open the module's properties, select "Port configuration", and set:
    • Operating mode: Modbus master (RTU)
    • Baud rate, parity, stop bits to match the slave
    • Inter-frame delay: 3.5 character times (default) or 50 ms for very old slaves
    • Response timeout: 1000 ms (adjust for slow slaves)
    • Compatibility mode: as required by slave
  3. Set the DIP switches on the physical module. The CP 1541-1 has a 4-position DIP switch: termination (on/off), bias (on/off), 2-wire/4-wire, and a reserved position. The DIP switch must agree with the software port configuration.
  4. Add the Modbus_Comm_Load instance. From the program blocks, drop Modbus_Comm_Load from "Communication" → "Modbus RTU". Configure it with the module's hardware identifier (from the system constants) and assign an instance DB (e.g., iDB_Modbus_Comm_Load). Call this FB once at startup; the DONE output enables the Modbus_Master jobs.
  5. Add the Modbus_Master instance. Drop Modbus_Master from the same palette. Assign a second instance DB (e.g., iDB_Modbus_Master_Coils). Configure MODE, DATA_ADDR, DATA_LEN, and DATA_PTR per Solution A above. The DATA_PTR must reference a BOOL in a non-optimized DB (e.g., "DB_Coils".Bit10).
  6. Build, download, and go online. Compile the project, download to the CPU, and go online. Open the instance DBs in the watch table and confirm DONE pulses TRUE on each request, ERROR remains FALSE, and STATUS = 0x0000.

12. SCL Code Example — Single-Bit Write Using FC15

// One-shot trigger for a single-bit write to a Modbus RTU slave.
// Pre-conditions: Modbus_Comm_Load has been called and DONE is TRUE.
// The instance DB "iDB_Modbus_Master_Coils" is the Modbus_Master IDB.
// "DB_Coils" is a non-optimized data block with a BOOL tag "Bit10".

IF "Start_Single_Write" THEN
    "iDB_Modbus_Master_Coils".REQ      := TRUE;
    "iDB_Modbus_Master_Coils".MB_ADDR  := 1;        // Slave ID 1
    "iDB_Modbus_Master_Coils".MODE     := 2;        // FC15 — Write Multiple Coils
    "iDB_Modbus_Master_Coils".DATA_ADDR := 10;       // Coil offset 10 (0-based)
    "iDB_Modbus_Master_Coils".DATA_LEN  := 1;        // Single bit
    "iDB_Modbus_Master_Coils".DATA_PTR  := "DB_Coils".Bit10;  // BOOL, non-optimized DB
    "Start_Single_Write" := FALSE;
END_IF;

// Reset REQ on completion; capture STATUS for diagnosis on error.
IF "iDB_Modbus_Master_Coils".DONE OR "iDB_Modbus_Master_Coils".ERROR THEN
    "iDB_Modbus_Master_Coils".REQ := FALSE;
    IF "iDB_Modbus_Master_Coils".ERROR THEN
        "Last_STATUS"     := "iDB_Modbus_Master_Coils".STATUS;
        "Last_Error_Time" := SYSTEM_TIMESTAMP();
    END_IF;
END_IF;

13. STATUS Code Reference

Selected STATUS codes for Modbus_Master on S7-1500
STATUS (hex) Cause Recommended action
0x0000 OK —
0x0001 MB_ADDR invalid (0 or > 247) Verify slave ID 1..247
0x0002 MODE invalid for the loaded port configuration or FW Re-check MODE against the table; update module FW
0x0003 DATA_PTR / DATA_LEN out of range, or DB is optimized Use non-optimized DB; verify DB number exists
0x0004 DATA_LEN invalid for the selected MODE Match LEN to MODE table (e.g., MODE=1 requires LEN=1)
0x0007 Data area overlaps another active use Use distinct DBs per concurrent job; serialize requests
0x8180 Slave exception 01 — ILLEGAL FUNCTION Slave does not implement FC05; switch to MODE=2
0x8280 Slave exception 02 — ILLEGAL DATA ADDRESS Coil address outside slave's map; check slave docs
0x8380 Slave exception 03 — ILLEGAL DATA VALUE Check CRC, baud, parity, termination
0xC091 Port configuration error Re-run Modbus_Comm_Load; check module FW
0xC092 Response timeout Increase response timeout; check slave power
0xC093 CRC error on the response Check wiring, termination, EMI, baud rate

For the full list refer to the MODBUS (RTU) (S7-1200, S7-1500) error messages help topic and the CP 1541-1 product documentation. The error reference covers the local master-side errors (0x0001..0x0007, 0xC0xx) and the Modbus exception codes returned by the slave (0x80 + exception code).

14. Verification Procedure

  1. With MODE=2 and DATA_LEN=1, trigger the job. DONE pulses TRUE for one scan; STATUS = 0x0000; ERROR remains FALSE.
  2. Confirm the coil on the slave changed state using the slave's HMI, web interface, or by reading the same coil back with a separate Modbus_Master call (MODE=0, LEN=1).
  3. Run a 24-hour stress test that toggles the coil at 100 ms intervals. ERROR must remain FALSE, STATUS must remain 0x0000, and the round-trip time (REQ rising edge to DONE rising edge) must remain stable within ±10%.
  4. Reconnect the laptop with the Modbus RTU master utility and verify the same coil is being polled by an independent tool. This rules out confusion about which slave is responding on a multi-drop RS-485 bus.
  5. Trend STATUS and round-trip time in WinCC Unified or a TIA Portal HMI to detect intermittent issues that the online watch table misses.

15. Multi-Slave and Multi-Job Considerations

On an RS-485 trunk with multiple slaves, each slave must have a unique MB_ADDR in the 1..247 range. A single CM/CP 1541-1 port supports multiple Modbus_Master jobs as long as each job has its own instance DB and the jobs are serialized (the instruction is non-reentrant). A typical pattern is to use a state machine in the OB1 cycle to dispatch one job per PLC scan, or to use a 100 ms cyclic OB for periodic polling.

If a downstream slave accepts FC05 and the upstream slave does not, implement two parallel Modbus_Master jobs with different MB_ADDR and DATA_PTRs, each configured with the correct MODE. The dispatcher selects the right job at runtime. This pattern is common on mixed-vendor Modbus installations where one controller is a legacy PAC and another is a modern sensor.

16. Related Topics

The same conceptual problem — single-bit write fails, multi-bit write succeeds — appears on the Modbus TCP side. When a Modbus TCP server is implemented by a Siemens S7-1500 CPU (acting as a Modbus TCP server on its PROFINET interface), some SCADA clients try to write a single bit to a holding-register address using FC05. The server rejects the request because the address is a register, not a coil. The workaround in the SCADA client is to construct a 16-bit mask and use FC16 to write the full register with the target bit set, leaving the other 15 bits unchanged. The lesson is the same: a server that does not support FC05 on its coil map will not support FC05 on its holding-register map either, and FC16 (or FC15 for coils) is the universal fallback.

For S7-1200 systems using the CM 1241 (RS485/422, 6ES7241-1CH32-0XB0) or CM 1241 (RS232, 6ES7241-1AH32-0XB0), the same MODE mapping applies and the same solution (MODE=2 for single-bit writes) resolves the issue. The TIA Portal Help topic "Modbus_Master / Modbus_Comm_Load" covers both CPU families.

17. Best Practices Summary

  • Always prefer FC15 (MODE=2) for single-bit writes when the slave's FC05 implementation is suspect. FC15 is functionally equivalent for a single bit and is supported by virtually all modern Modbus RTU slaves.
  • Use a non-optimized data block for the data pointer. The Modbus instructions reject optimized blocks with STATUS 0x0003 on S7-1500.
  • Call Modbus_Comm_Load only once at startup, with DONE feeding the enable logic of the Modbus_Master jobs. Do not call Modbus_Comm_Load cyclically — it re-binds the port and disrupts active jobs.
  • Use a single instance DB per concurrent Modbus_Master job. The instruction is non-reentrant; concurrent calls to the same instance DB produce undefined behavior.
  • Add 120 Ω termination at each end of the RS-485 trunk. Enable bias resistors on at most one device (the CP 1541-1 has a DIP switch for this).
  • Capture STATUS into a non-optimized DB on every rising edge of ERROR. Trend the values in WinCC Unified or a TIA Portal HMI to detect intermittent issues.
  • Keep the inter-frame gap at the default 3.5 character times. Increase to 50 ms only for slaves that explicitly require it.
  • When integrating with a new slave vendor, perform the FC05/FC15 test on a PC-based Modbus utility first. If FC05 fails, document it and standardize on MODE=2 for the project.

FAQ

Why does my S7-1500 master fail with STATUS 0x8180 when writing a single coil with MODE=1?

STATUS 0x8180 means the slave returned Modbus exception 01 (Illegal Function) for the FC05 Write Single Coil request. The slave firmware does not implement FC05. Switch the MODE parameter to 2 so the master uses FC15 (Write Multiple Coils) with DATA_LEN=1. The wire-level encoding is functionally equivalent for a single bit and is supported by virtually all modern Modbus RTU slaves.

Is there a Compatibility Mode that fixes single-bit write errors on CM 1541-1?

No. The Compatibility Mode checkbox in the CM 1541-1 / CP 1541-1 port properties changes the inter-frame timing and the response timeout; it does not change the function code selected by the MODE parameter. A slave that does not implement FC05 will still reject the request when Compatibility Mode is on.

Can I use MODE=2 with DATA_LEN=1 instead of MODE=1 for every single-bit write?

Yes. The PDU sent on the wire is a Write Multiple Coils request with quantity=1. The slave parses it, writes the single bit, and returns a normal response. This is the recommended replacement for MODE=1 when the slave's FC05 implementation is buggy or absent.

Which firmware version of CP 1541-1 supports the full MODE 0..14 range?

CP 1541-1 (6GK7541-1AX00-0XE0) supports the full MODE range from firmware V2.0.0 onward. Earlier firmware limits the supported MODEs to 0..7. The TIA Portal Help entry "Modbus_Comm_Load / Modbus_Master" lists the exact firmware dependency for each MODE. Update the module's firmware with the Siemens support tool before assuming a MODE is unavailable.

My S7-1500 master fails with STATUS 0x0003 when writing a coil. Is that the same problem?

No. STATUS 0x0003 means the data pointer (DATA_PTR) points outside the configured data block, the data block is optimized, or the data block number does not exist. Re-allocate the data block as a non-optimized DB and confirm the DB number exists at runtime. See the MODBUS (RTU) (S7-1200, S7-1500) error reference for the full list of causes.

Why does LEN=2 work with MODE=1 on some slaves but is not recommended?

Some legacy slaves have a guard in their FC15 handler that tolerates FC05 requests with LEN>1 by misrouting them to the FC15 parser. This is non-conformant and depends on the slave's specific firmware behavior. The S7 master does not deliberately downgrade MODE=1 to FC15; the slave is taking liberties with the protocol. Do not rely on this. Use MODE=2 with DATA_LEN=1 for a portable, spec-compliant fix.

Back to blog