Skip to main content

Learning MQTT

·591 words·3 mins
C C++ IoT Electronics
Luĉjo
Author
Luĉjo
Studento kaj via loka esperantisto
Table of Contents

Last week I parttook in the BIP week in Novi Sad and learned some of the practical aspects of networking in embedded systems which is instrumental for internet of things.

Novi Sad
#

Novi Sad is a very beautiful city with a distinctly Austro-Hungarian architecture, which makes it very distinct from other cities in Serbia 🇷🇸

MQTT
#

MQTT is a light-weight protocoll for exchanging messages between low-resource and low-bandwidth devices - even when the network connection is unreliable. It offers the user a bidirectional communication based on TCP.

MQTT works over a Wi-Fi connection and it involves a MQTT broker (or server node) and many clients. Every client can publish (send) messages. A message is composed of two parts:

  • Topic (for example house/temperature)
  • Payload (for example 19.92C)

The MQTT Broker receives the message and then transports it to every other device, which is subscribed to the topic name.

On Linux it is possible to install the MQTT broker in the following way:

sudo apt-get install mosquitto -y
sudo apt-get install mosquitto-clients -y

but you also need to modify the following file located in /etc/mosquitto/conf.d for a easy usage of MQTT:

allow_anonymous true
listener 1883

and you should be done! In case you want to listen to the topic topic_name you can run:

mosquitto_sub -h 0.0.0.0 -d -u mqtt -P mqtt -t topic_name

where 0.0.0.0 means reading topics from all IP-addresses and if you wish to publish something to a topic yourself you can run:

mosquitto_sub -h addr -d -u mqtt -P mqtt -t topic_name -m "Saluton!"

where addr is the address of your broker (typically your PC - on Linux you can find out the IP address using ip addr). I think it’s a great idea to test your MQTT broker with another PC.

Atentu! You need to adjust your firewall settings for MQTT to work properly

On your microcontroller which supports Wi-Fi you can run the following code to create a client, which can send data to your broker in order to check if everything works. Do make sure that all devices are connected to the same Wi-Fi connection.

#include <SPI.h>
#include <WiFi.h>
#include <PubSubClient.h>

IPAddress server(192, , , ); // Enter the broker IP
String clientId;

const char* ssid = "wifinetwork"; // Enter your Wi-Fi name
const char* password = "wifipassword"; // Enter Wi-Fi password

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

WiFiClient ethClient;
PubSubClient client(ethClient);

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("...Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("...Connecting to WiFi...");
  }
  Serial.print("Connected to the WiFi AP. My address is: ");
  Serial.println(WiFi.localIP());
  String client_id = "esp32-client-";
  client_id += String(WiFi.macAddress());
  Serial.printf("The client %s connects to the MQTT broker\n", client_id.c_str());

  client.setServer(server, 1883);
  client.setCallback(callback);

  // Allow the hardware to sort itself out
  delay(1500);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  // Read from serial and send over MQTT
  if (Serial.available() > 0) {
    String message = Serial.readStringUntil('\n');
    client.publish("outTopic", message.c_str());
  }
}

Using MQTT my team then made a small multiplayer F1-themed reaction game on the hardware that was provided to use (ESP32) to demonstrate how the protocol works:

Reply by Email