Getting started

This documentation article is intended to allow you an initial, quick start in how to use this product. After the successful Installation and Licensing, perform the following steps in order to connect to an MQTT Message Broker and send and receive messages.

Getting started 1:

Message Broker installation

This document requires the presence of a locally installed and functional MQTT Message Broker. As an example we use the Mosquitto Message Broker here, but you can use any message broker you like.

Message Broker setup

The Mosquitto Message Broker has been shipped since version 2.x with a configuration that requires security measures to be set up to ensure secure operation of the message broker. In the following, we will show you how to modify the Mosquitto Message Broker configuration so that an unsecured communication connection can be established with the broker. However, this should be done exclusively for testing purposes in a trusted operating environment. For productive operation, we recommend using a secure broker configuration.

1. Install the Mosquitto Message Broker on your system.
2. Make a backup of the mosquitto.conf file from the Mosquitto installation directory. This is typically located at C:\Program Files\mosquitto.
3. Open the mosquitto.conf file with a text editor of your choice and remove the existing content. Add the following content and save the file.

listener 1883
allow_anonymous true

4. Restart the Mosquitto Message Broker, either via the corresponding Windows service or manually via the console or mosquitto.exe.
You have now configured the Mosquitto Message Broker to listen for incoming client connections on port 1883 and it does not require any security (neither user authentication nor client certificates).

You can now start setting up the TwinCAT project.

Setup of the TwinCAT project

After you have installed the message broker, you can now start setting up the TwinCAT project to connect to the broker and exchange messages via it.

1. Create a TwinCAT project with a PLC and add Tc3_IotBase as library reference.
2. Create a program block and create an instance of FB_IotMqttClient in the declaration part as well as two auxiliary variables to control the program flow if needed.
PROGRAM PrgMqttCom
VAR
    fbMqttClient    : FB_IotMqttClient;
    bSetParameter   : BOOL := TRUE;
    bConnect        : BOOL := TRUE;
END_VAR
3. Declare two variables (for topic and payload) for the MQTT message to be sent. In the sample, a message is to be sent every second, which is to be realized via a corresponding timer function block. A counter variable is to be used later for the message content.
    (* published message *)
    sTopicPub   : STRING(255) := 'MyTopic';
    sPayloadPub : STRING(255);
    fbTimer : TON := (PT:=T#1S);
    i : UDINT;
4. For each message receive operation a variable containing the topic to be received should be declared, plus two further variables indicating the topic and payload of the last received message. The received messages are to be collected in a queue in order to be evaluated sequentially. For this you declare an instance of FB_IotMqttMessageQueue and an instance of FB_IotMqttMessage.
    (* received message *)
    bSubscribed    : BOOL;
    sTopicSub      : STRING(255) := 'MyTopic';
    {attribute 'TcEncoding':='UTF-8'}
    sTopicRcv      : STRING(255);
    {attribute 'TcEncoding':='UTF-8'}
    sPayloadRcv    : STRING(255);
    fbMessageQueue : FB_IotMqttMessageQueue;
    fbMessage      : FB_IotMqttMessage;
5. In the program part, the MQTT client must be triggered cyclically, in order to ensure that a connection to the broker is established and maintained and the message is received. In this sample, the connection parameters are assigned once in the program code before the client call. Since this is usually only required once, the parameters can already be specified in the declaration part during instantiation of the MQTT client. Not all parameters have to be assigned. In our sample the broker is installed locally on the same system on which you want to activate the PLC project. Alternatively, you can specify the IP address or host name of the system on which the message broker was installed.
IF bSetParameter THEN
    bSetParameter               := FALSE;
    fbMqttClient.sHostName      := 'localhost';
    fbMqttClient.nHostPort      := 1883;
    fbMqttClient.ipMessageQueue := fbMessageQueue;
END_IF
fbMqttClient.Execute(bConnect);
6. The cyclic call of the MQTT client ensures that the messages are received. The client receives all messages with topics to which it has previously subscribed with the broker (see next step) and places them in the message queue. Once messages are available, call the method Dequeue() to gain access to the message properties such as topic or payload via the message object fbMessage. In the following implementation of message evaluation, one received message is evaluated per cycle. If several messages were accumulated in the message queue, the evaluation is distributed over several cycles.
IF fbMessageQueue.nQueuedMessages > 0 THEN
    IF fbMessageQueue.Dequeue(fbMessage:=fbMessage) THEN
        fbMessage.GetTopic(pTopic:=ADR(sTopicRcv), nTopicSize:=SIZEOF(sTopicRcv) );
        fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=FALSE);
    END_IF
END_IF
7. As soon as the connection to the broker is established, the client should subscribe to a particular topic. A message should be sent every second. In this sample, sTopicPub = sTopicSub, so that a loopback occurs and the sent messages are received right back. In other applications the topics usually differ.
IF fbMqttClient.bConnected THEN
    IF NOT bSubscribed THEN
        bSubscribed := fbMqttClient.Subscribe(sTopic:=sTopicSub, eQoS:=TcIotMqttQos.AtMostOnceDelivery);
    END_IF
    fbTimer(IN:=TRUE);
    IF fbTimer.Q THEN // publish new payload every second
        fbTimer(IN:=FALSE);
        i := i + 1;
        sPayloadPub := CONCAT('MyMessage', TO_STRING(i));
        fbMqttClient.Publish(sTopic:= sTopicPub, pPayload:= ADR(sPayloadPub), nPayloadSize:= LEN2(ADR(sPayloadPub))+1, eQoS:= TcIotMqttQos.AtMostOnceDelivery, bRetain:= FALSE, bQueue:= FALSE );
    END_IF
END_IF

Next steps

Now that you have successfully connected to the message broker, we recommend that you reset the Mosquitto Message Broker to its delivery state. For this, please take the backup file of mosquitto.conf that you created in the previous steps. This file, together with the broker documentation, is a good basis for further steps, e.g. to set up a secure message broker operating environment considering client/server certificates and user authentication.

In the above sample, we have sent or received a string variable as the payload of the message. Since the data format is not specified for MQTT, you are free to decide how this should be structured. However, typical IoT applications use a JSON or XML-based data format. For this purpose, Beckhoff provides the PLC library Tc3_JsonXml, which you can use to create and read JSON and XML documents.