ESP32 Communication Protocol – MQTT

Pendahuluan

Message Queue Telemetry Transport (MQTT) adalah many-to-many communication protocol dimana message broker sebagai mediator. Terdapat publishers yang berfungsi mengirim messages ke topic pada broker, dan ada subscribers, yang menerima messages dari topics yang mereka subscribe. Sebuah node dapat berfungsi sebagai publisher dan subscriber secara bersamaan.

MQTT menggunakan TCP sebagai transport protocol dan menggunakan TLS untuk communication security.

Topics adalah cara kita mengorganisasi information dalam MQTT. Berikut beberapa aturan dan best practice mengenai topics:

  • / (slash) adalah level separator. Kita tidak mulai dengan / untuk memberi nama sebuah topic (karena akan menambahkan level yang tidak diperlukan).
  • + (plus) adalah single-level wildcard. Agar jelasnya kita langsung gunakan contoh, ketika kita subscribe home/+/light, kita akan menerima semua topic yang sesuai dengan pattern, misalnya home/kitchen/light atau home/bedroom/light.
  • # (sharp) adalah multi-level wildcard dan hanya dapat digunakan diakhir. Akan matches semua topic pada level tersebut dan dibawahnya.
  • Topic names tidak bolah mengandung space atau non-printable characters.
  • Penamaan dan levels tergantung dari context.
  • IoT protocols with ESP32 30

Persiapan Project

Pada aplikiasi kali ini kita akan menggunakan sensor DHT11. Aplikasi akan publish data temperature dan humidity sebagai topics terpisah pada MQTT broker.

Untuk keperluan modul ini, diperlukan Eclipse Mosquitto, yaitu MQTT message broker. Silakan download di https://mosquitto.org/download

Untuk sensor DHT11 hubungkan ke GPIO17 pin pada ESP32 Devkit.

Buat project baru, lalu ubah platformio.ini seperti berikut: (gunakan path tempat anda menyimpan library.

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = espidf

monitor_speed = 115200
lib_extra_dirs = 
    ../esp-idf-lib/components
    ../common
build_flags =
    -DWIFI_SSID=${sysenv.WIFI_SSID}
    -DWIFI_PASS=${sysenv.WIFI_PASS}
    -DMQTT_BROKER_URL=${sysenv.MQTT_BROKER_URL}

Kemudian download library https://drive.google.com/file/d/1_zAaUaJJY22HuVUk6Ora1vhLfPdjkOI-/view?usp=sharing, extract dan simpan didirectory common (sesuai dengan directory yang ditulias pada platformio.ini).

Library diatas akan beris file header untuk sensor DHT11 dan WiFi Connect.

Buka platformio CLI, kemudian definsikan environment variable: (ganti export dengan set untuk windows platform).

(penv)$ export WIFI_SSID='\"<your_ssid>\"'
(penv)$ export WIFI_PASS='\"<your_pass>\"'

Code

Setelah persiapan diatas selesai, kita lakukan coding dengan membuka file main.c, lalu gunakan code dibawah:

//import library dan variable init
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

#include "mqtt_client.h"

#include "app_temp.h"
#include "app_wifi.h"

#define TAG "app"

//#ifndef MQTT_BROKER_URL
#define MQTT_BROKER_URL "mqtt://localhost"
//#endif

#define SENSOR_NO "1"
#define ENABLE_TOPIC "home/" SENSOR_NO "/enable"
#define TEMP_TOPIC "home/temperature/" SENSOR_NO
#define HUM_TOPIC "home/humidity/" SENSOR_NO

static esp_mqtt_client_handle_t client = NULL;
static bool enabled = false;

// fungsi publish reading
static void publish_reading(int temp, int hum)
{
    char buffer[5];

    if (client != NULL && enabled)
    {
        esp_mqtt_client_publish(client, TEMP_TOPIC, itoa(temp, buffer, 10), 0, 1, 0);
        esp_mqtt_client_publish(client, HUM_TOPIC, itoa(hum, buffer, 10), 0, 1, 0);
    }
}

//fungsi handle mqtt events
static void handle_mqtt_events(void *handler_args,
                               esp_event_base_t base,
                               int32_t event_id,
                               void *event_data)
{
    esp_mqtt_event_handle_t event = event_data;

    switch ((esp_mqtt_event_id_t)event_id)
    {
    case MQTT_EVENT_CONNECTED:
        ESP_LOGI(TAG, "mqtt broker connected");
        esp_mqtt_client_subscribe(client, ENABLE_TOPIC, 0);
        break;
    case MQTT_EVENT_DATA:
        if (!strncmp(event->topic, ENABLE_TOPIC, event->topic_len))
        {
            enabled = event->data[0] - '0';
        }
        break;
    case MQTT_EVENT_ERROR:
        ESP_LOGE(TAG, "errtype: %d", event->error_handle->error_type);
        break;
    default:
        ESP_LOGI(TAG, "event: %d", event_id);
        break;
    }
}

//fungsi handle wifi connect
static void handle_wifi_connect(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {
        .uri = MQTT_BROKER_URL
    };
    client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, handle_mqtt_events, NULL);
    esp_mqtt_client_start(client);
    apptemp_init(publish_reading);
}

