ESP8266 / ESP32 & Mesh Network ตอนที่ 2: ภาคต่อของ Painlessmesh Client/Server

ความเดิมตอนที่แล้ว

จาก ตอนที่ 1: Introduction & Painlessmesh ผู้อ่านน่าจะได้เข้าใจหลักการทำงานของ Mesh Network และการใช้งาน Library Painlessmesh ร่วมกับ ESP8266/ESP32 กันไปบ้างแล้วซึ่งเป็นการ Broadcast Message ไปยังทุก Node ที่อยู่ใน Mesh Network ซึ่งทั้งนี้ทั้งนั้นอยากให้เข้าใจหลักการการใช้งานกันก่อน เพราะถ้าเราเข้าใจหลักการแล้ว การประยุกต์ใช้งานจะทำได้ง่ายและเหมาะสมขึ้น งั้นเราก็มาทวนกันหน่อยละกันเนอะ

 

High Availability / Fault Tolerance

ขยายความจากตอนเดิม Mesh Network นั้นข้อดีก็คือเรื่องของความสเถียร สะดวก แทบไม่ต้อง setup อะไรเลย ถ้าดูตัวอย่างจากรูปด้านบน ถ้ามี Node ใด Node หนึ่งร่วงไปหรืออาจจะมากกว่าหนึ่งตัวก็ได้ เส้นทางในการส่งข้อมูลก็ยังคงไม่ถูกตัดขาด เพราะด้วยคุณสมบัติของ Self-Organize / Self-Configure ก็จะทำให้สามารถส่งข้อมูลไปยังปลายทาง หรือ Node ที่ยัง Active อยู่ได้ โดยไม่ต้องมีอุปกรณ์เป็นศูนย์กลางเหมือนระบบ WiFi ที่มีการทำงานแบบ Star ซึ่งถ้า WiFi Router หรือ AP ล่ม ทุก Node ก็จบ

 

Coverage Area

จากรูปด้านบน ถ้าคิด “เฉลี่ย” ที่ hop ละ 40 เมตร นี่คิดแบบ Conservative สุดๆไปเลยนะ เพียงแค่ 14 Node ก็สามารถทำให้มีการสื่อสารคลอบคลุมพื้นที่ได้ถึง 14,400 ตารางเมตร หรือ 9 ไร่กันเลยทีเดียว ถูกกว่าซื้อ AP หรือ Repeter มาใช้ซะอีก

ลักษณะการทำงานของ Mesh Network นั้นมักจะเป็นการใช้งานแบบ local network อย่างที่เราเห็นกันในระบบ home automation หรือแม้กระทั่ง smart meter บางรุ่น ฉะนั้นถ้าจะทำให้ Home Automation หรือ Local Mesh Network ที่เราสร้างขึ้นมานั้นส่งข้อมูลออกไปข้างนอกได้ ก็จะมีอีก Node หนึ่งขึ้นมาเพื่อเป็นสะพาน (Bridge) และใช้เป็นประตู (Gateway) ในการ forward ข้อมูลหรือใช้ในการสื่อสารกับ Network ภายนอก

Fibaro z-wave mesh network ใช้อุปกรณ์ที่ชื่อ Home Center เป็นตัว Bridge ระหว่างอุปกรณ์ต่างๆกับ Network ภายนอกซึ่งรองรับทั้ง WiFi และ Ethernet

ในระบบ Home Automation ที่ใช้ Zigbee หรือ Z-Wave หรือบางระบบซึ่งรองรับการสื่อสารทั้งสองแบบก็จะมีอุปกรณ์ที่เรียกว่า Gateway ไว้เป็นตัว Bridge ระหว่าง Local Mesh Network กับการสื่อสารผ่านโครงข่ายข้างนอก ไม่ว่าจะเป็น WiFi, Internet หรือแม้กระทั่งข้ามไปมาระหว่าง Zigbee กับ Z-Wave ซึ่งเดี่ยวเราจะมาต่อกันในบทที่ 3 เรื่อง Bridge ระหว่าง Mesh Network กับ Network ภายนอกกัน

 

Power Consumption

