ต้องการใส่ Line token ผ่านแอพ เเทนการใส่ตรง ๆ ไปใน arduino

Maokee (Maokeeลูกแมวเหมียว) November 17, 2020, 1:46pm #22
ผมลบไฟล์ตามที่ ขีดไว้เเล้วแต่ติดตรงนี้เหมือนเดิมครับ

ภาพ

ทำไมกระทู้เก่าผมเป็นแบบนี้หว่า

ขออภัยด้วยครับ ตอนนั้นผมไปอัพเดทแล้วไม่ได้ แบคอัพไว้ แล้วเกิดผิดพลาด ข้อมูลเลยหายไป 20% ผมเลยไปตามหาใน index แคช ของ google ที่มันเลยเก็บไว้แล้วเอามาแปะไว้ก่อน

ซึ่งตอนนี้ทำแบคอัพไว้ทุกครั้งแล้วครับ

เบื้องต้นผมจะ Adjust โครงสร้างโพสให้ใหม่ครับ

PUYIOT October 18, 2020, 3:42pm #23

ผมเข้าใจถูกหรือปล่าวครับ

  1. ใช้ ESP32 เชื่อมต่อ WiFi โดยสามารถเลือก SSID และ Password ได้ จากนั้นก็สามารถป้อน ID Line ได้ด้วยใช่มั๊ยครับ
  2. ถ้าเป็นลักษณะตามข้อที่ 1. ก็แสดงว่า Project ของ @Maokee ต้องใช้ Internet ในการส่งไลน์ ใช่มั๊ยครับ
    ถ้าเป็นตามนี้จรืง ก็ไม่ยากเกินไปครับ มันทำได้อยู่แล้วครับ และเป็นอย่างที่ @Remy_Martin และ @KD2NYY แนะนำไว้แล้วครับ ส่วนข้อมูลเพิ่มเติมติดขัดอย่างไร มีคนช่วยรุมๆ กันตอบ เดี๋ยวก็ได้ครับ :sweat_smile:

Maokee (Maokeeลูกแมวเหมียว) November 17, 2020, 1:46pm #24

ตอนนี้สามารถรันโค้ดได้เเล้วครับ ถูกต้องตามที่พี่เข้าใจเลยครับ แต่ตอนนี้ผมไม่เข้าใจว่ามันจะขึ้นหน้าให้ config wifi ตอนที่เราเลือก wifi หรือเราต้องเปิด browser เเล้วเข้า url ตามที่เราฟิกอะครับ

image

Maokee (Maokeeลูกแมวเหมียว) November 17, 2020, 1:46pm #25

ผมเข้าใจว่ามันจะขึ้นชื่อ wifi ให้เชื่อมต่อก่อนเเล้วมันจะพาไปยัง url หน้าที่ให้ config wifi ,token เเต่ว่ามันหาชื่อ wifi ไม่เจอ

image

Remy_Martin (Permpol Thanapunnamas) October 19, 2020, 12:22am #26

อันนี้ผมก็ไม่แน่ใจว่ามันคืออะไรเวลาที่เชื่อมแล้วมันไปที่หน้าคอนฟิกเลย อันนี้น่าสนใจว่า อาจจะพัฒนาต่อไปได้

แต่อันที่ใช้เราต้องเปิด url ขึ้นมาเองก่อนนะครับ

Remy_Martin (Permpol Thanapunnamas) October 19, 2020, 12:23am #27

สรุปกรณีนี้ให้หน่อยครับว่า แก้ไขได้อย่างไร

KD2NYY (Thanasak) October 19, 2020, 12:34am #28

แล้วแต่เครื่อง ครับ บางเครื่อง Connect Wifi แล้ว ก็จะไปหน้า URL. ให้เลย แต่บางเครื่อง ก็ต้องป้อน URL. เองครับ ( เป็นที่ OS. ของมือถือ )

1 Like

Remy_Martin (Permpol Thanapunnamas) October 19, 2020, 2:30am #29

ขอบคุณสำหรับ ข้อมูลครับผม :grin:

