Module 10 - Mesh

10.1 Introduction

Module 10: Mesh

Author: YP

Learning Objectives

After completing this module, students are expected to be able to:

10.2 What is Mesh?

10.2.1 What is a Mesh Network?

image

A mesh network is a topology where each device (node) is interconnected, creating multiple paths for data. Unlike traditional networks that rely on a single central point (such as a router), a mesh network is decentralized.

How It Works

In a mesh network, each ESP32 node acts as both a sender and receiver, functioning as a repeater. This differs from a star network where communication only goes through one central hub. A mesh network is more decentralized, thus improving coverage and network reliability.

In this setup, one ESP32 acts as the root node, which connects the mesh network to an external network, while other nodes can serve as intermediate parents that forward data or as leaf nodes that only send and receive their own data. Data in the network is automatically routed through available nodes until it reaches the final destination, either another node within the mesh or an external network via the root node. This creates an efficient, flexible, and fault-tolerant network.

Key characteristics include:


10.2.2 Topology Comparison: Mesh vs. Star

To understand the advantages, let’s compare it with the commonly used Star topology in home Wi-Fi.

Component Mesh Topology Star Topology
Resilience Very High. Supports self-healing. Low. If the hub/router fails, the entire network fails.
Coverage Wide and flexible. Easy to expand. Limited by the hub/router’s range.
Complexity More complex to configure. Simple and easy to set up.

10.2.3 Types of Nodes in a Mesh Network

In this lab, we will learn about 4 types of nodes:

10.3 Example Code

10.3.1 Root Node

#include <Arduino.h>
#include <painlessMesh.h>
#include <WiFi.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 Root menerima pesan dari Leaf
void receivedCallback(uint32_t from, String &msg) {
  Serial.printf("Pesan diterima dari node %u: %s\n", from, msg.c_str());
}

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

  // Inisialisasi Mesh
  mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
  mesh.init(MESH_PREFIX, 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");
  Serial.print("Root ESP32 SoftAP IP: ");
  Serial.println(WiFi.softAPIP());
}

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

10.3.2 Leaf 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;

// 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 lastSend = 0;
  if (millis() - lastSend > 5000) {  // kirim tiap 5 detik
    lastSend = millis();
    sendMessage();
  }
}

10.3.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();
}

10.3.4 Idle Node

There is no code because this is just a status if the node is not yet connected to the mesh.