ถ้าจุดที่เราติดตั้งมีไฟฟ้าใช้งานตลอดเวลา หรือมีความสะดวกสบายในการเดินสายไฟ ประเด็นเรื่อง Power Consumption อาจจะไม่ต้องคิดมากนัก แต่ในระบบ home automation มักจะมีอุปกรณ์ประเภทที่ติดตั้งไว้โดดๆ หรือตอนที่บ้านสร้างเสร็จแล้ว อาจไม่สะดวกในเรื่องของการเดินสายไฟ ซึ่งอุปกรณ์เหล่านี้ก็จะเป็นพวก

  • PIR ไว้ตรวจจับความเคลื่อนไหวต่างๆ
  • Leak Sensor ไว้ดูว่ามีน้ำรั่วใต้ซิงค์ล้างจาน หรือใต้หลังคามั้ย
  • IR Remote ซึ่งทำให้เราสามารถที่จะควบคุมอุปกรณ์ต่างๆเช่น TV แอร์ พัดลม

ที่ยกตัวอย่างไป ถ้าบ้านที่สร้างเสร็จไปแล้ว และต้องมาเดินสายไฟ อาจไม่สวยงามนัก Zigbee กับ Z-wave จึงมาตอบโจทย์ตรงนี้ ในการเชื่อมต่อก็เป็นลักษณะ Mesh Network ไม่ต้องเดินสาย แถมกินไฟต่ำ ใส่ถ่าน A23 ไปสองก้อนอยู่ได้เป็นปี ทำให้สะดวกมากๆ แต่อุปกรณ์เหล่านี้ก็มีราคาแพง ถ้าเทียบกับ ESP8266/ESP32

 

ซึ่งถ้าเราจะใช้ ESP8266/ESP32 แล้วหละก็ สิ่งหนึ่งที่ต้องคำนึงถึงเลยก็คือเรื่องของการจ่ายไฟให้ Node เหล่านี้ทำงานอยู่ตลอดเวลา ไม่สามารถที่จะ Sleep เพื่อที่จะประหยัดไฟได้ เรามาลองดูกันว่าในสถานการณ์ต่างๆเจ้า nodemcu ของเรากินกระแสมากน้อยขนาดไหน ซึ่งลองวัดกันแบบหยาบๆผ่าน usb tester กัน ซึ่งถ้าใครมี Oscilloscope หรือ Multi-meter อยู่ใกล้ตัวก็น่าจะวัดได้ละเอียดขึ้น

Scenario1: rom เปล่าๆ วนลูปไปเรื่อย ค่าที่ได้ 80mA

Scenario2: ต่อ WiFi ทิ้งไว้ตามปกติ ค่าที่ได้อยู่ที่ 80mA

Scenario3: Join Mesh Network (ใช้ Painlessmesh) 2-6 Nodes Broadcast Message ค่าที่สังเกตุได้อยู่ที่ประมาณ 80-90mA มีค่า Peak อยู่ที่ประมาณ 150mA ซึ่งน่าจะมาจากตอน Led กระพริบและตอนที่ Join/Update Mesh Network ซึ่งคาดว่าใช้งานจริงเพิ่ม Node เข้าไป น่าจะทำให้อัตราการกินกระแสสูงขึ้น ถ้าอยากให้กระแสต่ำลงอาจจะต้องพิจารณาใช้ ESP12E อย่างเดียว ตัดพวก LED หรือ Serial to USB IC ออก ซึ่งก็จะทำให้ประหยัดไฟเพิ่มขึ้น แต่ก็ต้อง On Node ไว้อยู่ดีถ้าต้องการให้มีการเชื่อมต่อ

 

ฉะนั้นถ้าจะเอา ESP8266/ESP32 มาทำ Mesh Network เพื่อรับส่งข้อมูล หรือ Control อุปกรณ์ต่างๆแล้ว น่าจะต้องคำนึงในเรื่องของภาคจ่ายไฟด้วย ในโรงงานหรืออาคารที่ไม่มีปัญหาเรื่องการจ่ายไฟ น่าจะเหมาะ ส่วนงานประเภท Outdoor / Open Field อาจต้องพิจารณาในเรื่องของการนำพวก Solar Cell มาใช้ ก็เป็นอีกทางเลือกนึงที่น่าสนใจ ซึ่งจากข้อมูลด้านบนก็จะทำให้เราสามารถเตรียมในเรื่องของขนาด Solar Cell และ Battery สำรองไฟไว้ให้เหมาะสมได้ (อย่าลืมวัดจากการใช้งานใน application จริงด้วย เพราะเซนเซอร์บางอย่างก็กินกระแสโหดเหมือนกัน)

 