Maokee (Maokeeลูกแมวเหมียว) October 19, 2020, 4:21am #30

ในโค้ดเหมือนต้องกดปุ่มก่อนหรือเปล่าครับถึงจะขึ้นชื่อwifi จากบอร์ด

PUYIOT October 19, 2020, 4:29am #31

ครับเดี๋ยวเราเริ่มต้นต้นที่ Code นี้ก่อน คือกดปุ่มเพื่อเชื่อมต่อ SSID กับ Password ของ WiFi ที่เราต้องการเชื่อมต่อด้วย

#include <FS.h>                   //this needs to be first, or it all crashes and burns...
#include <SPIFFS.h>//เพิ่ม

#include <WiFi.h>          //https://github.com/esp8266/Arduino
#include <WiFiClient.h>


//needed for library
#include <DNSServer.h>
#include <WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>       //Ver 5.13.4   //https://github.com/bblanchon/ArduinoJson
//------------------------------------------------------------------------------------------------------------------------//
//#include <BlynkSimpleEsp32.h>          //  Blynk_Release_v0.6.1
//------------------------------------------------------------------------------------------------------------------------//


//------------------------------        การกำหนดค่าในส่วนของ Blynk         ------------------------------------------------//
//#define BLYNK_DEBUG
//#define BLYNK_PRINT Serial
//int blynkIsDownCount = 0;
//
//char blynk_token[34] = "lE0j-VJUuIZ3mBZYfpcHqCT36ak29gdU";//ใส่ Blynk_token ของเราที่ Blynk ส่งมาทาง Email ตอน Create Project ใหม่
//
//BlynkTimer timer;  //เรียกใช้การตั้งเวลาของ Blynk

//----------------------------------  กำหนดหมายเลขของขาของ Node MCU ESP32  --------------------------------------------//

const int Ledblynk = 2;                     // ใช้ไฟ LED สีฟ้า ของบอร์ด MCU ESP32 ให้มีสัญญาณไฟกระพริบ ตาม Code ที่เขียน
const int AP_Config = 23;                // ใช้เป็นปุ่มกด เพื่อเข้า AP Config ได้ตามความต้องการของผู้ใช้
//------------------------------------------------------------------------------------------------------------------------//



bool shouldSaveConfig = false;

//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}
//------------------------------------------------------------------------------------------------------------------------//


//-------------สำหรับ Server local ที่แจกให้ เพิ่ม **** แค่ 2 บรรทัดนี้--------------   (ถ้าเป็น Blynk Server ปกติไม่ต้องใส่)  ----------//
//char server[] = "oasiskit.com";
//int port = 8080;
//------------------------------------------------------------------------------------------------------------------------//





//------------------------------------------------------------------------------------------------------------------------//
//*********************************************       void setup        **************************************************//
//------------------------------------------------------------------------------------------------------------------------//

