top of page

ลองเล่นกับ SmartConfig ตั้งค่า ESP8266/ESP32 แบบไม่ต้องเชื่อมต่อ

อัปเดตเมื่อ 25 มี.ค. 2565


การตั้งค่า WiFi ส่วนใหญ่ใช้ไลบารี่ WiFiManager โดยมีขั้นตอนการตั้งค่า คือที่ ESP8266/ESP32 (ต่อไปนี้ขอเรียก ESP) ตั้งตัวเองเป็น Access Point จากนั้นใช้โทรศัพท์มือถือ เครื่องคอมพิวเตอร์เชื่อมเข้าไปที่ตัว ESP แล้วจึงตั้งค่าการเชื่อมต่อ WiFi จะเห็นได้ว่าหากใช้ WiFiManager จะมีขั้นตอนยุ่งยากพอสมควร โดยเฉพาะกับผู้ใช้ทั่วไป แนวทางการตั้งค่าการเชื่อมต่อ WiFi ที่ง่ายกว่าวิธีหนึ่งคือใช้ SmartConfig โดยขั้นตอนหลักคือการใช้แอพพลิเคชั่นบนโทรศัพท์มือถือตั้งค่า WiFi โดยไม่ต้องเชื่อมต่อ WiFi เข้าไปที่ตัว ESP ก่อน


รู้จักกับ SmartConfig

SmartConfig เป็นเทคโนโลยีการตั้งค่าการเชื่อมต่อ WiFi กับเร้าเตอร์ ที่พัฒนาโดย TI (Texas Instruments) หลักการทำงานคือ แอพพลิเคชั่นจะสั่งให้โทรศัพท์มือถือปล่อยคลื่น WiFi ที่แฝงข้อมูลการตั้งค่าออกไป (แบบ Broadcast) ที่ ESP ได้รับข้อมูลการตั้งค่ามา ก็จะนำมาตั้งค่าการเชื่อมต่อให้เชื่อมต่อกับเร้าเตอร์ หลังจากเชื่อมต่อกับเร้าเตอร์ได้แล้ว ตัว ESP จึงปล่อยคลื่น WiFi ที่แฝงข้อมูลที่ได้จากการเชื่อมต่อ ประกอบด้วยหมายเลข IP (แบบ local) และ MAC Address เมื่อโทรศัพท์มือถือได้รับ แอพพลิเคชั่นจะแจ้งผลการตั้งค่าให้ผู้ใช้รับทราบต่อไป


ทดลองใช้ SmartConfig

SmartConfig รองรับทั้ง ESP8266 และ ESP32 โดยสามารถใช้บอร์ดใดก็ได้ในการทดสอบ สำหรับในบทความนี้เลือกใช้บอร์ด IOXESP32+ ที่คอมพิวเตอร์ติดตั้งไดร์เวอร์ของบอร์ด (FT231XQ) และเพิ่มบอร์ด ESP32 ลงโปรแกรม Arduino IDE เรียบร้อยแล้ว จึงทำตามขั้นตอนดังนี้

1) เปิดโปรแกรม Arduino IDE ขึ้นมา จากนั้นกดไปที่ File > Examples > WiFi เลือก WiFiSmartConfig

2) เลือกบอร์ด เลือกพอร์ต จากนั้นกดปุ่มอัพโหลดโปรแกรมลงบอร์ด ESP32

3) เปิด Serial Monitor ขึ้นมา กดปุ่ม RESET บนบอร์ด 1 ครั้ง จะเห็นว่ามีข้อความ Waiting for SmartConfig. แสดงขึ้นมา สามารถใช้แอพพลิเคชั่นตั้งค่าการเชื่อมต่อได้เลย

4) ดาวน์โหลด-ติดตั้ง แอพพลิเคชั่น ESPTouch จาก Google Play หรือ App Store

5) เปิดแอพพลิเคชั่น ESPTouch ขึ้นมา สังเกตชื่อ WiFi ที่ต้องการให้ ESP ไปเชื่อมต่อ (1) โดยแอพพลิเคชั่นจะดึงชื่อ WiFi ที่โทรศัพท์มือถือเชื่อมต่อมาแสดง กรอกรหัสผ่านของ WiFi (2) จากนั้นกดปุ่ม CONFIRM