ในตอนที่ผ่านมาใครที่ผ่านมาอ่านแล้วได้ทดลองทำตามตัวอย่างแรกไป อาจเริ่มตัวอย่างที่สองในส่วนของการทำงานลักษณะที่เป็น Client/Server ไปแล้วก็ได้เพราะตัวอย่างที่ให้มานั้นค่อนข้างดีเลยทีเดียว แต่ถ้าใครยังไม่ได้เริ่ม ก็มาเริ่มพร้อมๆกันเลยครับ เกริ่นซะยาวอีกแล้ว

 

เริ่มใช้งาน Painlessmesh แบบ Client/Server

ตัวอย่างประกอบสำหรับการใช้งานแบบ Client/Server จะใช้อยู่สองตัวด้วยกันคือ logServer และ logClient โดยสามารถเลือกเปิดได้จาก File–>Examples–>Painless Mesh–> logServer หรือ logClient


#define   MESH_PREFIX     "HelloMyMesh"
#define   MESH_PASSWORD   "hellomymeshnetwork"
#define   MESH_PORT       5555

โดยเราจะเริ่มที่ logServer กันก่อนครับ ซึ่ง concept ก็ยังคงเหมือนเดิม ให้แก้ไขในส่วนของการตั้งค่า Mesh Network ของเราซึ่งก็คือ 3 บรรทัดด้านบนนี้ครับ หรือใครจะคงเดิมไว้เหมือนตัวอย่างที่ให้มาก็ได้แล้วก็ Flash ลง ESP8266/ESP32 ของเราได้เลย

 

แต่ในส่วนของคนที่ใช้ ESP32 ต้องแก้นิดนึงครับ เพราะการ Declare ในส่วนของ Authentication Mode นั้นไม่เหมือนกัน แต่ ESP8266 จะแก้ให้เป็นแบบ ESP32 ก็สามารถใช้งานได้เหมือนกันครับ


mesh.init( MESH_PREFIX, MESH_PASSWORD, MESH_PORT, STA_AP, WIFI_AUTH_WPA2_PSK, 6 ); // <-- ต้องเพิ่มคำว่า WIFI_ เข้าไปด้วย

 

Concept ของตัวอย่าง logServer นั้นคล้ายๆกับตอนที่ 1 ครับเพียงแต่ว่า Broadcast Message ที่ส่งออกไปนั้น มีจุดประสงค์ในการส่งออกไปเพื่อบอกให้ node ที่อยู่ใน Mesh Network นี้รู้ว่า ฉัน NodeID นี้นะเป็น Server Node นะ ซึ่งก็จะทำงานด้วย task scheduler ทุกๆ 10 วิ ฉะนั้นเมื่อมี node ใหม่เข้ามา join ใน Mesh Network ก็จะรู้แล้วว่าจะต้องส่งข้อมูลให้ใครซึ่งรูปแบบ Message ที่ส่งออกไปก็อยู่ในฟอร์แมทของ JSON ครับ โดยในส่วนของ receivedCallback ก็ยังเหมือนเดิมคือ ได้รับ message มาก็ Print ออกทาง Serial Port ไม่มีไรเปลี่ยนแปลง



Task logServerTask(10000, TASK_FOREVER, []() {
    DynamicJsonBuffer jsonBuffer;
    JsonObject& msg = jsonBuffer.createObject();
    msg["topic"] = "logServer";       //กำหนด Topic เพื่อที่ Node ที่ join เข้ามาหาข้อมูลของ Server เจอ
    msg["nodeId"] = mesh.getNodeId(); // ใช้คำสั่ง mesh.getNodeID(); เพื่ออ่านค่า NodeID

    String str;
    msg.printTo(str);
    mesh.sendBroadcast(str);          // ส่งข้อความ Broadcast ไปยังทุก Node ว่าฉันคือ Server Node นะ

    // log to serial
    msg.printTo(Serial);
    Serial.printf("\n");
});

 

 

 

