[TH] WiFiServer

หลังจากได้ศึกษาเรื่องของ ESP8266WiFi เพื่อควบคุมการทำงานของไมโครคอนโทรลเลอร์ให้เชื่อมต่อกับเครือข่ายไร้สายในแบบ STA และ SoftAP ไปแล้ว หลังจากนั้นได้เรียนรู้การใช้ WiFiClient เพื่อใช้ esp8266 เป็นโหนดลูกข่าย ในครั้งนี้เป็นเรื่องของ WiFiServer เพื่อให้ esp8266 ทำหน้าที่เป็นโหนดให้บริการหรือ Server โดยตัวอย่างในบทความนี้เป็นการสร้างระบบเครือข่ายภายในโดยใช้ esp8266 จำนวน 3 ตัวเพื่อทำหน้าที่เป็น SoftAP, Server และ Client ดังภาพที่ 1

WiFiServer

คลาส WiFiServer เป็นคลาสสำหรับทำให้ไมโครคอนโทรลเลอร์ทำงานเป็นเครื่องให้บริการ โดยการสร้างวัตถุประเภทเครื่องให้บริการต้องระบุหมายเลขพอร์ตให้บริการในขั้นตอนการสร้าง ดังรูปแบบการใช้งานต่อไปนี้

WiFiServer วัตถุ( หมายเลขพอร์ต )

เมื่อได้วัตถุสำหรับอ้างอิงการทำงานของไลบรารีเครื่องให้บริการเป็นที่เรียบร้อย ขั้นตอนต่อไปคือการสร้างวัตถุแบบลูกข่ายที่เตรียมไว้สำหรับให้บริการดังนี้

WiFiClient วัตถุลูกข่าย = วัตถุ.available()

ถ้าวัตถุลูกข่ายไม่ใช่ 0 หมายถึง เครื่องให้บริการที่เราสร้างนั้นพร้อมให้บริการ ผู้เขียนโปรแกรมต้องทำการตรวจสอบว่ามีลูกข่ายใดเข้าเชื่อมต่อมาที่เครื่องให้บริการหรือไม่ (โดยใช้คำสั่ง WiFiClient.begin( เครื่องบริการ, พอร์ต ) จากบทความก่อนหน้านี้) ด้วยคำสั่งต่อไปนี้

ผลการตรวจสอบ = วัตถุลูกข่าย.connected()

การอ่านข้อมูลคำร้องขอจากลูกข่ายใช้คำสั่งใช้คำสั่ง readStringUntil() ดังรูปแบบต่อไปนี้

String ตัวแปร = วัตถุลูกข่าย.readStringUntil( ตัวสิ้นสุดการอ่าน )

การส่งข้อมูลตอบสนองให้ลูกข่ายใช้คำสั่ง print() หรือ println() ดังนี้

วัตถุลูกข่าย.print( ข้อมูลส่งกลับ )

วัตถุลูกข่าย.println( ข้อมูลส่งกลับ )

เพื่อความมั่นใจในการส่งข้อมูลหรือรับข้อมูลการ flush() เป็นการทำให้บัฟเฟอร์ว่างด้วยการนำเข้าหรือนำออกให้เสร็จสิ้นก่อนทำงานอื่น ๆ ต่อไป โดยคำสั่ง flush() มีรูปแบบการใช้งานดังนี้

วัตถุลูกข่าย.flush()

สุดท้ายเมื่อไม่มีการเชื่อมต่อหรือสื่อสารกับลูกข่ายให้ยกเลิกการเชื่อมต่อกับลูกข่ายด้วยคำสั่ง stop() ดังนี้

วัตถุลูกข่าย.stop()

ตัวอย่างโปรแกรม

อุปกรณ์การทดลองของตัวอย่างโปรแกรมในบทความนี้ ทางเราใช้ esp8266 จำนวน 3 ตัว ดังภาพที่ 1 โดยเป็นรุ่น WeMos D1 mini (clone) ให้เป็น SoftAP เพื่อแจกจ่าย IP Address ให้กับ Server และ Client หลังจากนั้นใช้ NodeMCU V3 (ทางขวา) เป็น Client และให้ NodeMCU ทางด้านซ้ายเป็น Server

ภาพที่ 1 อุปกรณ์การทดลอง

โค้ดสำหรับ SoftAP

// Node 1 : SoftAP
#include <ESP8266WiFi.h>

IPAddress myIP(192, 168, 4, 1);
IPAddress gwIP(192, 168, 4, 10);
IPAddress subnet(255, 255, 255, 0);

#define SSID "JarutEx"
#define PSK "123456789"

