
MQTT and TwinCAT
MQTT:
The Message Queuing Telemetry Transport is a lightweight, publish-subscribe network protocol that transports messages between mostly low-powered devices via an intermediate software called a broker. The protocol usually runs over TCP/IP. This is different from than client-server protocol. In client-server protocol, the client makes a request and the server responds. The MQTT protocol provides a lightweight method of carrying out messaging using a publish/subscribe model. Downloads Windows Publisher and subscriber, paho_mqtt_publisher_subscriber.zip
This makes it suitable for Internet of Things messaging such as with low-power sensors or mobile devices such as phones, embedded computers, or microcontrollers. In the very basic, a publisher (a publishing client in the system) can publish its own data to the broker. Some other interested consumers might tell the broker that we are interested in the same kinds of data, if those types of data are available then let me know. In that case, if nobody is interested in data still publisher can publish the data. On the other hand, some consumers (or subscriber client may be interested or has registered for data but there may not have any publisher, in that case, they just wait). In most cases, broker software runs in the cloud and both publisher and subscriber can access the broker and send receive a message.
Broker keeps trucks of all kinds of records like who is publishing, who is subscribing, should it remember the session if the client goes out of network, etc. In this article, we shall build a sample application using MS Windows and the Beckhoff PLC devices.
Free broker:
=> Eclipse Mosquitto is an open-source (EPL/EDL licensed) message broker that implements the MQTT protocol versions 5.0, 3.1.1, and 3.1. Mosquitto is lightweight and is suitable for use on all devices from low-power single-board computers to full servers. The Mosquitto project also provides a C library for implementing MQTT clients, and the very popular mosquitto_pub and mosquitto_sub command line MQTT clients. It also provides a free testing platform for development, more can be found at https://test.mosquitto.org/
The Mosquitto Project runs a test server at test.mosquitto.org where you can test your clients in a variety of ways: plain MQTT, MQTT over TLS, MQTT over TLS (with client certificate), MQTT over WebSockets, and MQTT over WebSockets with TLS.
=> You can download mosquitto-2.0.xx-install-windows-x64.exe (64-bit build, Windows Vista and up, built with Visual Studio Community 2019) from https://mosquitto.org/download/. You can install it to your local computer and you can access the broker with an IP 127.0.0.1. This software runs as a service on the local computer. The default port is 1883.
Test if the broker is running or not:
In separate terminal windows do the following:
Start the broker:
mosquitto
Start the command line subscriber:
mosquitto_sub -v -t 'test/topic'
Publish test message with the command line publisher:
mosquitto_pub -t 'test/topic' -m 'helloWorld'
As well as seeing both the subscriber and publisher connection messages in the broker terminal the following should be printed in the subscriber terminal:
test/topic helloWorld
EDIT:
It is worth pointing out that from v2.0.0 of Mosquitto it will only be listening for connections on the loopback interface by default. If you want to access the broker from machines other than the one it is installed on you will need to edit the config file (and pass it to the broker with the -c option e.g. mosquitto -c /path/to/mosquitto.conf) to enable listening on other interfaces.
We can check if the broker is running by looking at service as in the following image.

MQTT Windows Platform
MQTT client application development is super easy in the dot net platform. It is also very easy to test by using free eclipse foundation broker.
Before starting or trying the sample application you need to do pre work.
=>Download the Paho software from this site https://www.eclipse.org/paho/index.php?page=clients/dotnet/index.php
=>On the other hand you can download the sample from hemelix.com by the link on the right side of this page.
=>Open the solution in Visual Studio and build all.
=>We are using a Windows Form application an using the test.mosquitto.org to test our application.
=>We have added a reference to the library from M2Mqtt.Net project, the library can be found at:
 {PROJECT_FOLDER}\\paho_mqtt_publisher_subscriber\bin\Debug\M2Mqtt.Net