void setup() {

  //-------IO NODE MCU Esp32-------//
  pinMode(Ledblynk, OUTPUT);      //กำหนดโหมดใช้งานให้กับขา Ledblynk เป็นขา สัญญาณไฟ ในสภาวะต่างๆ
  pinMode(AP_Config, INPUT_PULLUP);//กำหนดโหมดใช้งานให้กับขา AP_Config เป็นขา กดปุ่ม ค้าง เพื่อตั้งค่า AP config


  // ให้ LED ทั้งหมดดับก่อน
  digitalWrite(Ledblynk, LOW);//ให้หลอด LED สีฟ้าดับก่อน

  //-------------------------------//


  Serial.begin(115200);
  //-------------------------------//





  //*************************    การ อ่าน  เขียนค่า WiFi + Password ]ลงใน Node MCU ESP32   ************//

  //read configuration from FS json
  Serial.println("mounting FS...");//แสดงข้อความใน Serial Monitor

  if (SPIFFS.begin(true)) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");
          //strcpy(blynk_token, json["blynk_token"]);

        } else {
          Serial.println("failed to load json config");//แสดงข้อความใน Serial Monitor
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");//แสดงข้อความใน Serial Monitor
  }
  //end read
  //Serial.println(blynk_token);

  //*************************   จบการ อ่าน  เขียนค่า WiFi + Password ]ลงใน Node MCU ESP32   **********//









  //**************************        AP AUTO CONNECT   ********************************************//

  //WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34);

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  //wifiManager.addParameter(&custom_blynk_token);


  for (int i = 5; i > -1; i--) {  // นับเวลาถอยหลัง 5 วินาทีก่อนกดปุ่ม AP Config
    digitalWrite(Ledblynk, HIGH);
    delay(500);
    digitalWrite(Ledblynk, LOW);
    delay(500);
    Serial.print (String(i) + " ");//แสดงข้อความใน Serial Monitor
  }


  if (digitalRead(AP_Config) == LOW) {
    digitalWrite(Ledblynk, HIGH);
    Serial.println("Button Pressed");//แสดงข้อความใน Serial Monitor



    // wifiManager.resetSettings();//ให้ล้างค่า SSID และ Password ที่เคยบันทึกไว้
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //load the flash-saved configs
    esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails)
    delay(2000); //wait a bit
    if (esp_wifi_restore() != ESP_OK)

    {
      Serial.println("WiFi is not initialized by esp_wifi_init ");
    } else {
      Serial.println("WiFi Configurations Cleared!");
    }
    //continue
    //delay(1000);
    //esp_restart(); //just my reset configs routine...


  }

  wifiManager.setTimeout(60);
  //ใช้ได้ 2 กรณี
  //1. เมื่อกดปุ่มเพื่อ Config ค่า AP แล้ว จะขึ้นชื่อ AP ที่เราตั้งขึ้น
  //   ช่วงนี้ให้เราทำการตั้งค่า SSID+Password หรืออื่นๆทั้งหมด ภายใน 60 วินาที ก่อน AP จะหมดเวลา
  //   ไม่เช่นนั้น เมื่อครบเวลา 60 วินาที MCU จะ Reset เริ่มต้นใหม่ ให้เราตั้งค่าอีกครั้งภายใน 60 วินาที
  //2. ช่วงไฟดับ Modem router + MCU จะดับทั้งคู่ และเมื่อมีไฟมา ทั้งคู่ก็เริ่มทำงานเช่นกัน
  //   โดยปกติ Modem router จะ Boot ช้ากว่า  MCU ทำให้ MCU กลับไปเป็น AP รอให้เราตั้งค่าใหม่
  //   ดังนั้น AP จะรอเวลาให้เราตั้งค่า 60 วินาที ถ้าไม่มีการตั้งค่าใดๆ เมื่อครบ 60 วินาที MCU จะ Reset อีกครั้ง
  //   ถ้า Modem router  Boot และใช้งานได้ภายใน 60 วินาที และหลังจากที่ MCU Resset และเริ่มทำงานใหม่
  //   ก็จะสามารถเชื่อมต่อกับ  Modem router ที่ Boot และใช้งานได้แล้ว  ได้  ระบบจะทำงานปกติ

  if (!wifiManager.autoConnect("ESP32 AP CONFIG")) {
    Serial.println("failed to connect and hit timeout");//แสดงข้อความใน Serial Monitor
    delay(3000);
    //reset and try again, or maybe put it to deep sleep
    ESP.restart();//แก้ เดิม ESP.reset(); ใน Esp8266
    delay(5000);

  }

  Serial.println("Connected.......OK!)");//แสดงข้อความใน Serial Monitor
  //strcpy(blynk_token, custom_blynk_token.getValue());


  //save the custom parameters to FS
  if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    //json["blynk_token"] = blynk_token;
    File configFile = SPIFFS.open("/config.json", "w");

    if (!configFile) {
      Serial.println("failed to open config file for writing");//แสดงข้อความใน Serial Monitor

    }
    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
  }

  //**************************    จบ    AP AUTO CONNECT   *****************************************//




  Serial.println("local ip"); //แสดงข้อความใน Serial Monitor
  delay(100);
  Serial.println(WiFi.localIP());//แสดงข้อความใน Serial Monitor
  Serial.println("gateway");
  delay(100);
  Serial.println(WiFi.gatewayIP());
  Serial.println("subnetMask");
  delay(100);
  Serial.println(WiFi.subnetMask());
  Serial.println("SSID");
  delay(100);
  Serial.println(WiFi.SSID());
  Serial.println("Password");
  delay(100);
  Serial.println(WiFi.psk());

  // Blynk.config(blynk_token);////เริ่มการเชื่อมต่อ Blynk Server แบบปกติ
  //Blynk.config(blynk_token, server, port);
  ////เริ่มการเชื่อมต่อ Blynk Server*********สำหรับ Server local ที่แจกให้ เพิ่ม, server, port  แค่นี้จบ



  //timer.setInterval(30000L, reconnecting);  //Function reconnect

  //ตั้งเวลาส่งข้อมูลให้ Blynk Server ทุกๆ 30 วินาที


}


