ESP8266 Sming framework – MQTT

The Sming framework supports the MQTT protocol out of the box. Comparing the MQTT protocol implementation on Sming with Nodemcu Lua, it appears that Sming MQTT implementation is faster and more stable and at least, in a first sight, doesn’t require any buffering code and semaphores to be implemented as I did in MQTT on Nodemcu to work.

So, out of the box code, without any other supporting code, I can have two timers “shooting” out MQTT massages at 200ms/250ms out of the ESP8266 and at the same time receiving MQTT data without losing any message! And this with the Mosquitto broker running on a low power Synology NAS ARM based device… Off course WIFI conditions are fine, but it’s an impressive achievement.
With Lua, I had to implement buffering and semaphoring for publishing, otherwise, I would get exceptions and/or loose messages.

How to start:
The Sming framework already has one example for using the MQTT protocol named MqttClient_Hello.
It is a simple example but shows all that is needed to use the MQTT protocol on the Sming Framework based code.
The API is simple, and it’s based on MqttClient object, where we define the broker address and the callback function for when receiving subscribed topics messages.

#define BROKER "192.168.1.16"   // We can use a hostname! -> "mqtt.myserver.com"
#define BRPORT 1883
#define BRUSER ""               // Empty string if broker doesn't use authentication
#define BRPWD  "pwd"

// Forward declaration, so that the compiler knows the MQTT callback function name before definition.
void onMqttReceived(String topic, String message);

// Define the MQTT object
MqttClient mqtt( BROKER , BRPORT , onMqttReceived );

As we can see the mqtt variable holds now a MQTT broker definition to be used, and also, defines the callback function that is called when a message arrives for a subscribed topic.

The sample function for displaying received messages is simple. It only prints the Topic name and message.
The function is the same for all subscribed topics, so in a real case scenario, some if/then/else logic is probably necessary.

// Callback for messages that arrived for subscribed topics
void onMqttReceived(String topic, String message)
{
	Serial.print(topic);
	Serial.print(":\r\n\t"); // Prettify alignment for printing
	Serial.println(message);
}

But after the above definition we are not still connected. To connect we need to call the connect function and define our client ID.

Connecting

The connect code is as follow:

// Connect to the MQTT broker.
// If BRUSER is not empty, connect with user and password.
void startMqttClient()
{
    String mqttID = "esp8266-" + String( system_get_chip_id() );
    if ( strlen( BRUSER ) == 0 )
	mqtt.connect( mqttID);
    else
        mqtt.connect( mqttID, BRUSER , BRPWD );
    
    // Let's subscribe topics    
    mqtt.subscribe("/status/#");
}

The mqtt.subscribe subscribes the MQTT topic passed as parameter.
Off course we can do as in the NodeMcu example, that is to define an topic array and subscribe each of the array elements.

Subscribe and unsubscribe:
After connecting we can subscribe and unsubscribe with the mqtt.subscribe( topic ) and mqtt.unsubscribe( topic ) functions. In both cases the functions receive the topic name.

As standard with MQTT we can use the # and * specifiers in topic names to subscribe one or more or zero or more.

Publishing:
There are two publishing functions, one that is the standard without Quality of Service and retention defined, and another one where we define those parameters:

  • publish( topic , value ) -> Standard publish
  • publishWithQoS( topic , value , QoS , Retain) -> Extended publish where QoS is defined and the boolean retention flag defines if the broker retains the message in case of non delivery.

The example function shows the use of the publish function, but also checks if a valid Mqtt broker connection is valid.

void publishMessage()
{
	if (mqtt.getConnectionState() != eTCS_Connected)
		startMqttClient(); // Auto reconnect

	Serial.println("Let's publish message now!");
	mqtt.publish("/sming", "Published! :)");
}

Testing:
My testing was done using the Mqtt-Spy tool for monitoring the messages published by the ESP8266, and a simple script that run on the broker machine that mass flood the subscribed topics…
Since I have the broker running on the Synology NAS, that as the ash shell, such script is as follows:

for i in `seq 500` ; do
 /volume1/@appstore/mosquitto/bin/mosquitto_pub -m "Hi there" -t "/status/sming"
done

At the same time I’ve changed the Sming example code for publish in two different topics:


int mq1 = 0;
int mq2 = 200;

Timer pub1;
Timer pub2;

void pubMqtt1() {
     	if (mqtt.getConnectionState() != eTCS_Connected)
		startMqttClient(); // Auto reconnect
    
        mq1 ++;
        if ( mq1 > 100 ) mq1 = 0;

        mqtt.publish("/data1", String(s));
}

void pubMqtt2() {
 	if (mqtt.getConnectionState() != eTCS_Connected)
		startMqttClient(); // Auto reconnect
    
        mq2 ++;
        if ( mq2 > 250 ) mq2 = 200;
    
        
        mqtt.publish("/data2", String(s));
}

....
....
// Will be called when WiFi station was connected to AP
void connectOk()
{
	Serial.println("I'm CONNECTED");

	// Start the MQTT client and subscribe to any topics
	startMqttClient();

	// Start publishing loop
	procTimer.initializeMs(20 * 1000, publishMessage).start(); // every 20 seconds
        
        pub1.initializeMs(200, pubMqtt1).start(true); // True is default , repeat timer.
        pub2.initializeMs(250, pubMqtt2).start(true);
}

....

So with above code that publish on two topics at very short intervals and with the Mosquitto server loop based script that also publishes data subscribed by the Sming framework, I’ve not witness any drops or failures that I’m aware off. Impressive.

Off course in other environments the results can be different, but the code is simple and needs no work arounds to be effectively used.

Advertisements

One thought on “ESP8266 Sming framework – MQTT

  1. Pingback: Sming – MQTT (part 2) | Primal Cortex's Weblog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s