MQTT With lwIP and the NXP FRDM-K64F

MQTT With lwIP and the NXP FRDM-K64F  #IoT #Cloud #BigData

  • For example, to Adafruit.IO:

    In this article, I show the basic steps to get MQTT running on the NXP FRDM-K64F board using MCUXpresso, lwIP, and MQTT.

  • Having a local broker is great for starting an MQTT project, as you can easily debug it and get things up and running with a local broker, and then you can switch to a broker/provider on the Internet.
  • I am using the MQTT.fx which has a nice GUI to monitor the broker status:

    To use MQTT.fx with Adafruit.io, see started my MQTT project from one of the lwIP example projects that come with the MCUXpresso SDK:

    And then I used the bare metal ‘ping’ example as the base:

    The example project used in this article is on GitHub.

  • From the ‘sources’ folder of that project, you need:

    The following code is a standard (bare metal) lwIP initialization:

    The MQTT application logic is implemented in the DoMQTT() function.

  • The following code shows how to connect with lwIP to the MQTT broker, adopted from the lwIP 2.0.2 code.

MQTT is a great IoT protocol. Together with the open source TCP/IP stack lwIP, you can easily connect to brokers to set up IoT communications.

@craigbrownphd: MQTT With lwIP and the NXP FRDM-K64F #IoT #Cloud #BigData

In the area of IoT, one obvious need is to have a way to send and receive data with an Internet protocol. MQTT (or Message Queue Telemetry Transport) is exactly like that: a lightweight Machine-to-Machine communication protocol. With the MQTT protocol, a microcontroller (or ‘client’) can send data and/or subscribe to data. For example, to Adafruit.IO:

In this article, I show the basic steps to get MQTT running on the NXP FRDM-K64F board using MCUXpresso, lwIP, and MQTT. lwIP is a small and open source TCP/IP stack in wide used. To keep things very simple in this first post, I’m using it in bare-metal (no RTOS) mode with no encryption/security. The principle applies to any IDE/toolchain, as long there is an lwIP port available for your board and IDE/toolchain. I’m using the MCUXpresso IDE, as it nicely integrates with the MCUXpresso SDK, which includes an lwIP port for the FRDM-K64F.

I’m using the following software and tools:

MQTT is a very cool connectivity protocol on top of TCP/IP with a subscribe/publish messaging transport. If you don’t know MQTT, then I recommend a bit of reading:

To use MQTT, I need a server or ‘broker’. Eclipse hosts the Mosquitto project, which is probably one of the most used MQTT brokers. You should be able to find plenty of tutorials about installing Mosquitto on Linux, Raspberry Pi, or even Windows.

Having a local broker is great for starting an MQTT project, as you can easily debug it and get things up and running with a local broker, and then you can switch to a broker/provider on the Internet. I have used this tutorial to install Mosquitto on Windows 10.

I love stuff from Adafruit! And they host a very useful MQTT broker.

It is very useful to have a client tool installed on the host machine. Have a read at http://www.hivemq.com/blog/seven-best-mqtt-client-tools and choose one. I am using the MQTT.fx (http://www.jensd.de/apps/mqttfx/) utility, which has a nice GUI to monitor the broker status:

I started my MQTT project from one of the lwIP example projects that come with the MCUXpresso SDK:

And then I used the bare metal ‘ping’ example as the base:

The example project used in this article is on GitHub.

From the ‘sources’ folder of that project, you need:

The following code is a standard (bare metal) lwIP initialization:

The MQTT application logic is implemented in the DoMQTT() function.

The following code shows how to connect with lwIP to the MQTT broker, adopted from the lwIP 2.0.2 code.

The address of the mqtt_client_t structure is passed from the caller:

The example above uses a static client address. The client information structure is filled with a client name, a password, and user name (both can be NULL), and then it connects to the broker with a connection callback (mqtt_connection_cb).

In the connection callback, if the connection gets accepted, it sets up three callbacks: one for the incoming publish callback (mqtt_incoming_publish_cb()), one for incoming data (mqtt_incoming_data_cb()), and one for subscription requests (mqtt_sub_request()):

Below are example implementation of the three callbacks:

/* The idea is to demultiplex topic and create some reference to be used in data callbacks Example here uses a global variable, better would be to use a member in arg If RAM and CPU budget allows it, the easiest implementation might be to just take a copy of the topic string and use it in mqtt_incoming_data_cb */ static int inpub_id; static void mqtt_incoming_publish_cb(void * arg, const char * topic, u32_t tot_len) { printf(“Incoming publish at topic %s with total length %u\n”, topic, (unsigned int) tot_len); /* Decode topic string into a user defined reference */ if (strcmp(topic, “print_payload”) == 0) { inpub_id = 0; } else if (topic[0] == ‘A’) { /* All topics starting with ‘A’ might be handled at the same way */ inpub_id = 1; } else { /* For all other topics */ inpub_id = 2; } } static void mqtt_incoming_data_cb(void * arg, const u8_t * data, u16_t len, u8_t flags) { printf(“Incoming publish payload with length %d, flags %u\n”, len, (unsigned int) flags); if (flags & MQTT_DATA_FLAG_LAST) { /* Last fragment of payload received (or whole part if payload fits receive buffer See MQTT_VAR_HEADER_BUFFER_LEN) */ /* Call function or do action depending on reference, in this case inpub_id */ if (inpub_id == 0) { /* Don’t trust the publisher, check zero termination */ if (data[len – 1] == 0) { printf(“mqtt_incoming_data_cb: %s\n”, (const char * ) data); } } else if (inpub_id == 1) { /* Call an ‘A’ function… */ } else { printf(“mqtt_incoming_data_cb: Ignoring payload…\n”); } } else { /* Handle fragmented payload, store in buffer, write to file or whatever */ } } static void mqtt_sub_request_cb(void * arg, err_t result) { /* Just print the result code here for simplicity, normal behaviour would be to take some action if subscribe fails like notifying user, retry subscribe or disconnect from server */ printf(“Subscribe result: %d\n”, result); }

To publish data, below is an example function. Replace the example topic “erichs/f/test” with your own topic.

A callback (mqtt_pub_request_cb()) is provided. In my case below, I print an error code if it fails:

With MQTT, I can publish/subscribe data on the Internet. It is lightweight, open source, and ideal for just about any IoT kind of application. But using it with the FRDM-K64F and lwIP took me a while to get things working, and I still face some issues in combination with FreeRTOS, so this is likely subject of a follow-up post. Another thing I have not covered here is the need for secure connections: Using an unencrypted MQTT port 1883 is not something to be used for sensitive data. Instead, port 8883 with SSL/TLS should be used. Yet another reason for a follow-up post, I think.

MQTT With lwIP and the NXP FRDM-K64F

You might also like More from author

Comments are closed, but trackbacks and pingbacks are open.