ESP8266 Arduino IDE – Mesh network dengan PainlessMesh

Hallo Warrior, pada pembahasan ini kita akan membahas mengenai salah satu implementasi dari Mesh Network pada NodeMCU/ESP8266 menggunakan library PainlessMesh. Disini kita akan coba mengguakan program sederhana dimana setiap node nantinya akan mendeteksi node yang lainnya dengan led sebagai indikatornya.

Introduction

Apa itu Mesh Network ?

Mesh Network/Topologi mesh merupakan sebuah bentuk dari topologi jaringan komputer yang menghubungkan antara satu node degan node lainnya, didalam jaringan tersebut. Hubungan antar node ini akan membentuk sebuah rangkaian yang menyerupai jaring (Dini S.Kom, DosenIT)

Contoh Jaringan Mesh
Contoh Jaringan Mesh

Topologi ini tidak membutuhkan dedicated links (perantara), setiap node akan saling berhubungan satu sama lainnya sehingga pada waktu yang sama akan terbentuk sebuah komunikasi langsung. Dikarenakan Komunikasinya terhubung secara langsung, maka apabila ada satu node yang mati, maka tidak akan berpengaruh pada node yang lainnya.

Ilustrasi satu node mati
Ilustrasi satu node mati

Dengan begini sistem komunikasi akan tetap terus berjalan dengan lancar dengan memanfaatkan node lain yang masih terhubung dengan jaringan yang sama.

Konsep Percobaan

Kita sudah mengulas sedikit mengenai topologi mesh tersebut, sekarang kita akan coba untuk membuat sebuah jaringan mesh dengan menggunakan NodeMCU/ESP8266 dan Library Painlessmesh.

Kita akan coba menggunakan program sederhana yaitu StartHere, dimana program ini nantinya akan menjalankan mesh, dan menghidupkan indikator led gpio 2 pada nodemcu ketika ada node lain yang terhubung. Sehingga led akan berkedip sesuai dengan jumlah node yang ada.

Berikut merupakan ilustrasi konsep yang akan dibuat pada percobaan ini.

Ilutrasi Mesh ESP8266
Ilutrasi Mesh ESP8266

Pada ilustrasi tersebut bisa kita lihat ada 3 node yang nanti akan dimatikan satu persatu sehingga led akan menentukan jumlah node nya.

Praktek

Persiapan Perangkat

Berikut merupakan beberapa perangkat yang kita butuhkan untuk percobaan ini :

  1. NodeMCU/ESP8266 x 3 pcs
  2. Library PainlessMesh yang sudah terintall (Download Disini)

Apabila kalian kesulitan untuk menambahkan library di Arduino IDE, kalian dapat mengikuti panduan berikut : Cara menambahkan library di Arduino IDE.

Sketch Program

#include <painlessMesh.h>

// Define Pin GPIO dengan nama -----------------------------------
#define LED  2   //GPIO untuk blink

// Define untuk timing led indikator -----------------------------
#define   BLINK_PERIOD    3000 // milliseconds until cycle repeat
#define   BLINK_DURATION  100  // milliseconds LED is on for

// Define untuk koneksi dan port jaringan ------------------------
#define   MESH_SSID       "warriornux.com"
#define   MESH_PASSWORD   "1234567890"
#define   MESH_PORT       5555

// Prototypes ----------------------------------------------------
void sendMessage(); 
void receivedCallback(uint32_t from, String & msg);
void newConnectionCallback(uint32_t nodeId);
void changedConnectionCallback(); 
void nodeTimeAdjustedCallback(int32_t offset); 
void delayReceivedCallback(uint32_t from, int32_t delay);

// Mengontrol Personal Task dan memanggil library painlessmesh ---
Scheduler     userScheduler;
painlessMesh  mesh;

bool calc_delay = false;
SimpleList<uint32_t> nodes;

// Mejalankan perintah untuk mengirim pesan ----------------------
void sendMessage() ; // Prototype
Task taskSendMessage( TASK_SECOND * 1, TASK_FOREVER, &sendMessage ); // start with a one second interval

// Task untuk menjalankan indikator sesuai jumlah node -----------
Task blinkNoNodes;
bool onFlag = false;

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

  pinMode(LED, OUTPUT);

// Untuk menampilkan log pesan mesh di serial --------------------
  mesh.setDebugMsgTypes(ERROR | DEBUG | CONNECTION);  // set before init() so that you can see startup messages

// Menjalankan Program dari Mesh Network --------------------------
  mesh.init(MESH_SSID, MESH_PASSWORD, &userScheduler, MESH_PORT);
  mesh.onReceive(&receivedCallback);
  mesh.onNewConnection(&newConnectionCallback);
  mesh.onChangedConnections(&changedConnectionCallback);
  mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);
  mesh.onNodeDelayReceived(&delayReceivedCallback);