6) รอแอพพลิเคชั่นส่งข้อมูลคอนฟิกเข้าไปที่ ESP

7) เมื่อ ESP ได้รับข้อมูลตั้งค่า และเชื่อมต่อ WiFi ได้แล้ว จะแสดงหมายเลข MAC Address (BSSID) และหมายเลข IP ขึ้นมาให้ทราบ

8) ที่ Serial Monitor จะแสดงผลการตั้งค่าและเชื่อมต่อ WiFi ขึ้นมาให้ทราบ

เท่านี้ก็สามารถตั้งค่าการเชื่อมต่อ WiFi ด้วย SmartConfig ได้แล้ว

การบันทีกการตั้งค่า WiFi

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

หลังจากเชื่อมต่อ WiFi ได้แล้ว สามารถใช้คำสั่ง WiFi.SSID() อ่านชื่อ WiFi ที่เชื่อมต่อ และใช้คำสั่ง WiFi.psk() เพื่อดูรหัสผ่าน ตัวอย่างด้านล่างแก้โค้ดให้แสดงชื่อ WiFi และรหัสผ่านของ WiFi ที่เชื่อมต่ออยู่ (บรรทัดที่ 31 ถึง 34)

การบันทึกการตั้งค่าทำได้ 2 วิธี 1) บันทึกลง EEPROM 2) บันทึกลง SPIFFS ในบทความนี้แนะนำให้ใช้ SPIFFS เนื่องจากใช้งานได้ง่ายกว่า EEPROM

แก้ไขโค้ดโปรแกรมให้บันทึก SSID และรหัสผ่านลง SPIFFS และเรียกใช้ข้อมูลที่บันทึกไว้ได้ดังนี้



#include "WiFi.h"
#include "SPIFFS.h"

#define WIFI_SSID_SAVE_FILE_NAME "/ssid.txt"
#define WIFI_PASS_SAVE_FILE_NAME "/pass.txt"

void fileWrite(String fileName, String content) {
  File file = SPIFFS.open(fileName, FILE_WRITE);
  if (!file) {
    Serial.printf("failed to open file '/%s' for writing\n", fileName.c_str());
    return;
  }
  file.print(content);
  file.close();
}

String fileRead(String fileName) {
  File file = SPIFFS.open(fileName, FILE_READ);
  if (!file) {
    Serial.printf("failed to open file '/%s' for reading\n", fileName.c_str());
    return String("");
  }
  String content = file.readString();
  file.close();

  return content;
}

void runSmartConfig() {
  // Delete old configs
  SPIFFS.remove(WIFI_SSID_SAVE_FILE_NAME);
  SPIFFS.remove(WIFI_PASS_SAVE_FILE_NAME);

  WiFi.beginSmartConfig();
  
  Serial.println("Waiting for SmartConfig.");
  while (!WiFi.smartConfigDone()) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("SmartConfig received.");

  // Save configs
  fileWrite(WIFI_SSID_SAVE_FILE_NAME, WiFi.SSID());
  fileWrite(WIFI_PASS_SAVE_FILE_NAME, WiFi.psk());
}

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

  if (!SPIFFS.begin(true)) { // Format if failed
    Serial.println("SPIFFS Mount Failed");
    return;
  }

  // Init WiFi as Station, start SmartConfig
  WiFi.mode(WIFI_AP_STA);

  if (!SPIFFS.exists(WIFI_SSID_SAVE_FILE_NAME)) { // If file ssid don't have
    runSmartConfig();
  } else {
    String txtSSID = fileRead(WIFI_SSID_SAVE_FILE_NAME);
    String txtPassword = fileRead(WIFI_PASS_SAVE_FILE_NAME);

    WiFi.begin(txtSSID.c_str(), txtPassword.c_str());
  }

  // Wait for WiFi to connect to AP
  Serial.println("Waiting for WiFi"); 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("WiFi Connected.");

  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  Serial.print("PSK: ");
  Serial.println(WiFi.psk());
}

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

}

เมื่ออัพโหลดโค้ดโปรแกรมลงบอร์ด หลังจากตั้งค่าการเชื่อมต่อ WiFi แล้ว จะเห็นว่าเมื่อ Reset บอร์ด ค่าที่ตั้งไว้จะถูกเรียกมาใช้อัตโนมัติ


