Skip to main content

10.3 Example Code

MQTT

4. (MessageContoh QueuingKode

Telemetry Transport) is a lightweight messaging protocol designed for constrained devices and unreliable networks, making it perfect for IoT. Instead of the request-response model, MQTT uses a publish/subscribe (pub/sub) model.

MQTT Components
  • Broker: A central server that acts as a intermediary, receiving messages from publishers and distributing them to interested subscribers

  • Client (Publisher): A device (like an ESP32 with a sensor) that publishes messages (e.g., temperature readings) to a specific "topic" on the broker. It doesn't know or care who reads the message.
  • Client (Subscriber): Another device or application (like a mobile app or a server) that subscribes to that same topic. The broker automatically forwards any message published to that topic to all subscribers.
MQTT Concepts
  • Topic: A hierarchical string that acts as a channel for messages (e.g., home/livingroom/lamp).
  • Quality of Service (QoS):
    • QoS 0 (At most once): The message is sent once ("fire and forget"). It's fast but offers no delivery confirmation.
    • QoS 4.1 (AtRoot least once)Node: The message is guaranteed to be delivered, but it might arrive more than once.
    • QoS 2 (Exactly once): The most reliable level, guaranteeing the message is delivered exactly one time. It is the slowest due to a more complex handshake.
MQTTS

Just like HTTPS, MQTTS is MQTT secured with TLS encryption to protect data confidentiality and integrity.

Example
#include <WiFi.Arduino.h>
#include <PubSubClient.painlessMesh.h>
#include <WiFi.h>

// --- ReplaceKonfigurasi with your network credentialsJaringan ---
const#define char* ssid =MESH_PREFIX     "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";jaringan_mesh_saya" // -----------------------------------------HARUS SAMA dengan semua node
#define MESH_PASSWORD   "password_mesh"      // ---HARUS MQTTSAMA Brokerdengan Configurationsemua ---node
const#define char*MESH_PORT       mqtt_server5555

=painlessMesh "broker.hivemq.com";
const int mqtt_port = 1883;mesh;

// ---Callback Topicsketika ---Root //menerima Topicpesan todari publish messages to
const char* publish_topic = "Digilab/Modul7/status"; 
// Topic to subscribe to for incoming messages
const char* subscribe_topic = "Digilab/Modul7/command"; 

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

// This function is called whenever a message arrives on a subscribed topicLeaf
void callback(char*receivedCallback(uint32_t topic,from, byte*String payload, unsigned int length)&msg) {
  Serial.print(printf("Message📩 arrivedPesan onditerima topic:dari ");node Serial.print(topic);%u: Serial.print(". Message: ");
  String message;
  for (int i = 0; i < length; i++) {
    message += (char)payload[i];
  }
  Serial.println(message);

  // Example: Turn on a built-in LED if the message is "ON"
  if (message == "ON") {
    Serial.println("Turning on lamp");
    digitalWrite(LED_BUILTIN, LOW);
  } else if (message == "OFF") {
    Serial.println("Turning off lamp");
    digitalWrite(LED_BUILTIN, LOW);
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!mqttClient.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP32Client-";
    clientId += String(random(0xffff)%s\n", HEX);from, // Attempt to connect
    if (mqttClient.connect(clientId.msg.c_str())) {
      Serial.println("connected");
      // Subscribe to the command topic upon connection
      mqttClient.subscribe(subscribe_topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);

  // ConnectInisialisasi toMesh
  Wi-Fimesh.setDebugMsgTypes(ERROR WiFi.begin(ssid,| password)STARTUP | CONNECTION);
  whilemesh.init(MESH_PREFIX, (WiFi.status(MESH_PASSWORD, MESH_PORT);

  // Set sebagai ROOT
  mesh.setRoot(true);
  mesh.setContainsRoot(true);

  // Pasang callback untuk menerima pesan
  mesh.onReceive(&receivedCallback);

  Serial.println("Mesh dimulai sebagai ROOT") != WL_CONNECTED) {
    delay(500);
  Serial.print(".Root ESP32 SoftAP IP: ");
  }
  Serial.println("\nWiFi connected!"WiFi.softAPIP();
  
  // Configure MQTT client
  mqttClient.setServer(mqtt_server, mqtt_port); 
  mqttClient.setCallback(callback));
}

void loop() {
  // Ensure the MQTT client is connected
  if (!mqttClient.connected()) {
    reconnect(mesh.update();
}

mqttClient.loop();
//

4.2 ThisLeaf allowsNode

the
#include client<Arduino.h>
to#include process incoming messages<painlessMesh.h>

// --- PublishKonfigurasi a message every 10 secondsJaringan ---
#define MESH_PREFIX     "jaringan_mesh_saya" // HARUS SAMA dengan semua node
#define MESH_PASSWORD   "password_mesh"      // HARUS SAMA dengan semua node
#define MESH_PORT       5555

painlessMesh mesh;

// Ganti sesuai nomor leaf
String leafName = "Leaf1";

void sendMessage() {
  String msg = "Hello guys im " + leafName;
  mesh.sendBroadcast(msg);
  Serial.println("Sent: " + msg);
}

void setup() {
  Serial.begin(115200);
  mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
  mesh.init(MESH_PREFIX, MESH_PASSWORD, MESH_PORT);
}

void loop() {
  mesh.update();
  static unsigned long lastMsglastSend = 0;
  unsignedif long(millis() now- lastSend > 5000) {  // kirim tiap 5 detik
    lastSend = millis();
    if (now - lastMsg > 10000) {
    lastMsg = now;
    
    char msg[50];
    snprintf(msg, 50, "Uptime: %lu seconds", millis(sendMessage() / 1000);
    
    Serial.printf("Publishing message to %s: %s\n", publish_topic, msg);
    mqttClient.publish(publish_topic, msg);
  }
}

4.3 Intermediate Parent Node

#include <Arduino.h>
#include <painlessMesh.h>

// --- Konfigurasi Jaringan ---
#define MESH_PREFIX     "jaringan_mesh_saya" // HARUS SAMA dengan semua node
#define MESH_PASSWORD   "password_mesh"      // HARUS SAMA dengan semua node
#define MESH_PORT       5555

painlessMesh mesh;

// Callback ketika node menerima pesan
void receivedCallback(uint32_t from, String &msg) {
  Serial.printf("Pesan diterima dari %u: %s\n", from, msg.c_str());
  // Intermediate node tidak perlu kirim ke server, cukup teruskan pesan
  mesh.sendBroadcast(msg);
}

// Callback saat node terhubung
void newConnectionCallback(uint32_t nodeId) {
  Serial.printf("Node baru terhubung: %u\n", nodeId);
}

// Callback saat node terputus
void changedConnectionCallback() {
  Serial.println("Perubahan koneksi terjadi!");
}

// Callback saat node time sync
void nodeTimeAdjustedCallback(int32_t offset) {
  Serial.printf("Waktu sinkronisasi, offset = %d\n", offset);
}

void setup() {
  Serial.begin(115200);

  // Inisialisasi mesh
  mesh.setDebugMsgTypes(ERROR | STARTUP);  
  mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
  
  // Callback
  mesh.onReceive(&receivedCallback);
  mesh.onNewConnection(&newConnectionCallback);
  mesh.onChangedConnections(&changedConnectionCallback);
  mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);
}

void loop() {
  mesh.update();
}

4.4 Idle Node

Gak ada kodenya karena ini cuma status aja kalo nodenya belom ke sambung sama mesh.