หลังจาก Flash เสร็จการทำงานก็เป็นอย่างที่เห็นข้างบนครับ จะเริ่มทำการเช็คข้างเคียงว่ามี Node ไหนที่สามารถ Join ได้บ้างจากนั้นก็ปรับ Offset Time Synchronize ให้เท่ากับเพื่อนๆในวงซะ แล้วก็เข้าสู่ Task ที่ใช้ในการ Broadcast Message ออกไปว่าเราคือ Server เพื่อให้ Node ทุกตัวที่อยู่ใน Mesh Network เดียวกันรู้ว่าจะส่งข้อมูลให้ Server ให้ส่งไปที่ NodeID หมายเลขอะไร ซึ่งในที่นี้ก็คือ 6217

 

มาดูในส่วนของ logClient กันบ้าง ซึ่งในส่วนของ receivedCallback เนี่ยแหละที่จะเปลี่ยนไป เพราะจะมีการเช็ค Broadcast Message จาก Node อื่นๆ ซึ่งก็คือ Server Node ว่า เห้ยยย นี่แหละ Server Node นะ มี ID นี้นะ จากนี้ถ้าจะส่งข้อความไปที่ ServerNode ให้ส่งไปที่ NodeID นี้นะ

void receivedCallback( uint32_t from, String &msg ) {
  Serial.printf("logClient: Received from %u msg=%s\n", from, msg.c_str());

  // Saving logServer
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(msg);
  if (root.containsKey("topic")) {
      if (String("logServer").equals(root["topic"].as<String>())) { //เช็ค Topic ว่าเป็น logServer หรือเปล่า
          // check for on: true or false
          logServerId = root["nodeId"]; //อ่านและบันทึกค่า nodeID ของ Server เพื่อใช้เป็นปลายทางในการส่ง
          Serial.printf("logServer detected!!!\n");
      }
      Serial.printf("Handled from %u msg=%s\n", from, msg.c_str());
  }
}

 

สำหรับส่วนของ Task ที่ใช้ในการส่ง Message ก็จะทำงานล้อกัน คือถ้ายังไม่เจอว่า ใน Mesh Network ที่เพิ่ง join เข้ามามี server หรือเปล่า ฉันก็ broadcast ข้อมูลของฉันเลยละกัน เนื่องจาก Server Node มีระยะเวลา 10 วินาทีถึงจะ Broadcast Message Topic “logserver” ออกไป ฉะนั้นการทำเช่นนี้ Server Node ที่รอข้อมูลจาก Client Node ก็จะได้ข้อมูลแน่ๆ (รวมถึงตัวอื่นๆด้วย)


Task myLoggingTask(10000, TASK_FOREVER, []() {
    DynamicJsonBuffer jsonBuffer;
    JsonObject& msg = jsonBuffer.createObject();
    msg["topic"] = "sensor";
    msg["value"] = random(0, 180);  //สำหรับไฟล์ตัวอย่างนี้ยังไม่ได้ต่อเข้ากับเซนเซอร์อะไร ก็สุ่มค่าส่งไปละกัน

    String str;
    msg.printTo(str);
    if (logServerId == 0) // If we don't know the logServer yet
        mesh.sendBroadcast(str);
    else
        mesh.sendSingle(logServerId, str);

    // log to serial
    msg.printTo(Serial);
    Serial.printf("\n");
});

 