//------------------------------------------------------------------------------------------------------------------------//
//*********************************************   จบ  void setup        **************************************************//
//------------------------------------------------------------------------------------------------------------------------//


//------------------------------------------------------------------------------------------------------------------------//
//*********************************************       void Loop        ***************************************************//
//------------------------------------------------------------------------------------------------------------------------//


void loop() {


  //-----------------------------------------------------------------------------------------------------------//
  //  if (Blynk.connected())
  //  {
  //    Blynk.run();
  //    digitalWrite(Ledblynk, HIGH);
  //
  //  } else {
  //
  //    digitalWrite(Ledblynk, LOW);
  //    delay(200);
  //    digitalWrite(Ledblynk, HIGH);
  //    delay(100);

  //  }
  //-----------------------------------------------------------------------------------------------------------//

  //  timer.run();//ให้เวลาของ Blynk ทำงาน
  //
  //  delay(100);


}

//------------------------------------------------------------------------------------------------------------------------//
//*********************************************      จบ void Loop       **************************************************//
//------------------------------------------------------------------------------------------------------------------------//




//------------------------------------------------------------------------------------------------------------------------//
//void reconnecting()
//{
//  if (!Blynk.connected())
//  {
//    blynkIsDownCount++;
//    BLYNK_LOG("blynk server is down! %d  times", blynkIsDownCount);
//    Blynk.connect(5000);
//  }
//}

ไปทีละขั้นนะครับ

ภาพ

ทำปุ่ม AP Config button ไว้ปุ่มเดียวก็ได้นะครับ

ใช้ WiFi Manager ของตัวนี้ครับ
WIFIMANAGER-ESP32-master.rar (32.0 KB)

เมื่อ Upload code เสร็จ เปิด Serial monitor มันจะนับ 5 วินาที ช่วง 5 วินาที ก็ให้กดปุ่ม AP Config button ค้างไว้นะครับ ค้างไว้จนกว่า จะครบ 5 วินาที แล้วปล่อยปุ่ม

ทีนี้ก็เปิดหา WiFi ใน มือถือ หรือในคอมพิวเตอร์ก็ได้ จะเจอ
1

Maokee (Maokeeลูกแมวเหมียว) October 19, 2020, 4:30am #32

แล้วถ้าผมจะใช้แบบไม่มีปุ่ม ผมไล่ลบโค้ดส่วนของปุ่มออกเลยไหมครับ แต่ลองลบดูก็ยังไม่ขึ้น :sweat_smile:
ปล.อยากได้แบบว่าไปหน้าคอนฟิกแบบไม่กดปุ่ม

PUYIOT October 19, 2020, 4:35am #33

