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).
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 |
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
- Open the Siemens Support search page and search for entry ID 109771836 ("Library for MQTT (LMQTT) – for S7-1500 and ET 200SP"). Download the
.zipmatching your TIA Portal major version. - Extract the archive. You will find global library files such as
LMQTT_V2_0_x.zal16and accompanying PDFs describing the FB interfaces. - In TIA Portal, choose Options → Global libraries → Open library and select the
.zal16file. - Drag the
LMQTT_Clienttype from the Master copies pane into your project tree under Program blocks → Types. - 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
- 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.
- Run the installer with administrator rights. The default install path is
C:\Program Files\mosquitto\. - 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 - Add the install directory to the system
PATHenvironment 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
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/24for the CPU,192.168.0.20/24for 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
-
Create a new cyclic OB (e.g.
OB1or a dedicatedOB35at 100 ms). Declare a single instance DB ofLMQTT_Clientand assign all input parameters in the call interface as shown below. -
Wire the input parameters with constants, tags, or HMI fields. Begin with unencrypted settings:
brokerPort := 1883,useTLS := FALSE,userName := "",userPassword := ""(matchesallow_anonymous true). -
Start the broker using the custom config file:
Thecd "C:\Program Files\mosquitto" mosquitto -c C:\mosquitto\config\mosquitto_plc.conf -v-vflag enables verbose logging in the console window; useful during commissioning. - Compile and download the TIA Portal project to the CPU. Perform a warm restart to ensure the OB is executed.
-
Trigger the connection by setting
connect := TRUE. The FB requires a rising edge; if the input staysTRUEthe FB handles reconnection automatically on error. -
Observe the FB outputs in the watch table or HMI:
-
connectedshould toggle toTRUEwithin 1–3 seconds. -
errorshould remainFALSE. -
statusshould read16#0000.
-
-
Verify from the broker side in the Mosquitto console window. You should see a line similar to:
The token1719287923: 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).c1means clean session = 1,k30means keep-alive = 30 s. -
Publish a test message by pulsing
publishfor one OB cycle. ThepublishDoneoutput acknowledges a successful QoS-1 acknowledgement from the broker. -
Subscribe and receive by setting
subscribeTopic := "siemens/cmd/#"and pulsingsubscribe. Any matching message published bymosquitto_pubappears atreceivedTopicandreceivedMessage.
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#80B1error 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
.zal16open.
9.2 Resolution Procedure
- In TIA Portal open Project tree → PLC → Type FB versions and compare the online and offline versions of
LMQTT_Clientand all referenced types. - Right-click → Update type / Replace with current version to align online and offline.
- Right-click the CPU → Compile → Software (rebuild all blocks). This regenerates every instance DB and resets the version stamps.
- Perform a full download (program blocks and PLC data types). Watch the Info → Compile window for warnings.
- Go online, open the watch table, and confirm the difference in low-level component message is gone.
LMQTT_Client.statusshould now return16#0000after the next rising edge onconnect.
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:
-
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 -
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 -
Import the CA certificate into the CPU. Use the TIA Portal certificate manager (Project tree → Security → Certificates). The file format is
.crtor.pem(DER or Base64). The certificate is downloaded with the project and stored in the CPU's security memory. -
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. - Set
LMQTT_Client.useTLS := TRUEandbrokerPort := 8883. Recompile and download.
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_Clientinstance opens exactly one MQTT session. To use multiple topics, rely on the wildcard subscriptions (+,#) and route messages inside the PLC usingreceivedTopicstring comparison. -
Topic length limit. The
WString[128]input forpublishTopicandsubscribeTopiclimits topic length to 127 UTF-16 characters (plus the implicit terminator). Design your topic tree to stay under 80 characters for headroom. -
Payload encoding.
publishMessageis 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
brokerAddressto 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.