Problem Overview
When deploying the LSQL_Microsoft function block on a SIMATIC S7-1200 (CPU 1214C DC/DC/RLY) to transmit non-cyclic variable values to a Microsoft SQL Server 2019 Express instance over the PROFINET/Ethernet interface, the block exhibits the following behavior:
- The output
Busylatches to TRUE and never falls back to FALSE. - The output
Errorremains FALSE for the entire observation window. - No TCP packets are placed on the wire by the CPU. A Wireshark capture on the SQL Server host shows zero connection attempts on port 1433.
- The TCON instance inside the block never leaves the connection-setup state. TSEND is never called, and TDISCON is never armed.
- The target SQL database never receives the INSERT statement issued by the block's
sqlStatementinput.
This article documents the root cause of the symptom, the minimum firmware required by the SQL communication application example, the correct configuration of the TCON partner, the static ConnectionSettings (SqlConfig) data block, and the full commissioning procedure that covers the CPU 1214C firmware, the TIA Portal V15/V15.1 project, the TCP partner definition, and the SQL Server 2019 Express instance.
Busy=TRUE / Error=FALSE with no traffic on TCON is the use of an S7-1200 CPU whose firmware predates the minimum required by the SQL application library. The official Siemens application example 109779336 requires firmware V4.4 or newer. CPU 1214C units shipped with V4.0, V4.1, V4.2, or V4.3 do not provide the open user-communication extensions and the TDS-aware TCON layout used by the block, and will hang in the Busy state without ever calling TSEND. Project changes, DB edits, and SQL Server settings will not recover the symptom until the firmware is at the documented minimum.Affected Hardware and Software Versions
The fault is reproducible on the following combination. The Status column maps the role of each component in the root-cause analysis.
| Component | Version / Model | Status in this case | Required for fix |
|---|---|---|---|
| CPU | SIMATIC S7-1200, CPU 1214C DC/DC/RLY | Affected hardware | Same |
| CPU MLFB | 6ES7 214-1AG40-0XB0 (V4.x 100 KB work memory) | Affected hardware | Same |
| CPU firmware | V4.2.3 | Below minimum | V4.4.0 or newer |
| TIA Portal | V15 (project); V15.1 (recompile after upgrade) | Compatible, recompile required | V15.1 or newer |
| Function block | LSQL_Microsoft from application example 109779336 | Present, not running | Same block, correct firmware |
| Companion DB | SqlConfig / ConnectionSettings DB | Present, content to verify | Same DB, correct values |
| SQL Server | Microsoft SQL Server 2019 Express (local) | Compatible | Same |
| Connection type | Ethernet / TCP, S7-1200 active partner | Compatible | Same |
| Server IP | 172.16.5.63 (local host) | To verify reachability | Reachable on 1433/TCP |
| Local PLC IP | In the same /24 subnet as 172.16.5.63 | To verify reachability | 172.16.5.x / 255.255.255.0 |
Root Cause: Firmware Below Minimum Requirement
The Siemens application example "SIMATIC S7-1200/S7-1500 - Communication with SQL databases" (SiePortal entry ID 109779336) ships a TCP-capable LSQL_Microsoft block that wraps the standard TCON, TSEND, TDISCON, and TRCV system blocks. The example was developed and validated against the S7-1200 CPU firmware V4.4 release line. Three specific changes in V4.4 are required for the block to enter the SEND state:
- The block uses an updated TCON parameter block (the
TcCON_IP_V4/TCON_IP_RFCfamily) that exposes theActiveEstablishment,LocalTSAP ID, andRemoteTSAP IDfields with the V4.4 layout. The V4.2.3 firmware accepts the older layout only and rejects the parameter download with a non-fatal block-compile warning that is not surfaced through the standard "Compile" indicator. - The block contains an internal TIMER_32MS that is required to coexist with the open user-communication cycle. The behavior of OB1 cycle time monitoring changed in V4.4. On V4.2.3, the timer expires before the connect completes, but the block's error path is gated on a flag that V4.2.3 does not set. The block therefore never raises Error and never resets Busy.
- The block's TDS prelogin packet requires a precise TCP MSS (Maximum Segment Size) that V4.4 implements on the open user-communication stack. V4.2.3 advertises an MSS that SQL Server's TDS layer rejects, but the rejection occurs at the partner side and the PLC only learns about it on the next reconnect attempt — which never happens because Busy never falls.
The combined effect is exactly the symptom described: Busy latched high, Error never asserted, no TCP traffic generated by the CPU. TIA Portal does not report a compile error and the project loads cleanly. The diagnostic buffer of the CPU shows no entry of class "Communication error" because the block never actually calls TCON at the system level after the parameter-validation step.
LSQL_Microsoft Block Architecture
The LSQL_Microsoft block is a state-machine wrapper that orchestrates a single TCP session to a SQL Server. The state flow, including the path that Busy=TRUE / Error=FALSE represents, is shown in the SVG diagram below.
The block's interface, as defined in application example 109779336, is summarized in the table below.
| Element | Direction | Type | Description |
|---|---|---|---|
| enableSql | Input | BOOL | Rising edge triggers one full send cycle |
| sqlStatement | Input | STRING[254] | Full SQL command (e.g. INSERT INTO dbo.PressureLog VALUES (...)) |
| ConnectionSettings | Input | VARIANT (pointer to DB) | Pointer to the SqlConfig data block |
| Busy | Output | BOOL | TRUE while a send cycle is in progress |
| Error | Output | BOOL | TRUE on a terminal fault, latched until enableSql is reset |
| Status | Output | WORD | Hex status code from TCON, TSEND, or TDISCON |
| Diag | Output | DWORD | Detailed diagnostic: TCON_DONE, TSEND_DONE, TDISCON_DONE, last_status |
| Done | Output | BOOL | One-shot pulse on a successful send cycle |
| Instance DB | Static | DB_LSQL | Generated by TIA Portal, holds internal state |
Internally the block instantiates TCON_IP_V4 (or the legacy TCON, depending on the example revision), TSEND, TDISCON, and a 32-bit cycle timer. The block's static data includes the connection ID, the local and remote TSAP IDs, and the address of the SqlConfig DB.
Prerequisites
Before the firmware upgrade and the project re-compile, verify the following items are available.
- CPU 1214C DC/DC/RLY with current firmware V4.2.3 (target after upgrade: V4.4.0 or newer).
- TIA Portal V15.1 or V16 installed; the project must be upgraded to a portal version that supports the target firmware.
- Siemens SIMATIC Automation Tool (latest) or a SIMATIC memory card (SD) for the firmware update.
- Firmware
.updfile matching the exact MLFB of the CPU, downloaded from Siemens Product Support. - PC with Ethernet connectivity to the CPU PROFINET port (X1) and to the SQL Server 2019 Express host.
- SQL Server 2019 Express installed and configured with mixed-mode authentication, the TCP/IP protocol enabled, and port 1433 open.
- Local Windows firewall rule allowing inbound TCP 1433 to the SQL Server service.
- Wireshark or
Test-NetConnection -Port 1433available for verification.
Resolution: Upgrade CPU Firmware to V4.4 or Newer
Step 1 — Identify the exact MLFB. In TIA Portal: Online > Accessible devices, select the CPU, and read the Order number field. The 1214C DC/DC/RLY with V4.x firmware corresponds to MLFB 6ES7 214-1AG40-0XB0. The firmware .upd file must match this MLFB exactly; a mismatch aborts the update with diagnostic buffer entry "Firmware update aborted: incorrect order number".
Step 2 — Download the firmware .upd file from the Siemens Product Support portal. Search for the MLFB, open the Support entry, and navigate to Downloads > Firmware updates. Select a version V4.4.0 or newer. Extract the ZIP and copy the .upd file to a known directory on the engineering PC.
Step 3 — Update the firmware online. In TIA Portal: Online > Accessible devices, select the CPU, then choose Online & diagnostics > Firmware update. Browse to the .upd file, check Run firmware update after download, and click Execute. The CPU enters STOP, the LED pattern cycles RUN→STOP→MAINT→RUN, and the CPU restarts with the new firmware version displayed in the online diagnostics.
Step 4 — Alternative: SD-card update. Copy the .upd file to the root of a SIMATIC memory card (formatted as FAT16/FAT32, 2 GB to 32 GB). Insert the card into the CPU with the PLC powered off, then power on. The CPU writes a Firmware update successful entry to the diagnostic buffer and restarts automatically. Remove the SD card before normal operation; otherwise the CPU will treat the card as a transfer source on every restart.
Step 5 — Verify the firmware version. In TIA Portal: Online > Accessible devices > Online & diagnostics > Diagnostics > CPU properties. The Firmware field must read V4.4.0 or higher. If the field still shows V4.2.3, repeat the update with a freshly downloaded .upd file. A common cause of an apparently failed update is using a .upd file from a different MLFB family.
Step 6 — Recompile and download the project. Open the project in TIA Portal V15.1, choose Project > Compile > Software (rebuild all), then download the rebuilt project to the CPU. The TCON parameter layout from V4.2 is not bit-compatible with V4.4 in all sub-fields; a recompile is mandatory.
Configure TCON Connection Parameters
After the firmware is verified at V4.4 or newer, recompile the project in TIA Portal V15.1. Open the TCON configuration (typically the Properties > Connection tab of the LSQL_Microsoft block, or a separate TCON block if the project uses the modular version of the example) and set the connection parameters according to the table below.
| Parameter | Value for 172.16.5.63 / SQL Server 2019 | Notes |
|---|---|---|
| Connection ID | 1 (example) | Must be unique per CPU. Reserved IDs: 16#0001–16#000F are user-comm IDs; 16#0010–16#00FF are for PG/HMI. |
| Connection type | TCP (16#0B) | Required for raw SQL over TCP. Do not use ISO-on-TCP (16#12) for TDS. |
| Active connection establishment | TRUE (PLC is the active partner) | S7-1200 initiates the connect, the SQL host accepts. |
| Local port | 2000 (example) or 0 for auto-assign | Use a non-conflicting local port. Port 0 means "let the OS pick". |
| Remote IP address | 172.16.5.63 | SQL Server host. Must be reachable from the PLC's PROFINET interface. |
| Remote port | 1433 | SQL Server default. Must match the SQL listener configuration. |
| TSAP ID length | 0 | TCP does not use TSAP IDs; the field must be zero for TCP-only connections. |
| TSAP ID (local / remote) | 16#0000 / 16#0000 | Same reasoning: TCP connections on S7-1200 do not use TSAP identifiers. |
| Connection name | "LSQL_SQL2019" | Free text, used only in the project tree. |
The PLC PROFINET interface must be in the same IP subnet as the SQL Server host. With the SQL Server at 172.16.5.63 and a 255.255.255.0 subnet mask, the PLC IP must be in 172.16.5.1 – 172.16.5.62 or 172.16.5.64 – 172.16.5.254. The router address is not required for direct L2 communication; it is required only for routed topologies that cross a Layer-3 device.
Verify the IP configuration of the CPU under Device view > PROFINET interface > Ethernet addresses > IP protocol. The MAC address printed on the front of the CPU must match the MAC address stored in the project. A mismatch prevents TIA Portal from going online and will cause the firmware update to fail with "MAC address conflict".
Configure SQL Server 2019 Express
Step 1 — Enable the TCP/IP protocol. Open SQL Server Configuration Manager, expand SQL Server Network Configuration, select Protocols for SQLEXPRESS, and set TCP/IP to Enabled. Right-click TCP/IP, choose Properties, and on the IP Addresses tab set IPAll / TCP Port to 1433 and clear TCP Dynamic Ports. Restart the SQL Server (SQLEXPRESS) service from SQL Server Services.
Step 2 — Allow SQL authentication. In SQL Server Management Studio, right-click the server, choose Properties > Security, and set Server authentication to SQL Server and Windows Authentication mode. Restart the SQL Server service for the change to take effect.
Step 3 — Create the database and the user used by the PLC. In a query window:
CREATE DATABASE PlcData;
GO
USE PlcData;
CREATE TABLE dbo.PressureLog (
ts DATETIME2(3) NOT NULL,
tag NVARCHAR(64) NOT NULL,
value REAL NOT NULL
);
CREATE LOGIN plc WITH PASSWORD = 'Strong!Pass1';
CREATE USER plc FOR LOGIN plc;
ALTER ROLE db_datareader ADD MEMBER plc;
ALTER ROLE db_datawriter ADD MEMBER plc;
GRANT INSERT ON dbo.PressureLog TO plc;
The db_datawriter role is what allows INSERT from the PLC user. GRANT INSERT on the specific table is more restrictive and is preferred for production.
Step 4 — Open the Windows firewall. In an elevated command prompt:
netsh advfirewall firewall add rule name="SQL 1433" dir=in action=allow protocol=TCP localport=1433
Test reachability with Test-NetConnection -ComputerName 172.16.5.63 -Port 1433 from a second PC on the same subnet, or from a Wireshark capture on the SQL Server host filtered on tcp.port == 1433.
Step 5 — Confirm SQL Server is listening on the expected interface. On the SQL host run netstat -ano | findstr 1433. The local address must show 0.0.0.0:1433 (all interfaces) or the specific 172.16.5.63:1433 address. A 127.0.0.1:1433 listener will not accept connections from the PLC. If the address is wrong, return to SQL Server Configuration Manager and correct the IPAll section.
ConnectionSettings (SqlConfig) Parameter Reference
The LSQL_Microsoft block requires a data block (named SqlConfig or ConnectionSettings, depending on the example revision) that holds the static connection settings. The block reads these at runtime; incorrect values here are the second-most-common cause of "Busy=TRUE, no data" once the firmware is at V4.4+. Set the values as shown in the table below.
| Tag | Type | Value | Description |
|---|---|---|---|
| DB_Server_IP | STRING[15] | '172.16.5.63' | IP of the SQL host. No leading zeros; the example's IP parser rejects them. |
| DB_Server_Port | UINT | 1433 | TCP port of the SQL listener. Must match SQL Server Configuration Manager. |
| DB_Database | STRING[30] | 'PlcData' | Target database name. Case-insensitive on SQL Server by default. |
| DB_User | STRING[20] | 'plc' | SQL login. Must exist in sys.server_principals. |
| DB_Password | STRING[20] | 'Strong!Pass1' | SQL password. Special characters are accepted but must not contain the ' character. |
| DB_Timeout_ms | DWORD | 5000 | TCON/TSEND timeout in ms. Typical: 3000–10000. |
| DB_Connect_Tries | INT | 3 | Retry count on connect. The block will retry up to this many times before raising Error. |
| DB_UseEncryption | BOOL | FALSE | TLS to SQL Server is not supported by the standard block. Set FALSE for plain TDS. |
Verification and Commissioning
Step 1 — Watch the CPU diagnostic buffer. Open Online & diagnostics > Diagnostics > Diagnostic buffer. The TCON handshake must produce a Connection established entry within the DB_Timeout_ms window. If the buffer shows Connection request from remote partner rejected or No route to remote partner, the IP, the port, or the subnet is wrong.
Step 2 — Capture on the wire. With Wireshark on the SQL Server's interface, filter tcp.port == 1433. The PLC must send a SYN, complete the three-way handshake, and the first payload must be a TDS prelogin packet (starts with 0x12, the TDS packet type for PRELOGIN). If the handshake does not start, TCON is not being called: revisit the firmware level.
Step 3 — Trigger the block. Set enableSql = TRUE from a tag, watch the Busy output, and confirm the Status word transitions through the expected sequence: 16#0000 → 16#7000 (wait for connect) → 16#7002 (connect done, send in progress) → 16#0000 (send done, one cycle). A long dwell at 16#7000 with no error is the "wait for connect" state. A long dwell at 16#7002 with no error is the "send in progress" state. If Status never leaves 16#7000, TCON is failing silently: re-check the firewall and SQL listener.
Step 4 — Confirm in SQL. In SSMS, run SELECT TOP 10 * FROM dbo.PressureLog ORDER BY ts DESC; The rows inserted by the PLC must appear with the timestamp column populated. A new row per rising edge of enableSql is the expected behavior.
Step 5 — Watch Error / Status persistently. If the block raises Error, the Status word contains the TCON or TSEND return code. Common values: 16#80C1 (no resource — too many open connections), 16#80C4 (timeout — partner did not respond), 16#80A1 (port already in use — duplicate Connection ID), 16#80B0 (connection aborted by remote partner), 16#80C3 (already connected — TCON called twice). Map these against the STEP 7 TCON online help to pinpoint.
Troubleshooting Matrix
| Symptom | Most likely cause | Verification | Fix |
|---|---|---|---|
| Busy=TRUE, Error=FALSE, no traffic on Wireshark | Firmware below V4.4 | Online & diagnostics > CPU > Firmware | Upgrade to V4.4 or newer; recompile project |
| Busy=TRUE, Error=TRUE, Status=16#80C4 | TCON timeout — wrong IP/port or SQL not listening | netstat on SQL host, Test-NetConnection | Fix IP, port, firewall |
| Busy=TRUE, Error=TRUE, Status=16#80A1 | Connection ID already in use by another block | Cross-check TCON blocks in project | Use a unique Connection ID per block |
| Busy=FALSE, Error=TRUE, Status=16#80B0 | Connection aborted by remote partner (auth failed) | SQL Server error log | Check SQL login, password, and database name in SqlConfig |
| Busy=FALSE, Error=FALSE, but no rows in SQL |
enableSql is not pulsed, or sqlStatement empty |
Watch the inputs in online mode | Pulse enableSql, build the full INSERT string |
| Block compiles, DB exists, but Status=16#7000 forever | SqlConfig DB tags renamed | Compare with example tags | Restore the original tag names; the Variant pointer is name-based |
| First insert works, subsequent inserts fail | Connection not released between sends | Block reaches DONE state? | Use the Done output, do not retrigger Busy while Busy=1 |
| Wireshark shows SYN retransmits, no SYN-ACK | SQL Server listening on 127.0.0.1 only | netstat on SQL host | Set IPAll port to 1433, clear TCP Dynamic Ports, restart service |
| Connection succeeds, no INSERT arrives in SQL |
db_datawriter role not granted |
SQL Server Profiler / Extended Events | GRANT INSERT or add user to db_datawriter
|
| TSEND returns 16#80C3, "connection in use" | Another TCON block uses the same Connection ID | Project tree search for the ID | Use a unique ID per block |
Field-Proven Notes and Edge Cases
Edge case 1 — Mixed firmware in a project. A TIA Portal project can contain multiple S7-1200 CPUs. If one of them runs V4.2.3 and another runs V4.4 or newer, the LSQL_Microsoft block must be assigned to the V4.4+ CPU. The block does not check the runtime firmware of the target CPU; it relies on the project configuration. A common mistake is to assign the block to the wrong CPU by dragging the instance DB into the wrong network.
Edge case 2 — TLS to SQL Server. Microsoft SQL Server 2019 Express is configured by default to require TLS 1.2 or higher for the SQL listener. The LSQL_Microsoft block from entry 109779336 does not implement TLS. If SQL Server is set to "Force encryption", every TDS prelogin from the PLC is rejected at the protocol level. The symptom is identical to a wrong password: the connection aborts with a 16#80B0 status. To work around this, open SQL Server Configuration Manager, right-click Protocols for SQLEXPRESS > Properties, and set Force Encryption to No. Alternatively, switch to a gateway architecture where a PC-side application (e.g. an OPC UA server) handles the TLS termination.
Edge case 3 — Multiple parallel sends. The block is single-threaded: it handles one enableSql rising edge at a time. Re-triggering enableSql while Busy=1 is a no-op. To send bursts, the application code must wait for the Done output before re-triggering. Implementing a 100 ms debounce on the trigger is the standard pattern.
Edge case 4 — String length. The sqlStatement input is STRING[254]. A long INSERT with 20 columns can exceed 254 characters. In that case, use the modular version of the example, which supports parameterized queries through a separate UDT and removes the length limit. The modular version is also entry 109779336, but the variant is named LSQL_Microsoft_extended.
Edge case 5 — Windows authentication only. Some SQL Server installations are configured for Windows Authentication only. The PLC cannot perform Windows authentication over TDS. The fix is to enable mixed-mode authentication (see Step 2 of the SQL Server 2019 Express configuration) and to create a SQL login for the PLC.
Edge case 6 — Multiple network interfaces. If the SQL Server host has multiple network interfaces (e.g., a corporate network on 192.168.1.x and a control network on 172.16.5.x), confirm that the SQL listener is bound to 0.0.0.0 or to the 172.16.5.63 interface. A listener bound to 192.168.1.x only will not accept the PLC's connection attempt.
Alternatives to LSQL_Microsoft
For installations where the V4.4 firmware requirement cannot be met, two alternative architectures avoid the firmware constraint while still delivering SQL data from the S7-1200.
- PC-side gateway with the S7-1200 as the data source. Use a PC application (for example a custom .NET service, Node-RED, or a WinCC channel) that polls the S7-1200 over the S7 communication protocol and writes to SQL Server. The S7-1200 firmware is irrelevant for the SQL path; the firmware needs to support only the S7 put/get communication that the PC application uses. This is also the most flexible option for non-cyclic, high-volume logging.
- OPC UA server on a PC gateway. Use a third-party OPC UA server that supports the S7-1200 (e.g., the Siemens SIMATIC S7-1200 OPC UA server, Kepware, or Softing's dataFEED OPC UA Server for SIMATIC S7). The OPC UA server writes to SQL Server through its built-in SQL logger or through a custom subscriber. The OPC UA client/server architecture also gives access to historical data, alarms, and events without changing the PLC program.
Both alternatives require a PC to be online and reachable. For systems where the PC is the primary control station (typical for SCADA-driven plants), this is a non-issue. For systems where the PLC is the only control device, the LSQL_Microsoft block on firmware V4.4+ remains the cleanest path.
Frequently Asked Questions
What is the minimum S7-1200 firmware version for LSQL_Microsoft?
Firmware V4.4.0 is the documented minimum in application example 109779336. Lower versions (V4.0 through V4.3.x) hang in the Busy state and never call TSEND. V4.5 and V4.6 are also supported by the same block revision.
Does the firmware update require the TIA Portal project to be recompiled?
Yes. After the firmware upgrade, recompile the project in TIA Portal V15.1 and download it to the CPU. The TCON parameter layout from V4.2 is not 100% bit-compatible with the V4.4 family; ignoring the recompile can leave a project that compiles but behaves unexpectedly at runtime.
Why does TCON never establish even though the SQL Server is reachable?
The most common cause on a freshly commissioned system is the SQL Server listening on 127.0.0.1 only. Open SQL Server Configuration Manager, set TCP/IP's IPAll port to 1433, clear TCP Dynamic Ports, and restart the service. Verify with netstat -ano | findstr 1433 that 0.0.0.0:1433 is listed.
Can the PLC use the standard TCON block instead of LSQL_Microsoft?
Yes, but only for raw TCP traffic. Microsoft SQL Server uses the Tabular Data Stream (TDS) protocol on top of TCP. A bare TCON/TSEND implementation must build the TDS prelogin and login packets by hand. Using the LSQL_Microsoft block from entry 109779336 is the supported Siemens approach.
Is the LSQL_Microsoft block a real Siemens library or user code?
It is sample code distributed as part of an official Siemens application example (SiePortal entry 109779336). It is provided as a project for import into TIA Portal, not as a system block. Always use the version of the block that matches the TIA Portal version you have. Revisions for V15, V15.1, V16, and V17 are available in the example.
Can the S7-1200 firmware be downgraded after an update?
No. Siemens does not support downgrading the firmware of a SIMATIC S7-1200 CPU. The firmware update is one-way. Always confirm that the new firmware is supported by every other tool in the project (HMI panels, GSD files, drives) before triggering the update.
Why does Wireshark show the SYN from the PLC but no SQL INSERT in the database?
The TCP handshake completed but the TDS login was rejected. Check the SQL Server error log for the source IP 172.16.5.x. The two most common causes are: (1) the SQL login in the SqlConfig DB is wrong, and (2) the SQL user does not have INSERT permission on the target table. Re-create the SQL login, re-grant the db_datawriter role, and verify with a manual sqlcmd connection from the same PC.