แล้วแต่ลักษณะงานครับ
ที่ผมทำปุ่มเอาไว้มีสาเหตุคือเมื่อเรานำ product ของเราไปให้กับทางลูกค้าแล้วลูกค้าสามารถที่จะตั้งค่า Config WiFi เองได้เลย หรือถ้าลูกค้านำไปอีกสถานที่หนึ่งก็สามารถกดปุ่ม Config ได้เลยเช่นกัน เมื่อคอนฟิกค่าไปแล้ว มันก็จะจำค่า SSID และ password ค่านั้นตลอดเมื่อเกิด WiFi หลุดขึ้นมา แล้ว WiFi กลับมาอีกครั้ง esp8266 ก็จะวนเข้าไปรับ SS ID และ password ที่เราตั้งค่าเอาไว้ก่อนหน้านี้ได้ และระบบก็จะเชื่อมต่อ WiFi ได้ปกติครับ
แต่ถ้าไม่มีปุ่มจะเกิดปัญหาคือ เราไม่ทราบว่า WiFi หลุดแล้วเราต้องกลับเข้าไปเชื่อมต่อเอง ซึ่งมันก็ไม่สะดวกสำหรับหน้างาน

Maokee (Maokeeลูกแมวเหมียว) October 19, 2020, 4:36am #34

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

PUYIOT October 19, 2020, 4:39am #35

ถ้าอย่างนั้นลองดูใน Example ของ esp32 ดูก็ได้ครับ เพราะผมเองก็ไม่เคยลองครับ แต่ถ้าเป็นแบบที่ผมทำอยู่ก็ ไกด์ไลน์ให้ได้ครับ ยังไงลองแบบที่ @Maokee ต้องการก่อนก็ได้ครับ

Maokee (Maokeeลูกแมวเหมียว) October 19, 2020, 4:55am #36

เลิกงานเดี๋ยวจะลองดูครับ

Maokee (Maokeeลูกแมวเหมียว) November 17, 2020, 1:46pm #38

ผมทำตามนี้เเล้วลองใส่ในส่วนของไลน์สามารถทำได้เเล้วครับ เเต่ในตัวอย่างนั้นไม่มีช่อง Label สำหรับใส่ในส่วนของ token ดังรูปล่าง
อยากให้มี label ให้ใส่ token เหมือนรูปที่ บน ควรเพิ่มอะไรตรงไหนครับอยากได้สัก3 label เอาไว้ใส่ประมาณ3 token ครับ

ภาพ

ภาพ

PUYIOT October 24, 2020, 3:29pm #39

23/10/256ลองดูว่า complie ผ่านหรือปล่าวครับ ผมยังไม่ได้ลอง เครื่อง ยังไม่ลง Esp32 ครับ

24/10/2563 ลอง Copy Code ดูใหม่อีกรอบนะครับ ผมแก้ให้แล้ว ลองทดสอบและ เรียนรู้ Code ดูนะครับ ว่ายังมีจุดไหนที่มีปัญหาอีก ค่อยๆ แก้กันไปครับ :grin:

#include <FS.h>                   //this needs to be first, or it all crashes and burns...
#include <SPIFFS.h>//เพิ่ม

#include <WiFi.h>          //https://github.com/esp8266/Arduino
#include <WiFiClient.h>


//needed for library
#include <DNSServer.h>
#include <WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>       //Ver 5.13.4   //https://github.com/bblanchon/ArduinoJson
//------------------------------------------------------------------------------------------------------------------------//


char line_token1[45] = "";//
char line_token2[45] = "";//
char line_token3[45] = "";//

//----------------------------------  กำหนดหมายเลขของขาของ Node MCU ESP32  --------------------------------------------//

const int Ledblynk = 2;                     // ใช้ไฟ LED สีฟ้า ของบอร์ด MCU ESP32 ให้มีสัญญาณไฟกระพริบ ตาม Code ที่เขียน
const int AP_Config = 23;                // ใช้เป็นปุ่มกด เพื่อเข้า AP Config ได้ตามความต้องการของผู้ใช้
//------------------------------------------------------------------------------------------------------------------------//



bool shouldSaveConfig = false;

//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}
//------------------------------------------------------------------------------------------------------------------------//