คราวนี้แทนที่เราจะจำลองข้อมูลเหมือนในตัวอย่าง ก็ได้เวลาเปิดกระป๋องแระ เอา DHT22 มาพ่วงเข้าไป คราวนี้ Temp/Humid ที่ได้ก็จะเป็นค่าจริงแล้วโดยการปรับ Code ในส่วนของ Task ที่ใช้สำหรับการส่งข้อความ ซึ่งจะมีการอ่านค่าจาก DHT22 แล้วจัดรูปแบบให้อยู่ในฟอร์แมทของ JSON โดยที่ Mesh Network นี้จะประกอบไปด้วย 12 Node ด้วยกันดังนี้

  • ESP32 Wroom ทำตัวเป็น Server
  • ESP-01 เป็น Client ที่ส่งค่าสุ่มเข้ามา
  • Wemos D1 Mini 4 ตัว เป็น Client ที่ส่งค่าสุ่มเข้ามา (Wemos-01 ถึง Wemos-04)
  • Wemos D1 Mini 1 ตัว เป็น Client ที่ส่งค่า Temp/Humid ที่อ่านได้จาก DHT22
  • Nodemcu 4 ตัว เป็น Client ที่ส่งค่าสุ่มเข้ามา (mcu-01 ถึง mcu-04)
  • Nodemcu 1 ตัว เป็น Client ที่ส่งค่า Temp/Humid ที่อ่านได้จาก DHT22

 

Code ที่ทำการแก้ไขสำหรับ Node ตัวที่สุ่มส่งค่า (ESP-01, Wemos-01 ถึง 04, mcu-01  ถึง 04)


// Send message to the logServer every 10 seconds 
Task myLoggingTask(5000, TASK_FOREVER, []() {
    DynamicJsonBuffer jsonBuffer;
    JsonObject& msg = jsonBuffer.createObject();
    msg["nodename"] = "mcu3";                     //เพิ่ม NodeName เข้ามาพอหลายๆตัวเริ่มงงกับ เลข NodeID
    msg["NodeID"] = mesh.getNodeId();             //เพิ่ม NodeID เอาไว้อ้างอิง
    msg["random value"] = random(0, 180);         //เปลี่ยนเป็น random value ให้ชัดเจนว่าเป็นค่าที่สุ่มขึ้นมา

    String str;
    msg.printTo(str);
    if (logServerId == 0) // If we don't know the logServer yet
        mesh.sendBroadcast(str);
    else
        mesh.sendSingle(logServerId, str);

    // log to serial
    msg.printTo(Serial);
    Serial.printf("\n");
});

 

Code ที่ทำการแก้ไขสำหรับ Node ตัวที่ส่งค่า Temp/Humid จาก DHT22 (Wemos-t1 และ mcu-t1)

#include "painlessMesh.h"
#include "DHT.h"

#define DHTPIN D4
#define DHTTYPE DHT22

#define   MESH_PREFIX     "HelloMyMesh"
#define   MESH_PASSWORD   "hellomymeshnetwork"
#define   MESH_PORT       5555

DHT dht(DHTPIN, DHTTYPE);

void receivedCallback( uint32_t from, String &msg );

painlessMesh  mesh;

size_t logServerId = 0;

// Send message to the logServer every 5 seconds
Task myLoggingTask(5000, TASK_FOREVER, []() {
  
  float h = dht.readHumidity();

  float t = dht.readTemperature();
  
  DynamicJsonBuffer jsonBuffer;
  JsonObject& msg = jsonBuffer.createObject();
  msg["nodename"] = "Wemos-t1";
  msg["NodeID"] = mesh.getNodeId();
  msg["Temp"] = String(t)+"C";
  msg["Humidity"] = String(h)+"%";

  String str;
  msg.printTo(str);
  if (logServerId == 0) // If we don't know the logServer yet
    mesh.sendBroadcast(str);
  else
    mesh.sendSingle(logServerId, str);

  // log to serial
  msg.printTo(Serial);
  Serial.printf("\n");
});

void setup() {

  Serial.begin(115200);
  Serial.println("Begin DHT22 Mesh Network test!");

  dht.begin();

  mesh.setDebugMsgTypes( ERROR | STARTUP | CONNECTION );  // set before init() so that you can see startup messages

  mesh.init( MESH_PREFIX, MESH_PASSWORD, MESH_PORT, STA_AP, AUTH_WPA2_PSK, 6 );
  mesh.onReceive(&receivedCallback);

  // Add the task to the mesh scheduler
  mesh.scheduler.addTask(myLoggingTask);
  myLoggingTask.enable();

}

void loop() {
  // put your main code here, to run repeatedly:

  mesh.update();


}