ตัวอย่างการใช้งานจริง

ตัวอย่างการดึง API จำนวนผู้ป่วยโควิด ตั้งค่า WiFi ด้วย SmartConfig โดยใช้ API จาก DDC OPENDATA Covid19 Thailand

โค้ดโปรแกรมหลังจากที่ปรับให้ดึงข้อมูล API มีดังนี้


#include "WiFi.h"
#include "SPIFFS.h"
#include <HTTPClient.h>
#include <WiFiClientSecure.h>

#define WIFI_SSID_SAVE_FILE_NAME "/ssid.txt"
#define WIFI_PASS_SAVE_FILE_NAME "/pass.txt"

void fileWrite(String fileName, String content) {
  File file = SPIFFS.open(fileName, FILE_WRITE);
  if (!file) {
    Serial.printf("failed to open file '/%s' for writing\n", fileName.c_str());
    return;
  }
  file.print(content);
  file.close();
}

String fileRead(String fileName) {
  File file = SPIFFS.open(fileName, FILE_READ);
  if (!file) {
    Serial.printf("failed to open file '/%s' for reading\n", fileName.c_str());
    return String("");
  }
  String content = file.readString();
  file.close();

  return content;
}

void runSmartConfig() {
  // Delete old configs
  SPIFFS.remove(WIFI_SSID_SAVE_FILE_NAME);
  SPIFFS.remove(WIFI_PASS_SAVE_FILE_NAME);

  WiFi.beginSmartConfig();

  Serial.println("Waiting for SmartConfig.");
  while (!WiFi.smartConfigDone()) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("SmartConfig received.");

  // Save configs
  fileWrite(WIFI_SSID_SAVE_FILE_NAME, WiFi.SSID());
  fileWrite(WIFI_PASS_SAVE_FILE_NAME, WiFi.psk());
}

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

  if (!SPIFFS.begin(true)) { // Format if failed
    Serial.println("SPIFFS Mount Failed");
    return;
  }

  // Init WiFi as Station, start SmartConfig
  WiFi.mode(WIFI_AP_STA);

  if (!SPIFFS.exists(WIFI_SSID_SAVE_FILE_NAME)) { // If file ssid don't have
    runSmartConfig();
  } else {
    String txtSSID = fileRead(WIFI_SSID_SAVE_FILE_NAME);
    String txtPassword = fileRead(WIFI_PASS_SAVE_FILE_NAME);

    WiFi.begin(txtSSID.c_str(), txtPassword.c_str());
  }

  // Wait for WiFi to connect to AP
  Serial.println("Waiting for WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("WiFi Connected.");

  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  Serial.print("PSK: ");
  Serial.println(WiFi.psk());
}

void loop() {
  WiFiClientSecure *client = new WiFiClientSecure;
  if (client) {
    client->setInsecure();
    {
      // Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is
      HTTPClient https;

      Serial.print("[HTTPS] begin...\n");
      if (https.begin(*client, "https://covid19.ddc.moph.go.th/api/Cases/today-cases-all")) {  // HTTPS
        Serial.print("[HTTPS] GET...\n");
        // start connection and send HTTP header
        int httpCode = https.GET();

        // httpCode will be negative on error
        if (httpCode > 0) {
          // HTTP header has been send and Server response header has been handled
          Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

          // file found at server
          if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
            String payload = https.getString();
            Serial.println(payload);
          }
        } else {
          Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
        }

        https.end();
      } else {
        Serial.printf("[HTTPS] Unable to connect\n");
      }

      // End extra scoping block
    }

    delete client;
  } else {
    Serial.println("Unable to create client");
  }

  Serial.println();
  Serial.println("Waiting 10s before the next round...");
  delay(10000);
}

หลังจากอัพโหลดโปรแกรม หลังเชื่อมต่อ WiFi ได้ จะเริ่มดึงข้อมูลจาก API และแสดงค่าได้ที่ได้ในกรอบสีแดง


สรุป

การใช้ SmartConfig ตั้งค่าการเชื่อมต่อ WiFi ให้ ESP8266/ESP32 สามารถทำได้ง่ายโดยใช้แอพ ESPTouch โดยต้องจัดการเรื่องการบันทึกการตั้งค่าเอง


ดู 1,060 ครั้ง0 ความคิดเห็น

コメント


bottom of page