//------------------------------------------------------------------------------------------------------------------------//
//*********************************************       void setup        **************************************************//
//------------------------------------------------------------------------------------------------------------------------//

void setup() {

  //-------IO NODE MCU Esp32-------//
  pinMode(Ledblynk, OUTPUT);      //กำหนดโหมดใช้งานให้กับขา Ledblynk เป็นขา สัญญาณไฟ ในสภาวะต่างๆ
  pinMode(AP_Config, INPUT_PULLUP);//กำหนดโหมดใช้งานให้กับขา AP_Config เป็นขา กดปุ่ม ค้าง เพื่อตั้งค่า AP config


  // ให้ LED ทั้งหมดดับก่อน
  digitalWrite(Ledblynk, LOW);//ให้หลอด LED สีฟ้าดับก่อน

  //-------------------------------//


  Serial.begin(115200);
  //-------------------------------//





  //*************************    การ อ่าน  เขียนค่า WiFi + Password ]ลงใน Node MCU ESP32   ************//

  //read configuration from FS json
  Serial.println("mounting FS...");//แสดงข้อความใน Serial Monitor

  if (SPIFFS.begin(true)) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");
          strcpy(line_token1, json["line_token1"]);
          strcpy(line_token2, json["line_token2"]);
          strcpy(line_token3, json["line_token3"]);


        } else {
          Serial.println("failed to load json config");//แสดงข้อความใน Serial Monitor
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");//แสดงข้อความใน Serial Monitor
  }
  //end read
  Serial.println(line_token1);

  //*************************   จบการ อ่าน  เขียนค่า WiFi + Password ]ลงใน Node MCU ESP32   **********//



  WiFiManagerParameter custom_text0("<p> </p>");
  WiFiManagerParameter custom_text1("<label>1:  ID Line 1 </label>");
  WiFiManagerParameter custom_text2("<label>2:  ID Line 2 </label>");
  WiFiManagerParameter custom_text3("<label>3:  ID Line 3 </label>");


  //**************************        AP AUTO CONNECT   ********************************************//

  WiFiManagerParameter custom_line_token1("line_token1", "line_token1", line_token1, 45);
  WiFiManagerParameter custom_line_token2("line_token2", "line_token2", line_token2, 45);
  WiFiManagerParameter custom_line_token3("line_token3", "line_token3", line_token3, 45);
  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  wifiManager.addParameter(&custom_text0);
  wifiManager.addParameter(&custom_text1);
  wifiManager.addParameter(&custom_line_token1);


  wifiManager.addParameter(&custom_text0);
  wifiManager.addParameter(&custom_text2);
  wifiManager.addParameter(&custom_line_token2);


  wifiManager.addParameter(&custom_text0);
  wifiManager.addParameter(&custom_text3);
  wifiManager.addParameter(&custom_line_token3);



  for (int i = 5; i > -1; i--) {  // นับเวลาถอยหลัง 5 วินาทีก่อนกดปุ่ม AP Config
    digitalWrite(Ledblynk, HIGH);
    delay(500);
    digitalWrite(Ledblynk, LOW);
    delay(500);
    Serial.print (String(i) + " ");//แสดงข้อความใน Serial Monitor
  }


  if (digitalRead(AP_Config) == LOW) {
    digitalWrite(Ledblynk, HIGH);
    Serial.println("Button Pressed");//แสดงข้อความใน Serial Monitor



    // wifiManager.resetSettings();//ให้ล้างค่า SSID และ Password ที่เคยบันทึกไว้
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //load the flash-saved configs
    esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails)
    delay(2000); //wait a bit
    if (esp_wifi_restore() != ESP_OK)

    {
      Serial.println("WiFi is not initialized by esp_wifi_init ");
    } else {
      Serial.println("WiFi Configurations Cleared!");
    }
    //continue
    //delay(1000);
    //esp_restart(); //just my reset configs routine...


  }


  wifiManager.setTimeout(90);
  //ใช้ได้ 2 กรณี
  //1. เมื่อกดปุ่มเพื่อ Config ค่า AP แล้ว จะขึ้นชื่อ AP ที่เราตั้งขึ้น
  //   ช่วงนี้ให้เราทำการตั้งค่า SSID+Password หรืออื่นๆทั้งหมด ภายใน 60 วินาที ก่อน AP จะหมดเวลา
  //   ไม่เช่นนั้น เมื่อครบเวลา 60 วินาที MCU จะ Reset เริ่มต้นใหม่ ให้เราตั้งค่าอีกครั้งภายใน 60 วินาที
  //2. ช่วงไฟดับ Modem router + MCU จะดับทั้งคู่ และเมื่อมีไฟมา ทั้งคู่ก็เริ่มทำงานเช่นกัน
  //   โดยปกติ Modem router จะ Boot ช้ากว่า  MCU ทำให้ MCU กลับไปเป็น AP รอให้เราตั้งค่าใหม่
  //   ดังนั้น AP จะรอเวลาให้เราตั้งค่า 60 วินาที ถ้าไม่มีการตั้งค่าใดๆ เมื่อครบ 60 วินาที MCU จะ Reset อีกครั้ง
  //   ถ้า Modem router  Boot และใช้งานได้ภายใน 60 วินาที และหลังจากที่ MCU Resset และเริ่มทำงานใหม่
  //   ก็จะสามารถเชื่อมต่อกับ  Modem router ที่ Boot และใช้งานได้แล้ว  ได้  ระบบจะทำงานปกติ



  if (!wifiManager.autoConnect("PUYIOT ESP32 AP CONFIG")) {
    Serial.println("failed to connect and hit timeout");//แสดงข้อความใน Serial Monitor
    delay(3000);
    //reset and try again, or maybe put it to deep sleep
    ESP.restart();//แก้ เดิม ESP.reset(); ใน Esp8266
    delay(5000);

  }

  Serial.println("Connected.......OK!)");//แสดงข้อความใน Serial Monitor
  strcpy(line_token1, custom_line_token1.getValue());
  strcpy(line_token2, custom_line_token2.getValue());
  strcpy(line_token3, custom_line_token3.getValue());

  //save the custom parameters to FS
  if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();

    json["line_token1"] = line_token1;
    File configFile = SPIFFS.open("/config.json", "w");

    json["line_token2"] = line_token2;
    File configFile2 = SPIFFS.open("/config.json", "w");



    json["line_token3"] = line_token3;
    File configFile3 = SPIFFS.open("/config.json", "w");


    if (!configFile) {
      Serial.println("failed to open config file for writing");//แสดงข้อความใน Serial Monitor

    }
    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();

    json.printTo(configFile2);
    configFile2.close();

    json.printTo(configFile3);
    configFile3.close();
    //end save
  }

  //**************************    จบ    AP AUTO CONNECT   *****************************************//




  Serial.println("local ip"); //แสดงข้อความใน Serial Monitor
  delay(100);
  Serial.println(WiFi.localIP());//แสดงข้อความใน Serial Monitor
  Serial.println(WiFi.gatewayIP());
  Serial.println(WiFi.subnetMask());


  Serial.println(line_token1);
  Serial.println(line_token2);
  Serial.println(line_token3);

}


//------------------------------------------------------------------------------------------------------------------------//
//*********************************************   จบ  void setup        **************************************************//
//------------------------------------------------------------------------------------------------------------------------//


//------------------------------------------------------------------------------------------------------------------------//
//*********************************************       void Loop        ***************************************************//
//------------------------------------------------------------------------------------------------------------------------//


void loop() {



  delay(100);


}

//------------------------------------------------------------------------------------------------------------------------//
//*********************************************      จบ void Loop       **************************************************//
//------------------------------------------------------------------------------------------------------------------------//

ID Line Token 3 ตัว + Label มีเวลาในการ Config AP + ใส่ค่า ID Line Token 3 ตัว 1.30 นาที ถ้าเลยจากนี้ Esp32 จะ Restart ใหม่ ให้กดปุ่ม AP Config ใหม่อีกรอบนะครับ