void receivedCallback( uint32_t from, String &msg ) {
  Serial.printf("logClient: Received from %u msg=%s\n", from, msg.c_str());

  // Saving logServer
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(msg);
  if (root.containsKey("topic")) {
      if (String("logServer").equals(root["topic"].as<String>())) {
          // check for on: true or false
          logServerId = root["nodeId"];
          Serial.printf("logServer detected!!!\n");
      }
      Serial.printf("Handled from %u msg=%s\n", from, msg.c_str());
  }
}

 

หลังจาก Flash ครบตัวสุดท้ายก็เปิด Serial Monitor ขึ้นมาจะเห็นได้จากรูปข้างล่างเลยครับว่า เจอ Node ข้างเคียงอยู่ทั้งหมด 10 Node พร้อมกับความแรงของสัญญาณจากแต่ละ Node ซึ่งจะใช้ในการจัดการการเชื่อมต่อของ Mesh Network ของเรา

 

อย่างที่ได้บอกไปข้างต้นครับ เมื่อเริ่มการทำงาน Server จะ Broadcast Message เพื่อบอกเพื่อนๆใน Mesh Network นี้ว่า NodeID ของ Server นั้นคือหมายเลขอะไร เพื่อที่ว่าเผื่อบางครั้ง ได้มีการเพิ่ม Node เข้าไปใน Mesh Network นี้ก็สามารถที่จะรู้ได้ทันทีว่าจะต้องส่งข้อมูลไปที่ Server NodeID ไหน แต่ระหว่างที่ยังไม่รู้ว่า Server NodeID คือหมายเลขอะไร Client Node ก็จะ Broadcast Message ออกไปเพื่อแจ้งไปก่อน อย่างน้อยมันก็ต้องเข้า Server Node แหละ คราวนี้เรามาจำลองเคสที่ว่านี้กันดู ระหว่างที่ยังไม่เจอ Server Node และเมื่อ Server Node Online และทุกๆ Node รับทราบกันหมดแล้วและส่ง Message ออกไปแบบระบุ NodeID

 

Scenario ที่ 1: No Server Node

ตามรูปด้านล่างนี้เลยครับ ข้อมูลที่ได้รับผ่าน receivedCallback ได้รับข้อมูลจาก Node ที่ Online ใน Mesh Network นี้ทั้งหมด เพราะว่ายังไม่ได้เปิด Server

 

Scenario ที่ 2: Server Node join Mesh Network

เมื่อเปิด Server Node เข้ามาก็จะเป็นเหมือนรูปข้างล่างนี้ครับ ได้รับ Broadcast Message จาก Server Node และในส่วนของ receivedCallback ก็จะมี logic เพื่อใช้ในการอ่านค่าว่ามี Topic ที่เป็น logServer มั้ย ถ้ามีก็บันทึกเก็บไว้ เพื่อในการส่งรอบต่อไปจะไม่ Broadcast ไปยังทุก Node ละ แต่จะระบุปลายทางเป็น NodeID ของ Server แทน

 

หลังจากที่ทุก Node ได้รับ Server NodeID จาก Broadcast Message ที่ส่งมาจาก Server Node แล้ว แทนที่ทุก Node จะส่งข้อมูลออกไปยังทุกๆ Node ก็จะส่งไปยัง Server Node แทนดังจะเห็นได้จากรูปข้างล่างที่ได้รับ Broadcast Message เข้ามาจะมีเฉพาะข้อความที่มาจาก Server Node เท่านั้น เพราะตัวอื่นๆส่งไปที่ Server Node หมดแล้ว

 

คราวนี้เรามาลองดูในฝั่งของ Server กันบ้างว่าเมื่อทุก Node ส่งข้อมูลมาที่ Server Node แล้วข้อมูลที่ได้จะเป็นลักษณะไหนกัน จากรูปจะเห็นได้ว่า ข้อมูลจะได้ครบเหมือนตอนที่เราดูของ Node ใด Node หนึ่งตอนที่ยังไม่มี Server Node เนื่องจากคราวนี้ทุก Node ใน Mesh Network ส่งมาที่จุดๆเดียว ก็เลยจะได้ข้อมูลครบ และตัว Server Node เองก็ยังคง Broadcast Message ออกไปเรื่อยๆเพื่อให้ทุกคนรู้ว่า ฉันอยู่ที่นี่นะ ถ้าจะส่งข้อมูลมาหา ให้ส่งมาที่ไหน

 