//fungsi handle wifi failed
static void handle_wifi_failed(void)
{
    ESP_LOGE(TAG, "wifi failed");
}

//main function
void app_main()
{
    esp_event_loop_create_default();

    connect_wifi_params_t cbs = {
        .on_connected = handle_wifi_connect,
        .on_failed = handle_wifi_failed};
    appwifi_connect(cbs);
}

Penjelasan Code

Bagian Import Library dan variable init

KIta include header files yang diperlukan. Header file untuk MQTT library adalah mqtt_client.h.

Kemudian kita definisikan global variable.

Kita cadangkan MQTT topic untuk enable atau disable sensor device. Sensor akan melakuka subscribe topic.

ENABLE_TOPIC, untuk set/reset enabled global variable. Ketika enabled, sensor device akan publish ke TEMP_TOPIC dan HUM_TOPIC, dan client lainnya didalam network dapat subscribe topik ini untuk mendapatkan informasi.

Bagian Main Function

Oertama kita buat default event loop untuk menerima MQTT events. Kemudian kita panggil appwifi_connect untuk connect ke local Wi-Fi.

Bagian Wifi Connect

Ketika WiFi terhubung, kita init MQTT client dan register MQTT event handler function, handle_mqtt_events.

Kita jalankan MQTT client untuk connect ke broker dengan memanggil esp_mqtt_client_start.

Terakhir, kita init DHT11 readings dengan publish_reading sebagai callback function.

Bagian handle MQTT event

Event pertama adalah MQTT_EVENT_CONNECTED, dimana kita akan subscribe ENABLE_TOPIC untuk mendengarkan messages untuk enable/disable sensor commands.

Ketika MQTT_EVENT_DATA terjadi, berarti kita menerima message dari topic. Pada kasus kita hanya memiliki satu topic.

Event terakhir adalah MQTT_EVENT_ERROR. Disini kita akan print error type ke serial console.

Bagian publish reading

Untuk publish message, kita panggil esp_mqtt_client_publish. Diperlukan parameter MQTT client, topic name, dan data untuk dipublish.

Untuk parameter quality of service (QoS) terdapat tiga pilihan:

  • QoS level-0: no delivery guarantee to subscribers. subscribers tidak harus melakukan acknowledge receipt message.
  • QoS level-1: Guarantees delivery, namun subscribers dapat menerima beberapa copy message.
  • QoS level-2: Subscribers hanya menerima persis satu copy dari message.

Untuk menggunakan QoS, sesuaikan dengan kebutuhan aplikasi. Contoh, jika tidak masalah ada pembacaaan yang terlewat, kita dapat gunakan QoS-0.

QoS-1 dan QoS-2 memerlukan extra message yaitu ACK, dimana akan menambah overhead pada jalur komuniskasi.

Compile, Upload dan Test

Sampai disini kita sudah selesai membuat code.

Berikutnya kita akan mempersiapkan Mosquitto.

Untuk testing, Mosquito sebagai broker, publisher dan subcriber client (link download adal pada awal modul ini).

Buka command prompt, lalu jalankan mosquito.

Kemudian buka command prompt, lalu jalankan mosquitto untuk listening:

$ mosquitto_sub -h localhost -t home/test

Buka command promp baru, lalu jalankan untuk publishing:

$ mosquitto_pub -h localhost -t home/test -m "test message"

Jika Anda melihat message pada window command prompt subcriber, maka mosquito sudah berjalan dengan baik. Berikutnya kita test dengan aplikasi ESP32.

Anda bisa tutup 2 window command prompt untuk publish dan subcribe, tapi window yang menjalankan mosquitto service harus tetap berjalan.

Lalu buka command promt baru, lalu jalankan perintah berikut

$ mosquitto_sub -h localhost -t "home/+/1" -d

Kembali ke visual studio code, lalu pada platformIO CLI, jalankan perintah

(penv)$ pio run -t upload && pio device monitor

Kemudian pada command prompt baru, jalankan perintah mosquitto untuk enable sensor.

mosquitto_pub -h localhost -t home/1/enable -m "1"

Sampai disini kita sudah selesai membahas penggunaan MQTT communication protocol.

Pada modul selanjutnya kita akan bahas CoAP comm protocol.

Sharing is caring:

Leave a Comment