/ Hardware

MQTT with LPC4337 and Keil MDK

Despite the busy week I had, I got some little time to write this as my main machine performed an update. You know those windows 10 updates you leave to run overnight...

Anyway, this is the fourth post of the series/tutorial. In case you have not gone through the other posts, you can do so now.
Post #1: SIM900 Dialup Connection Setup
Post #2: SIM900 PPP Driver for KEIL Network-DS
Post #3: Choosing the protocol and why I chose MQTT

This post will also be very short (or so I hope).
Setting up MQTT in your Keil MDK project is very easy especially for the Eclipse Paho client for C. I did this in one git commit. You will notice that of the three flavors available, I chose the MQTTPacket because it is lightweight. The other flavors required some more work. Setting the timing parts for the MQTTClient, required understanding the library perfectly to work it out. One requires the timing to work if you need to subscribe to a topic or if you need the broker to confirm delivery (QoS 2 or QoS 1). For the basic proof of concept, QoS 1 works fine. It means I need no response from the broker.

If the term broker or subscribing to a topic is not familiar, I recommend the links for further reading in the [previous post (Post #3)](Choosing the protocol and why I chose MQTT](/communication-protocols-for-embedded-application-and-why-i-chose-mqtt/).

The second git commit had changes in only 3 files. My interest is the file named CommunicationThread.c.

After determining the IP address of the host as we had in Post #2, we send a report as a means of testing MQTT. The exact method execution is towards the end of the file line numbers 122-152.

You will notice some functions that may look strange.
transport_open, transport_sendPacketBuffer and transport_close are functions prototyped in mqtt_keilds_transport.h and implemented in mqtt_keilds_transport.c. These functions are in charge of getting the IP address for a host name, opening a TCP connection, sending data via a TCP connection and closing a TCP connection. I already did discuss this earlier.

There're some variables above the SendReport function, which is of interest too.

MQTT Broker

In the code I used a public broker. The host name is "m2m.eclipse.org:1883" (unencrypted traffic). You should only use this for test and sensitive data should not be sent since so many other people can be listening. Consider the use of a # to capture all topics. What if someone is listening?

The topic

You really can set this to anything but remember, when using a public broker, you need to make it unique otherwise you will get a lot of messages and not tell which one is the one you sent unless you look at the payload. In my case I set it to "devices/{device-id}/telemetry" as shown.
Remember the topic because you will need to listen to it on another client (say a desktop computer). In the latter, it will be easy to listen to "device/#/telemetry".

The other variables

Of course, I did not make the library, I just showed how to use it. That means that the rest of the stuff remains largely the same as in the sample given for MQTTPacket and I see no need to mention any details.

The big catch

The code is working alright but you may not work as expected with the public broker. These brokers may be overloaded and not deliver. They are prone to misuse and thus not reliable for anything than testing. You may be quick to say that you can do it with a broker hosted in your localhost. Well, you are right but getting that to work with a PPP connection over a GSM/GPRS modem is too much work to do. I find it easier to setup my own broker in the cloud. Using the localhost option is very viable and an obvious option if you use a wired ethernet connection (note: still never got mine to work, maybe yours will).

Setting up your own broker is very easy and can cost you as little as $15/month on Azure. I think that qualifies for a separate post.

Happy hacking :-)