// Mengaktifkan Schedule untuk mengirim pesan ---------------------
  userScheduler.addTask( taskSendMessage );
  taskSendMessage.enable();

// Mengaktifkan parameter pada led indikator ----------------------
// dengan menyesuaikan dengan node yang aktif ---------------------
  blinkNoNodes.set(BLINK_PERIOD, (mesh.getNodeList().size() + 1) * 2, []() {
      // If on, switch off, else switch on
      if (onFlag)
        onFlag = false;
      else
        onFlag = true;
      blinkNoNodes.delay(BLINK_DURATION);

      if (blinkNoNodes.isLastIteration()) {
        // Finished blinking. Reset task for next run 
        // blink number of nodes (including this node) times
        blinkNoNodes.setIterations((mesh.getNodeList().size() + 1) * 2);
        // Calculate delay based on current mesh time and BLINK_PERIOD
        // This results in blinks between nodes being synced
        blinkNoNodes.enableDelayed(BLINK_PERIOD - 
            (mesh.getNodeTime() % (BLINK_PERIOD*1000))/1000);
      }
  });
  userScheduler.addTask(blinkNoNodes);
  blinkNoNodes.enable();

  randomSeed(analogRead(A0));
}

void loop() {
// Menjalankan scheduler dan mesh untuk update -----------------------------
  userScheduler.execute(); // it will run mesh scheduler as well
  mesh.update();

// Menjalankan LED Indikator -----------------------------------------------
  digitalWrite(LED, !onFlag);
  
}

// void untuk mengirim pesan ke node lain -----------------------------------
void sendMessage() {
  String msg = "Hello from node ";
  msg += mesh.getNodeId();
  msg += " myFreeMemory: " + String(ESP.getFreeHeap());
  mesh.sendBroadcast(msg);

  if (calc_delay) {
    SimpleList<uint32_t>::iterator node = nodes.begin();
    while (node != nodes.end()) {
      mesh.startDelayMeas(*node);
      node++;
    }
    calc_delay = false;
  }

  Serial.printf("Sending message: %s\n", msg.c_str());
  
  taskSendMessage.setInterval( random(TASK_SECOND * 1, TASK_SECOND * 5));  // between 1 and 5 seconds
}

// void untuk meminta callback pesan dari node lain ---------------------------
void receivedCallback(uint32_t from, String & msg) {
  Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
}

// 
void newConnectionCallback(uint32_t nodeId) {
  // Reset blink task
  onFlag = false;
  blinkNoNodes.setIterations((mesh.getNodeList().size() + 1) * 2);
  blinkNoNodes.enableDelayed(BLINK_PERIOD - (mesh.getNodeTime() % (BLINK_PERIOD*1000))/1000);
 
  Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
}

// void untuk menginformasikan koneksi ketika berpindah ------------------------
void changedConnectionCallback() {
  Serial.printf("Changed connections %s\n", mesh.subConnectionJson().c_str());
  // Reset blink task
  onFlag = false;
  blinkNoNodes.setIterations((mesh.getNodeList().size() + 1) * 2);
  blinkNoNodes.enableDelayed(BLINK_PERIOD - (mesh.getNodeTime() % (BLINK_PERIOD*1000))/1000);
 
  nodes = mesh.getNodeList();

  Serial.printf("Num nodes: %d\n", nodes.size());
  Serial.printf("Connection list:");

  SimpleList<uint32_t>::iterator node = nodes.begin();
  while (node != nodes.end()) {
    Serial.printf(" %u", *node);
    node++;
  }
  Serial.println();
  calc_delay = true;
}

void nodeTimeAdjustedCallback(int32_t offset) {
  Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(), offset);
}

void delayReceivedCallback(uint32_t from, int32_t delay) {
  Serial.printf("Delay to node %u is %d us\n", from, delay);
}

Upload Sketch program tersebut pada Arduino IDE dengan Board General ESP8266. Apabila terjadi error pada saat melakukan upload program Painlessmesh, maka kalian bisa ikuti solusi berikut : Error Compailing Library PainlessMesh ESP8266

Video Hasil Percobaan

Demo PainlessMesh NodeMCU/ESP8266

Kesimpulan

Setelah melakukan percobaan ini kita dapat menyimpulkan bahwa dengan menggunakan pogram starhere pada library painlessmesh ini kita dapat membuat sebuah jaringan mesh yang bisa saling terhubung satu sama lain antar node, dimana setiap node akan mengidentifikasi node lainnya dan dilaporkan dalam bentuk led blink sesuai dengan jumlah node yang ada.

Tresna Widiyaman Avatar