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

 Download the TwinCAT sample to see how the MQTT work in structured text programming Mqtt_Beckhoff_hemelix.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.

 

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

 

 

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.

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

=> Call the method Execute to connect with the broker with a parameter TRUE, This method must be called cyclically in order to ensure the background communication with the MQTT broker.
=> If the Execute method fails for any reason, then bError field of FB_IotMqttClient is set to TRUE and hrErrorCode will provide the error code.
=> FB_JsonSaxWriter object is used to create the JSON string from the STRUCT or we can build the JSON string automatically.

 

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

 

Publish

BOOL

The method returns the return value TRUE if the call was successful.

Introduction to MQTT from HiveMQ (Online resources)