void setup() {
  Serial.begin(115200);
  Serial.println("\n\r\n\r");
  Serial.print("MAC Address : ");
  Serial.println(WiFi.softAPmacAddress());
  if (WiFi.softAPConfig( myIP, gwIP, subnet )) {
    if (WiFi.softAP(SSID, PSK, 8, true, 3)) {
      Serial.print("IP Address : ");
      Serial.println(WiFi.softAPIP());
      Serial.print(WiFi.softAPgetStationNum());
      Serial.println(" connected.");
      // WiFi.softAPdisconnect();
    } else {
      Serial.println("softAP() failed!!");
    }
  } else {
    Serial.println("softAPConfig() failed!");
  }
}

void loop() {
}

โค้ดสำหรับ Server

//  2-Server
// WIFI_STA
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#define AP_NAME "JarutEx"
#define AP_PASSWD "123456789"

ESP8266WiFiMulti  wifiMulti;
WiFiServer server(3003);
IPAddress ip(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

void setup() {
  Serial.begin(115200);
  Serial.println("\n\r\n\r");
  WiFi.mode( WIFI_STA );
  wifiMulti.addAP( AP_NAME, AP_PASSWD );
  while (wifiMulti.run() != WL_CONNECTED) {
    delay(500);
  }
  Serial.println(WiFi.localIP());
  server.begin();
  Serial.println("Server begin.");
  Serial.print("Status: "); Serial.println(WiFi.status());  
  Serial.print("IP: ");     Serial.println(WiFi.localIP());
  Serial.print("Subnet: "); Serial.println(WiFi.subnetMask());
  Serial.print("Gateway: "); Serial.println(WiFi.gatewayIP());
  Serial.print("SSID: "); Serial.println(WiFi.SSID());
  Serial.print("Signal: "); Serial.println(WiFi.RSSI());
  Serial.print("Networks: "); Serial.println(WiFi.scanNetworks());
}

void loop() {
  if (wifiMulti.run() == WL_CONNECTED) {
    WiFiClient client = server.available();
    if (client) {
      if (client.connected()) {
        String req = client.readStringUntil('\r');
        Serial.print("From client:");
        Serial.println(req);
        client.flush();
        client.println(req);
        client.stop();
      } else {
        delay(5000);
        Serial.print("+");
      }
    }
  }
}

และโค้ดสำหรับ Client

// 3-Client
// WIFI_STA
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#define AP_NAME  "JarutEx"
#define AP_PASSWD  "123456789"
ESP8266WiFiMulti  wifiMulti;
WiFiClient client;
IPAddress sIP(192, 168, 4, 100);

void setup() {
  Serial.begin(115200);
  Serial.println("\n\r\ns\r");
  WiFi.mode( WIFI_STA );
  wifiMulti.addAP( AP_NAME, AP_PASSWD );
  while (wifiMulti.run() != WL_CONNECTED) {
    delay(500);
  }
  Serial.println(WiFi.localIP());
  Serial.println("Client  begin.");
}

void loop() {
  if (wifiMulti.run() == WL_CONNECTED) {
    if (client.connect( sIP, 3003 )) {
      Serial.println("Connected.");
      client.println("Hello, World!\r");
      while (!client.available());
      String echoStr = client.readStringUntil('\r');
      client.flush();
      Serial.print("From server:");
      Serial.println(echoStr);
      client.stop();
      delay(10000);
    }
  } else {
    delay(5000);
  }
}

เมื่อระบบทำงานโดยเชื่อมต่อดังภาพที่ 1 ได้ผลลัพธ์ดังตัวอย่างในภาพที่ 2

ภาพที่ 2 ตัวอย่างผลลัพธ์จากการทำงานของโปรแกรมทั้ง 3

สรุป

จากตัวอย่างในครั้งนี้จะพบว่า การใช้ esp8266 เป็นเครือข่ายของการสื่อสารไร้สายด้วยโพรโทคอลอินเทอร์เน็ตนั้นไม่ได้ยุ่งยาก เนื่องจากไม่ต้องเดินสาย และไมโครคอนโทรลเลอร์รองรับการทำงานด้านนี้อยู่แล้ว และเมื่อเชื่อมต่อวงจรเซ็นเซอร์เข้าไปในเครือข่ายที่สร้างขึ้น ผู้อ่านจะได้เครือข่ายไร้สายของเซ็นเซอร์ให้ใช้งาน สถดท้ายนี้หวังว่าบทความจะมีประโยชน์ในการนำไปใช้งาน และขอให้สนุกกับการเขียนโปรแกรมครับ

ท่านใดต้องการพูดคุยสามารถคอมเมนท์ไว้ได้เลยครับ

แหล่งอ้างอิง

  1. ESP8266 Arduino Core: ESP8266WiFi
  2. ESP8266 Arduino Core: Server
  3. Link2004@github: ESP8266 WiFiServer Class Reference

(C) 2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ

ปรับปรุงเมื่อ 2021-07-31, 2021-08-01, 2021-11-04