PROJECT_FOLDER is the root where you have installed the sample.
=>Also we need JSON parser which can be downloaded as Nuget packages. We are using Newtonsoft.Json for this.
The code snippet that connect and subscribe data from the broker.
private MqttClient client;
private string clientId;
private bool isRunning = false;
private object lockObject = new object();
private string BrokerAddress = "test.mosquitto.org";
private Thread workingThread;
public Form1()
{
  InitializeComponent();
  client = new MqttClient(BrokerAddress);
  // register a callback-function (we have to implement, see below) which is called by the library when a message was received
  client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
  // use a unique id as client id, each time we start the application
  clientId = Guid.NewGuid().ToString();
  client.Connect(clientId);
Â
client_MqttMsgPublishReceived is call back function, this is called when data is received by the subscriber client. When data is received by this subscribing client, it is converted to the Sensor class (by JSON prser) and displayed on the UI.
Â
 private void client_MqttMsgPublishReceived(object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishEventArgs e)
{
string ReceivedMessage = Encoding.UTF8.GetString(e.Message);
SensorMeasurement sensorMeasurement = JsonConvert.DeserializeObject<SensorMeasurement>(ReceivedMessage);
Â
Â
MQTT C# sample example
Download the Windows sample:
Downloads Windows Publisher and subscriber, paho_mqtt_publisher_subscriber.zip
In the sample, we have a sensor that want to publish it’s value with some interval. This is fictitious case. We have a class for this sensor as shown in the following code snippet. It has an id, publishing time and the value at that time.
  public class SensorMeasurement
  {
    public int IDSensor { get; set; }
    public DateTime Datetime { get; set; }
    public double Value { get; set; }
  }
Â
Â
When we press on the publisher button then this application will start to publish data to the cloud and when we press the subscribe button it will start to subscribe from the cloud. When data is available then it will display it to the field.

Subscription of the data:
//Publish 700 milliseconds interval
Thread.Sleep(700);
Random random = new Random();
SensorMeasurement sensorMeasurement = new SensorMeasurement();
sensorMeasurement.IDSensor = 1;
sensorMeasurement.Datetime = DateTime.Now;
sensorMeasurement.Value = Math.Round(18 + random.NextDouble() * 5, 2);
string json = JsonConvert.SerializeObject(sensorMeasurement);
client.Publish("mytopic/test", Encoding.UTF8.GetBytes(json), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, false);
Download the Windows sample:
Â
Downloads Windows Publisher and subscriber, paho_mqtt_publisher_subscriber.zip
Â
Â
How to Test the sample
=> We make sure that the broker is running in local machine at address (127.0.0.1 and port is 1883)
=> Press on the publish button in the windows application (publishing start, this is both publisher and subscriber)
=> Press on the subscribe button to subscribe the data (Now sensor data should be displayed in UI)
=> We can check also with the commercial MQTTX application (we make a connection by using Topic mytopic/test)

MQTT in Beckhoff PLC
Beckhoff has implemented the MQTT specification in the TF6701 IoT communication module. We can easily integrate their great work into our software without any pain. If you have read or tried our Windows C# client in the previous section you may have noticed that we are using test.mosquitto.org as a free broker for testing or the broker running in local machine (127.0.0.1).
We shall do the same for PLC structured text program. This PLC program will work as a publisher and subscriber and the data can be visible in TwinCAT HMI. Though we are using all in the same computer, these applications can be located on any computer anywhere in the world.
New architecture of the sample is shown in the following image. TwinCAT client (Beckhoff PLC) can publish message to the MQTT broker and Windows client (see the previous sample) can publish or subscribe the message. In addition we have added a HMI that can display the published/subscribed data to the UI as shown in the following image.

The following screenshot is showing the TwinCAT HMI, part of the PLC Program, and the Windows Client as well.

Download the sample from above link and load it in your visual studio project and see how it works in the real life.
How the sample works:
One of the main function block used in this sample is FB_IotMqttClient
The function block enables communication with an MQTT broker. A client function block is responsible for the connection to precisely one broker. The Execute() method of the function block must be called cyclically in order to ensure the background communication with this broker and facilitate receiving of messages. All connection parameters exist as input parameters and are evaluated when a connection is established.
=> Configure the client by filling the following field
  sClientId   : STRING(255);   // default is generated during initialization
  sHostName   : STRING(255) := '127.0.0.1'; // default is local host
  nHostPort   : UINT := 1883;  // default is 1883
  sTopicPrefix : STRING(255);   // topic prefix for pub and sub of this client (handled internally)
  nKeepAlive  : UINT := 60;   // in seconds
Â
  sUserName   : STRING(255);   // optional parameter
  sUserPassword : STRING(255);   // optional parameter
Â
fbJson.ResetDocument();
fbJsonDataType.AddJsonValueFromSymbol(fbJson, 'ST_Values', SIZEOF(stValues), ADR(stValues));
sJsonDocPublish := fbJson.GetDocument();
fbMqttClient.Publish( sTopic:= sTopicPub, pPayload:= ADR(sJsonDocPublish), nPayloadSize:= LEN2(ADR(sJsonDocPublish)), eQoS:= TcIotMqttQos.AtMostOnceDelivery, bRetain:= FALSE, bQueue:= FALSE );Â
=> If the document is too big we can use fbJson.CopyDocument(sTargetString, SIZEOF(sTargetString)); Where sTargetString can have any length.
The Publish method is the most important method for sending data to broker. All parameters are described below.
Â
METHOD Publish : BOOL //Publish returns TRUE if the call is successful
VAR_IN_OUT
  sTopic    : STRING; // topic string (UTF-8) with any length (attend that MQTT topics are case sensitive)
END_VAR
VAR_INPUT
  pPayload   : PVOID;
  nPayloadSize : UDINT; //reduce the size to 1 so the 00 (null char) will not go to broker side
  eQoS     : TcIotMqttQos; // quality of service between the publishing client and the broker (0 to 2)
  bRetain   : BOOL; // if TRUE the broker stores the message in order to send it to new subscribers
  bQueue    : BOOL; // for future extension
END_VAR
fbTimer(IN:=TRUE);
IF fbTimer.Q THEN // publish new payload every second
fbTimer(IN:=FALSE);
fbGetSystemTime(timeLoDW=>fileTime.dwLowDateTime, timeHiDW=>fileTime.dwHighDateTime );
    putBufMessage := CONCAT('DT#', SYSTEMTIME_TO_STRING( FILETIME_TO_SYSTEMTIME( fileTime ) ));
stValues.Datetime := STRING_TO_DT( putBufMessage );
stValues.IDSensor := 1;
stValues.Value := stValues.Value+ 0.234;
fbJson.ResetDocument();
fbJsonDataType.AddJsonValueFromSymbol(fbJson, 'ST_Values', SIZEOF(stValues), ADR(stValues));
sJsonDocPublish := fbJson.GetDocument();
fbMqttClient.Publish( sTopic:= sTopicSub, pPayload:= ADR(sJsonDocPublish), nPayloadSize:= LEN2(ADR(sJsonDocPublish)), eQoS:= TcIotMqttQos.AtMostOnceDelivery, bRetain:= FALSE, bQueue:= FALSE );Â
IF fbMqttClient.bError THEN
hrErrorOccurred := fbMqttClient.hrErrorCode;
END_IF
END_IF
Reporting:
References:
=>Â https://www.hemelix.com/automation/structured-text-mqtt-node-red-mssql/
=>Â https://mqttx.app/ (MQTTX mqtt test client)
=>Â https://www.hivemq.com/mqtt-essentials/
=>Â http://www.steves-internet-guide.com/mqtt-works/
=> https://infosys.beckhoff.com/english.php?content=../content/1033/tf6701_tc3_iot_communication_mqtt/3391835403.html&id=6531035858226877065
Download the sample from the link given above.
Next, let’s try to understand the PLC data type at https://www.hemelix.com/plc/twincat-opc-ua-server/
Ask questions related to Hemelix sample code and design at Google group https://groups.google.com/g/hemelix