Connecting LMQTT_client to Local Mosquitto Broker on S7-1500 CPUs

David Krause16 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

1. Overview of the LMQTT_client Communication Architecture

The LMQTT_Client function block is part of the Siemens Library for MQTT (LMQTT), distributed through the Siemens Industry Online Support portal. The library implements a lightweight MQTT v3.1.1 client directly on the CPU's user program, eliminating the need for a dedicated CP 1545-1 or CloudConnect gateway. The client exchanges publish/subscribe messages with any standards-compliant broker, including the open-source Eclipse Mosquitto broker.

The typical deployment topology is illustrated below. The S7-1500/ET 200SP CPU acts as an MQTT client; the workstation running mosquitto.exe (or the Linux mosquitto daemon) acts as the broker. Both endpoints must share an IP-reachable subnet and must agree on TCP port (default 1883, or 8883 for TLS).

S7-1500 / ET 200SP CPU 1512SPF-1 LMQTT_Client FB PROFINET X1 192.168.0.10 PC / IPC mosquitto broker TCP 1883 / 8883 192.168.0.20 topic tree: siemens/* MQTT PUBLISH / SUBSCRIBE Layer-3 switch / router

The PLC initiates a TCP connection to the broker. Authentication, topic filtering, keep-alive, and QoS handling are managed inside the FB. The programmer does not have to write any low-level socket or TLS code.

2. Prerequisites

Before instantiating LMQTT_Client in your project, verify the following hardware, firmware, and software requirements.

Component Required Version Notes
CPU ET 200SP CPU 1512SP F-1 PN (6ES7512-1SK02-0AB0) or compatible S7-1500 Firmware V2.6 or higher recommended
TIA Portal V16 Update 5 or higher (V17/V18 also supported) Library version must match portal version
LMQTT library V2.0.x for TIA V16, V2.1.x for TIA V17 Downloaded from Siemens Support with valid user account
Operating system on broker host Windows 10/11, Windows Server 2016+, or Linux (x64, ARM) No Windows-Only requirement
Mosquitto broker V2.0.0 or higher V1.6.x also works; ACL syntax differs
Network IPv4 subnet, TCP port 1883 (or 8883 for TLS) reachable both directions Firewall must allow outbound from CPU
PLCsim limitation: PLCSim and PLCSim Advanced do not implement the full TLS 1.2 stack required by LMQTT. If you select useTLS = TRUE on a simulated CPU, LMQTT_Client.status will return a low-level component error (typically 16#80B1) and the connection will never reach the connected state. Use a real S7-1500 or ET 200SP CPU for any TLS test.

3. Installing the LMQTT Library in TIA Portal

  1. Open the Siemens Support search page and search for entry ID 109771836 ("Library for MQTT (LMQTT) – for S7-1500 and ET 200SP"). Download the .zip matching your TIA Portal major version.
  2. Extract the archive. You will find global library files such as LMQTT_V2_0_x.zal16 and accompanying PDFs describing the FB interfaces.
  3. In TIA Portal, choose Options → Global libraries → Open library and select the .zal16 file.
  4. Drag the LMQTT_Client type from the Master copies pane into your project tree under Program blocks → Types.
  5. Open Devices & networks, select the CPU, and confirm that the LMQTT library is shown under PLC supervision & diagnostics → Information → Library versions after compilation.

If you do not see the library version, the project still references a previous type FB version of LMQTT. Re-compile all blocks with Project → Compile all → Software (rebuild all blocks).

4. LMQTT_Client Function Block Interface

The block exposes a fixed input/output interface. The following table lists the inputs you must populate to establish a connection. All string parameters are of type WString on the S7-1500 (UTF-16 LE encoding).

Input Data type Description Example
connect BOOL Rising edge initiates (or re-initiates) the MQTT session TRUE
brokerAddress WString[64] IPv4 dotted-quad of the broker host "192.168.0.20"
brokerPort UINT TCP port; 1883 unencrypted, 8883 for TLS 1883
clientID WString[64] Must be unique per broker. Avoid spaces. "S7_1512SPF_01"
userName WString[64] Optional; required if broker ACL demands it "plc_user"
userPassword WString[64] Optional; required if broker ACL demands it "Pa$$w0rd"
keepAlive Time PINGREQ interval; 30 s is a safe default T#30s
cleanSession BOOL If FALSE, the broker retains QoS-1/-2 messages for offline clients TRUE
useTLS BOOL Switch to TLS (port 8883) – requires TLS data block configuration FALSE
publishTopic WString[128] Topic to publish to on rising edge of publish "siemens/line1/temp"
publishMessage WString[512] Payload (string). For binary, use the byte variant FB. "23.5"
publishQoS BYTE 0, 1, or 2 per MQTT 3.1.1 1
publishRetain BOOL Broker stores the last message for new subscribers FALSE
subscribeTopic WString[128] Topic filter to subscribe to "siemens/cmd/#"
subscribeQoS BYTE Maximum QoS granted by the broker 0

Outputs of interest: connected (BOOL, true while the session is established), busy (BOOL), error (BOOL), and status (WORD). When error = TRUE, status holds the diagnostic code described in Section 8.

5. Mosquitto Broker Installation and Configuration

Eclipse Mosquitto is the reference broker for this library. Install it on the same workstation that will run long-term, or on a dedicated IPC in the control cabinet.

5.1 Installation on Windows

  1. Download the official installer (64-bit) from the Mosquitto download page on the Eclipse Foundation site. The Windows build is shipped by the Mosquitto project itself and is signed.
  2. Run the installer with administrator rights. The default install path is C:\Program Files\mosquitto\.
  3. Open a Command Prompt in the install directory and confirm the version:
    cd "C:\Program Files\mosquitto"
    mosquitto -h | findstr "version"
    mosquitto -v
    # 1719287873: mosquitto version 2.0.18 starting
  4. Add the install directory to the system PATH environment variable for convenience.

5.2 Minimal mosquitto.conf for Local Development

Create a configuration file at C:\mosquitto\config\mosquitto_plc.conf with the following content. This configuration is suitable for a closed lab network where the PLC and the broker are the only participants.

# mosquitto_plc.conf - minimal config for LMQTT_Client testing
listener 1883 0.0.0.0
allow_anonymous true
persistence true
persistence_location C:/mosquitto/data/
log_dest file C:/mosquitto/log/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information
connection_messages true
log_timestamp true
max_inflight_messages 200
max_queued_messages 1000
Security warning: allow_anonymous true permits any client on the network to publish/subscribe. In a production cell, switch to allow_anonymous false and add a password_file plus an acl_file. The PLC must then supply matching userName and userPassword values on LMQTT_Client.

5.3 Generate a Password File (Optional but Recommended)

cd "C:\Program Files\mosquitto"
mosquitto_passwd -c C:\mosquitto\config\plc_pw.txt plc_user
# type password twice

Add the following lines to the configuration file and restart the broker service:

allow_anonymous false
password_file C:/mosquitto/config/plc_pw.txt
acl_file C:/mosquitto/config/plc_acl.txt

Sample plc_acl.txt granting the PLC read/write access to a single topic subtree:

user plc_user
topic readwrite siemens/#

5.4 Verifying the Broker

Use the bundled mosquitto_sub and mosquitto_pub command-line tools to confirm the broker accepts and routes messages.

# Terminal A - subscribe
mosquitto_sub -h 127.0.0.1 -p 1883 -t "siemens/#" -v

# Terminal B - publish (from any reachable host)
mosquitto_pub -h 127.0.0.1 -p 1883 -t "siemens/line1/temp" -m "23.5"

If Terminal A prints siemens/line1/temp 23.5, the broker is healthy and ready to accept the S7 client.

6. Network and Firewall Configuration

On a Windows host, the default firewall rule created by the Mosquitto installer opens only loopback traffic in some builds. Add an explicit inbound rule:

netsh advfirewall firewall add rule name="Mosquitto 1883" dir=in action=allow protocol=TCP localport=1883
netsh advfirewall firewall add rule name="Mosquitto 8883" dir=in action=allow protocol=TCP localport=8883

On the PLC side there is no firewall, but confirm the following in Devices & networks:

  • The PROFINET interface of the CPU is in the same IP subnet as the broker host (e.g. 192.168.0.10/24 for the CPU, 192.168.0.20/24 for the broker).
  • The CPU's Security → Firewall settings (only on CPU firmware V2.9 and higher with security enabled) are not blocking outbound TCP.
  • Any managed switch between CPU and broker is not filtering by MAC ACL.

A quick reachability test from a Windows command shell on the same subnet:

ping 192.168.0.10
Test-NetConnection 192.168.0.10 -Port 1883

The Test-NetConnection cmdlet should return TcpTestSucceeded: True. If it returns False, the TCP path is blocked; do not proceed with the LMQTT configuration until this is resolved.

7. Step-by-Step Commissioning Procedure

  1. Create a new cyclic OB (e.g. OB1 or a dedicated OB35 at 100 ms). Declare a single instance DB of LMQTT_Client and assign all input parameters in the call interface as shown below.
  2. Wire the input parameters with constants, tags, or HMI fields. Begin with unencrypted settings: brokerPort := 1883, useTLS := FALSE, userName := "", userPassword := "" (matches allow_anonymous true).
  3. Start the broker using the custom config file:
    cd "C:\Program Files\mosquitto"
    mosquitto -c C:\mosquitto\config\mosquitto_plc.conf -v
    The -v flag enables verbose logging in the console window; useful during commissioning.
  4. Compile and download the TIA Portal project to the CPU. Perform a warm restart to ensure the OB is executed.
  5. Trigger the connection by setting connect := TRUE. The FB requires a rising edge; if the input stays TRUE the FB handles reconnection automatically on error.
  6. Observe the FB outputs in the watch table or HMI:
    • connected should toggle to TRUE within 1–3 seconds.
    • error should remain FALSE.
    • status should read 16#0000.
  7. Verify from the broker side in the Mosquitto console window. You should see a line similar to:
    1719287923: New connection from 192.168.0.10:49152 on port 1883.
    1719287923: New client connected from 192.168.0.10:49152 as S7_1512SPF_01 (p2, c1, k30).
    The token c1 means clean session = 1, k30 means keep-alive = 30 s.
  8. Publish a test message by pulsing publish for one OB cycle. The publishDone output acknowledges a successful QoS-1 acknowledgement from the broker.
  9. Subscribe and receive by setting subscribeTopic := "siemens/cmd/#" and pulsing subscribe. Any matching message published by mosquitto_pub appears at receivedTopic and receivedMessage.

8. Diagnostic Status Codes (status WORD)

The status output reports the library-internal or TCP-layer error. The most common values you will encounter are listed below. The codes conform to the LMQTT library reference manual shipped with the download.

Code (hex) Meaning Typical cause Remedy
16#0000 No error — —
16#8001 Connection refused / TCP error Wrong IP, port blocked, broker not running Verify reachability with Test-NetConnection
16#8002 Protocol error / malformed packet Mismatched MQTT versions, corrupted payload Confirm Mosquitto V2.x and LMQTT V2.x
16#8003 TLS handshake failure Missing certificate, expired cert, cipher mismatch Re-import certificate, check TLS_DB FB
16#8004 Authentication failure (CONNACK return code 4 or 5) Wrong username/password or anonymous not allowed Adjust mosquitto.conf ACL or PLC credentials
16#8005 Invalid client ID (CONNACK return code 2) Client ID already in use, contains invalid characters Generate unique ID per CPU, avoid spaces
16#80B0 Library internal error Buffer overflow, instance DB too small Re-create the instance DB; check receivedMessage length
16#80B1 Difference in low-level component (version mismatch) Library version does not match CPU firmware/portal version Match library to TIA Portal version and recompile all
16#80C0 Timeout (broker did not respond) Network latency, keep-alive too short Increase keepAlive, check network

9. Diagnosing the "Difference in Low-Level Component" Error

The message "difference in low-level component" displayed in the TIA Portal online watch table is a generic notification that the user program references a type FB (here LMQTT_Client) whose version on the CPU does not match the version in the project. The library uses several subordinate FBs (LMQTT_TLS_Client, the OpenSSL-derived security component, and the TCP socket wrappers); any version skew between them triggers this message.

9.1 Root Causes

  • Library and TIA Portal mismatch: LMQTT V2.1 was compiled for TIA V17; opening it in TIA V16 produces a "type cannot be resolved" warning and the 16#80B1 error on download.
  • Firmware older than the library expects: LMQTT V2.0 requires the security patches shipped in CPU firmware V2.6+. Older firmware lacks the OPC-UA security update that LMQTT depends on.
  • Partial download: Only the program blocks were downloaded, but the type/version metadata of the FB was not refreshed.
  • Online/offline drift: A colleague changed the library on a different engineering station, but the current station still has the old .zal16 open.

9.2 Resolution Procedure

  1. In TIA Portal open Project tree → PLC → Type FB versions and compare the online and offline versions of LMQTT_Client and all referenced types.
  2. Right-click → Update type / Replace with current version to align online and offline.
  3. Right-click the CPU → Compile → Software (rebuild all blocks). This regenerates every instance DB and resets the version stamps.
  4. Perform a full download (program blocks and PLC data types). Watch the Info → Compile window for warnings.
  5. Go online, open the watch table, and confirm the difference in low-level component message is gone. LMQTT_Client.status should now return 16#0000 after the next rising edge on connect.
If the error persists after the steps above, check the CPU's Online → Diagnostics → Module information → Firmware version. A firmware update to the latest service pack within the same major version (e.g. V2.9.x) is usually sufficient and does not invalidate the TIA Portal project.

10. TLS/SSL Configuration in Detail

When useTLS := TRUE, the LMQTT library requires a separate configuration block (commonly named LMQTT_TLS_Config_DB) that holds certificates, trust chains, and cipher lists. The configuration steps are:

  1. Generate a CA and broker certificate on the Mosquitto host with openssl:
    openssl req -new -x509 -days 3650 -extensions v3_ca \
      -keyout ca.key -out ca.crt -subj "/CN=Mosquitto-CA"
    openssl genrsa -out broker.key 2048
    openssl req -new -key broker.key -out broker.csr \
      -subj "/CN=192.168.0.20"
    openssl x509 -req -in broker.csr -CA ca.crt -CAkey ca.key \
      -CAcreateserial -out broker.crt -days 3650
  2. Enable TLS in mosquitto.conf:
    listener 8883 0.0.0.0
    cafile C:/mosquitto/certs/ca.crt
    certfile C:/mosquitto/certs/broker.crt
    keyfile C:/mosquitto/certs/broker.key
    require_certificate false
    tls_version tlsv1.2
  3. Import the CA certificate into the CPU. Use the TIA Portal certificate manager (Project tree → Security → Certificates). The file format is .crt or .pem (DER or Base64). The certificate is downloaded with the project and stored in the CPU's security memory.
  4. Fill the TLS config DB with the subject name, fingerprint, and time-to-live values as described in the LMQTT reference manual. Use the certificate SHA-256 fingerprint printed by openssl x509 -fingerprint -sha256 -in broker.crt -noout.
  5. Set LMQTT_Client.useTLS := TRUE and brokerPort := 8883. Recompile and download.
PLCsim cannot test TLS. As mentioned in Section 2, PLCSim and PLCSim Advanced do not implement the security stack required for the handshake. If you must validate TLS during development, use a real S7-1500 or ET 200SP CPU on the lab bench.

11. Sample Structured-Text Implementation

The following example shows a complete OB35 call with publish-on-change and a simple ack monitoring. Adapt the fbMqtt instance DB to your project naming.

// OB35 - Cyclic 100 ms
// Trigger publish on rising edge of bTrigger
IF i_bPublishTrigger AND NOT i_bPublishTriggerOld THEN
    fbMqtt.publish := TRUE;
ELSE
    fbMqtt.publish := FALSE;
END_IF;
i_bPublishTriggerOld := i_bPublishTrigger;

fbMqtt.connect         := TRUE;
fbMqtt.brokerAddress   := '192.168.0.20';
fbMqtt.brokerPort      := 1883;
fbMqtt.clientID        := 'S7_1512SPF_01';
fbMqtt.userName        := '';
fbMqtt.userPassword    := '';
fbMqtt.keepAlive       := T#30s;
fbMqtt.cleanSession    := TRUE;
fbMqtt.useTLS          := FALSE;
fbMqtt.publishTopic    := 'siemens/line1/temp';
fbMqtt.publishMessage  := REAL_TO_STRING(fTemperature);
fbMqtt.publishQoS      := 1;
fbMqtt.publishRetain   := FALSE;
fbMqtt.subscribeTopic  := 'siemens/cmd/#';
fbMqtt.subscribeQoS    := 0;

fbMqtt();

// Mirror outputs to flags for HMI
o_bConnected := fbMqtt.connected;
o_bError     := fbMqtt.error;
o_wStatus    := fbMqtt.status;
o_bPublishOk := fbMqtt.publishDone;
o_sLastRx    := fbMqtt.receivedMessage;
IF fbMqtt.error THEN
    // optional: increase counter for diagnostics
    i_dwErrorCount := i_dwErrorCount + 1;
END_IF;

12. Verification Checklist

Walk through this list before declaring the integration complete:

# Check Pass criteria
1 Broker process is running Console line mosquitto version 2.x starting visible
2 TCP reachability from CPU Test-NetConnection from PC returns TcpTestSucceeded: True
3 LMQTT version alignment Online and offline type versions identical, no difference in low-level component
4 FB status status = 16#0000 and connected = TRUE
5 Broker log shows new client Line New client connected ... as S7_1512SPF_01
6 Publish round-trip PLC publishes, mosquitto_sub on PC prints payload
7 Subscribe round-trip mosquitto_pub triggers receivedMessage update on PLC
8 Reconnection after broker restart Within 2 x keepAlive, connected returns to TRUE without manual intervention

13. Troubleshooting Matrix

Symptom Likely cause First action
error = TRUE, status = 16#8001 Broker not running, wrong port, firewall Test-NetConnection, restart broker
error = TRUE, status = 16#8004 ACL rejects the credentials Set allow_anonymous true temporarily
error = TRUE, status = 16#80B1 Library/firmware mismatch Recompile, full download, see Section 9
Difference in low-level component warning in watch table Type FB version drift Update type, rebuild all
connected never TRUE, no error bit connect not seeing rising edge Use a one-shot (edge detection) or call FB every cycle with persistent TRUE
Messages published but not received on broker Topic filter mismatch, retain flag Compare publishTopic against mosquitto_sub -t
Broker log shows TLS alert Certificate not trusted by CPU Import CA into TIA Portal, set useTLS := TRUE

14. Operational Notes and Field-Proven Caveats

  • Single connection per instance. A single LMQTT_Client instance opens exactly one MQTT session. To use multiple topics, rely on the wildcard subscriptions (+, #) and route messages inside the PLC using receivedTopic string comparison.
  • Topic length limit. The WString[128] input for publishTopic and subscribeTopic limits topic length to 127 UTF-16 characters (plus the implicit terminator). Design your topic tree to stay under 80 characters for headroom.
  • Payload encoding. publishMessage is a UTF-16 string. To send binary or numeric payloads, use the byte-array variant of the FB or convert the value to a hex string in SCL before assigning.
  • Performance. The library runs in the user program and consumes OB runtime proportional to the message rate. With QoS 0 and messages under 256 bytes, the cycle impact is below 1 ms on a CPU 1512SPF-1. Higher QoS or larger payloads increase the time per message.
  • Firewall on CPU firmware V2.9+. If the security functions are activated, an outbound rule for TCP 1883 (or 8883) must be added under Security → Firewall in TIA Portal. Otherwise the connection is silently dropped at the CPU.
  • Broker redundancy. Mosquitto V2.x has no built-in high availability. For redundant brokers, use a third-party bridge such as HAProxy in front of two Mosquitto instances and set brokerAddress to the virtual IP.
  • Library update path. When upgrading from LMQTT V1.x to V2.x, the instance DB layout changes. Always re-create the instance after a major library upgrade, and review the new FB interface in the supplied PDF.

15. Frequently Asked Questions

Why does LMQTT_client report "difference in low-level component" even with a freshly downloaded library?

The message indicates a type-version mismatch between the compiled user program and the PLC firmware. Right-click the CPU, choose Compile → Software (rebuild all blocks), then perform a full download so that all type FBs, including the subordinate TLS/socket blocks, are refreshed on the CPU. If the warning remains, the CPU firmware is older than the library expects; update the firmware within the same major version.

Can I test LMQTT_client with PLCSim and a local Mosquitto broker?

Yes, but only with useTLS = FALSE and port 1883. PLCSim and PLCSim Advanced do not implement the full TLS stack, so any TLS configuration will fail with status 16#8003 or 16#80B1. For TLS validation, use a real S7-1500 or ET 200SP CPU on the lab bench.

Do I need additional logic on the PLC to publish or subscribe?

No extra glue logic is required for a single topic. Call the LMQTT_Client FB in a cyclic OB, set the inputs, and let the FB handle connect, publish, subscribe, and reconnection. For multiple topics, add a small router block that dispatches receivedMessage based on the receivedTopic string.

What is the default MQTT port and how do I change it?

Mosquitto's default is TCP 1883 (unencrypted) and TCP 8883 (TLS). To use a custom port, edit listener 1883 0.0.0.0 in mosquitto.conf and set the matching brokerPort input on the LMQTT_Client. Make sure the firewall on the broker host allows the chosen port.

How large can the publish payload be?

The string variant of the FB limits publishMessage to 511 UTF-16 characters (length 512). For larger payloads, switch to the byte-array variant of the FB (typically LMQTT_Client_Ext) and partition the data into multiple messages, or increase the maximum packet size on the broker via max_packet_size in mosquitto.conf.

Back to blog