ขยายความในส่วนของ Server Node กันอีกนิดว่าทำไมต้องคอย Broadcast Server NodeID อยู่ตลอดเวลา

  • ข้อดีเลยก็คือ ถ้าในอนาคตต้องมีการเปลี่ยนอุปกรณ์ในส่วนของ Server Node ที่เสียไป แต่เมื่อสลับอุปกรณ์เปลี่ยน Server Node แน่นอนว่า ChipID เปลี่ยนไปละ การ Broadcast Server NodeID และในส่วนของ Client ที่มี receivedCallback คอยเช็ค Server NodeID ก็จะทำให้แทบไม่กระทบกับการทำงานเลย เพราะในทุกสุดทุก Node ก็จะรู้ว่าต้องส่งไปที่ Server Node ใหม่หมายเลขอะไร

 

  • ซึ่งถ้าเข้าใจหลักการที่เขียนมาสองบทนี้ เรายังสามารถประยุกต์ใช้งานในการทำ Server Node ที่มีมากกว่า 1 ก็ได้ ยิ่งทำให้ระบบ Mesh Network ที่ใช้ในการสื่อสารออกไป Network ภายนอกนั้นเสถียรยิ่งขึ้น หรือจะแบ่งเบาภาระของ Server Node เป็นลักษณะของ load balance ก็ยังได้

 

ตัวอย่างการประยุกต์ใช้งาน

  • Read and Forward: เคสนี้จะเข้าข่ายสำหรับพวกการส่งข้อมูลเข้า Server อาจจะเป็นการวัดอุณหภูมิ ความชื้น หรือแม้กระทั่งเสียงบริเวณต่างๆของโรงงาน แล้วมาเก็บไว้ที่ Server เพื่อที่จะแสดงผล หรือนำข้อมูลไปวิเคราะห์เหตุต่างๆ เหมือนในตัวอย่าง logServer/logClient ที่เราเพิ่งทำกันไป เป็นการใช้งานที่ค่อนข้าง One-way ซะเป็นส่วนใหญ่ และก็เป็น Application ของ iot ซะเป็นส่วนใหญ่อีกเช่นกันด้วย

 

  • เนื่องจากการส่ง message ภายใน Mesh Network นี้สามารถที่จะกำหนดปลายทางผู้รับได้ด้วย NodeID หรือจะส่ง Broadcast แล้วค่อย Filter Message เอาก็ได้ว่าปลายทางที่ระบุใน Broadcast Message เป็นของเราหรือเปล่า จากนั้นอ่านค่าที่ได้มา เปรียบเทียบ logic ที่ต้องการ อาจจะเป็นการสั่งให้เปิดปั้มน้ำเพื่อรดน้ำต้นไม้ หรือสั่งให้เปิด Siren นอกอาคารกรณีมีการตรวจจับควันไฟได้ จะแจ้งเป็น zone หรือแจ้งเป็นจุดๆ ก็แล้วแต่หลักการเขียนข้อความที่ส่งไป และหลักการเปรียบเทียบ logic ของข้อความที่ได้รับมา ซึ่ง Painlessmesh ใช้รูปแบบการส่งแบบ JSON ก็สะดวกยิ่งขึ้น

 

  • Point to Point / Independent: เนื่องจาก Mesh Network นั้นทำให้ทุก Node นั้นเชื่อมหากันอยู่แล้ว Node ไหน อยากคุยกับ Node ไหนก็ได้ เคสลักษณะนี้ก็อาจจะมี Node ที่ทำงานเป็นลักษณะ Control Panel สามารถที่จะเลือกได้ว่าจะส่งคำสั่งไปให้ node ตัวไหนก็ได้ โดยการอ้างอิงจาก NodeID หรืออาจจะแปลง NodeID ให้เป็นชื่อที่อ่านแล้วเข้าใจง่ายเหมือนที่ผมทำเป็นต้น

 

หมายเหตุ

เนื่องจาก ESP8266/ESP32 ยังใช้ WiFi ย่าน 2.4 GHz อยู่ ซึ่งเวลาใช้งานในโหมดของ Station and AP เพื่อให้ Node ต่างๆมาเกาะรวมกันเป็น Mesh Network แล้ว ถ้าเปิดโปรแกรมพวก WiFi Analyzer มาดูก็จะเห็นชื่อ AP ใน Mesh ของเราขึ้นมาเพียบเลย ซึ่งอาจจะไปกวนกับ AP อื่นหรือ AP อื่นอาจจะมากวนเราก็ได้ ยังไงก็ลองพิจารณาการใช้งานให้เหมาะสมดูครับ

 

วันนี้ก็จบตอน 2 ไว้เพียงเท่านี้ก่อนครับ แล้วตอนหน้าเราจะมาดูกันว่า การที่จะส่งข้อมูลออกไปที่ Network ภายนอกหรือ Internet เพื่อให้สื่อสารกับโลกภายนอกผ่านการ Bridge ระหว่าง Mesh Network และ Node ที่ทำตัวเป็น Gateway ได้อย่างไร

 

เรื่องเล่าท้ายตอน

สมัยปี 40 เป็นปีแรกเลยที่ได้รู้จัก ได้ใช้งาน micro controller ตระกูล MCS51 โปรเจคแรกๆก็หนีไม่พ้นหุ่นเดินตามเส้น ต้องเขียนด้วยภาษา Assembly หน่วยความจำก็มีจำกัด อุปกรณ์ที่ใช้สำหรับ flash ก็แพง อุปกรณ์จะซื้อทีก็ต้องนั่งรถจากศาลายามาบ้านหม้อ เทียบกับสมัยนี้ที่สะดวกสบายขึ้นมาก การเข้าถึง content ด้านต่างๆก็ง่ายขึ้น สมัยตอนเรียนสิ่งเดียวที่พอหาอ้างอิงได้คือ โปรเจคจบของรุ่นพี่ แล้วก็หนังสือจากห้องสมุด พอเข้าสู่ยุคที่มี raspberry pi, arduino และ social media ช่างรู้สึกว่าโลกเปลี่ยนไปเร็วเหลือเกิน เด็กรุ่นใหม่ๆนี่เรียนรู้กันได้เร็วและเก่งมาก ด้วยอายุที่มากขึ้น เปลี่ยนสายงานจากลงมือ implement เอง มาเป็นดูภาพรวมบริหารงาน ก็ยังสนุกกับการหาความรู้ใหม่ๆ ทดลองนั่นนู่นี่ตามโอกาสอำนวย ยิ่งเห็นการเปิดตัวของ maker space และ startup ต่างๆแล้วยิ่งคิดถึงสมัยอยู่ lab ของมหาลัยดึกๆดื่นๆ ในตอนที่ 2 ก็ฝากกันไว้เท่านี่ก่อนครับ แล้วเดี่ยวมาต่อตอนที่ 3 กัน

ปล.

ถ้าดูจาก Sponsor หลัก (และ Sponsor เดียว) ของทีมผู้พัฒนา Painlessmesh แล้ว ก็จะมีบริษัท  Sowillo ที่เป็นผู้ให้เงินทุนสนับสนุนโดยธุรกิจของ Sowillo ก็จะทำเกี่ยวกับเครื่องทำน้ำร้อนโดยใช้พลังงานแสงอาทิตย์ ซึ่งถ้าใครเอา Painlessmesh ไปใช้งานในเชิงพาณิชย์ ถ้าสามารถสนับสนุนทีมพัฒนานี้ได้ก็จะดีมากๆเลยครับ

หน้าหลักของ Painlessmesh

Author: Joe D.S.
Just a man on earth

2 thoughts on “ESP8266 / ESP32 & Mesh Network ตอนที่ 2: ภาคต่อของ Painlessmesh Client/Server

  1. สวัสดีครับ ผมสงสัยเรื่องนึงครับ ค่าได้รับจากการส่งจำพวก อุณหภูมิ สามารถนำมาคำนวณ ต่างๆ ได้มั้ย

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.