การใช้งานติดฟังก์ชั่น Wifi Manager รบกวนผู้รู้ช่วยหน่อยครับ

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

  1. เปิด-ปิดถังโดยไม่เชื่อมไวไฟ
  2. เปิด-ปิดถังและแจ้งเตือนผ่านไลน์โดยเชื่อมไวไฟ
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <TridentTD_LineNotify.h>
#include <Servo.h>

Servo myservo;
#define LINE_TOKEN  "nYczuXng44ykxZObO1TcjLUZmIqQ0q6WTLeYSnTBmxo" 

int LEDD0 = D0; // ไฟขา D0
int LEDD4 = D4; // ไฟขา D4
int Max = 24;    //กำหนดความลึกของถัง โดยวัดจากขณะไม่มีขยะ
int detect = 30; //กำหนดระยะที่คนเดินผ่านแล้วเปิด

void setup()
{
  Serial.begin(9600);     //กำหนด Board rate
  WiFiManager wifiManager;   
  if(!wifiManager.autoConnect("Auto Trash Bin")) 
   {
     Serial.println("Failed to connect and hit timeout");
     delay(3000);
     ESP.reset();
     delay(5000);
   }
  WiFi.printDiag(Serial);
  Serial.println();
  Serial.println("connected...OK");  
  LINE.setToken(LINE_TOKEN); //กำหนด Token ของไลน์
  
  ESP.wdtDisable();       //ปิดการใช้งาน wdt
  ESP.wdtEnable(WDTO_8S); //เปิดการใช้งาน wdt ที่ 8 วินาที
  Serial.println(LINE.getVersion()); 

  myservo.attach(D1); //ประกาศขาสัญญาณของ servo
  servo("CLOSE");     //ให้ servo ปิด
  pinMode(LEDD0, OUTPUT);
  pinMode(LEDD4, OUTPUT);
  digitalWrite(LEDD0, LOW);
  digitalWrite(LEDD4, LOW);
}

bool level[3];
int Dis = 50 ;
int free_space = 24;
int garbage = 24;

void loop()
{
  while (1)
  {
    static uint32_t t_tms15, t_tms500;
    if (millis() - t_tms15 >= 15) //ลูปนี้ จะทำงานทุก 15 ms
    {
      t_tms15 = millis();
      if (Dis < detect) //ถ้าระยะที่อ่านได้ น้อยกว่าที่ตั้ง 
      {
        servo("OPEN"); //ให้ servo เปิด
      }
      else              //ถ้าไม่ใช่
      {
        servo("CLOSE"); //ให้ servo ปิด
      }
    }
    if (millis() - t_tms500 >= 500) //ลูปนี้ จะทำงานทุก 500 ms
    {
      t_tms500 = millis();
      Dis = sonic(D2, D3);     //อ่านค่าจาก ultrasonic ที่ตรวจจับคน ดึงเข้าตัวแปรชื่อ Dis
      Serial.println("Distance" + String(Dis));
      free_space = sonic(D5, D6);  //อ่านค่าจาก ultrasonic ที่ตรวจจับปริมาณขยะ ดึงเข้าตัวแปรชื่อ free_space
      Serial.println("free_space" + String(free_space));
      garbage = Max - free_space;     //นำความลึกจากเซ็นเซอร์ถึงก้นถังขยะ(ที่ตั้งไว้)ลบกับความลึกจากเซ็นเซอร์ถึงบนขยะจะได้ความสูงขยะ
      garbage = map(garbage, Max, 0, 100, 0); //นำความสูงของขยะมาแปลงเป็น 0 - 100%
      Serial.println(String(garbage) + "%");        //แสดง %
      Serial.println("====================================="); 
      Serial.println(String(garbage) + "%");        
      Serial.println(String("level[3] == ") + level[3]); 
      Serial.println(String("level[2] == ") + level[2]); 
      Serial.println(String("level[1] == ") + level[1]); 
      Serial.println("=====================================");
      
      if (Dis > detect)               //ถ้าไม่มีคนแสดงว่าฝาปิดอยู่
      {
        if((garbage >= 80) && level[2] == 0)        //ถ้าเกิน 80% และตัวแปรตัว level ตัวที่ 2 ยังไม่แจ้งเตือน
        {
          LINE.notify("ถังขยะใกล้เต็มแล้ว"); //ให้ส่งข้อความนี้ออกไปที่ไลน์
          level[2] = 1;                   //กำหนดให้ตัวแปรตัว level ตัวที่ 3 แจ้งเตือนแล้ว
        }
        else if((garbage >= 60) && level[1] == 0)   //ถ้าเกิน 60% และตัวแปรตัว level ตัวที่ 1 ยังไม่แจ้งเตือน
        {
          LINE.notify("มีขยะประมาณ 60%"); //ให้ส่งข้อความนี้ออกไปที่ไลน
          level[1] = 1;                   //กำหนดให้ตัวแปรตัว level ตัวที่ 1 แจ้งเตือนแล้ว
        }
        else if(garbage <= 10)//ถ้าไม่มีขยะ หรือขยะถูกนำออกแล้ว
        {
          for(int i = 1;i<=2;i++) level[i] = 0; //กำหนดให้ตัวแปรตัว level ตัวที่ 1-3 ยังไม่แจ้งเตือน
        }
      }
    }
        if (millis() - t_tms500 >= 500) //ลูปนี้ จะทำงานทุก 500 ms
        {
            t_tms500 = millis();
      
          if(garbage >= 80)
          {
            digitalWrite(LEDD0, HIGH);
            digitalWrite(LEDD4, LOW);
          }
          else
          {
            digitalWrite(LEDD4, HIGH);
            digitalWrite(LEDD0, LOW);
          }
        }
    ESP.wdtFeed(); //รีเซ็ทค่า wdt
  }
}
int sonic(int Trig, int Echo)  //ฟังชั่นอ่านค่า Ultrasonic โดยระบุขา Trig และ Echo ลงในวงเล็บตามลำดับ
{
  long duration;
  int cm;
  pinMode(Trig, OUTPUT);
  digitalWrite(Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);
  delayMicroseconds(5);
  digitalWrite(Trig, LOW);
  pinMode(Echo, INPUT);
  duration = pulseIn(Echo, HIGH);

  cm = microsecondsToCentimeters(duration);

  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  return cm;
}
long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

void servo(String cmd) //ฟังชั่น servo
{
  if (cmd == "OPEN") //ถ้ามีคำสั่ง OPEN
  {
   myservo.write(30);   //ให้ servo หมุนไปที่ 30 องศา
  }
  if (cmd == "CLOSE")//ถ้ามีคำสั่ง CLOSE
  {
    myservo.write(0);   //ให้ servo หมุนไปที่ 0 องศา
  }
}

จะใช้อะไรสั่งการครับถ้าไม่เชื่อม

Ultrasonic ครับ

เอ๋ปกติก็ไม่จำเป็นต้องเชื่อมก็ควรจะใช้ได้นะครับ

ผมจะใช้ wifi ส่งไลน์อย่างเดียวอะครับ แบบสมมติถ้าสัญญาณมันหายไปก็สามารถเชื่อมใหม่ได้โดยที่ไม่รบกวนการทำงานของ การเปิดปิดฝาถังอะครับ

เหมือนกับมันบังคับให้เชื่อมตัวไวไฟก่อนอะครับไม่งั้นมันจะไม่ปล่อยผ่านโค้ดบรรทัดนี้ไปครับ มันนอไวไฟอย่างเดียวเลย


  myservo.attach(D1); //ประกาศขาสัญญาณของ servo
  servo("CLOSE");     //ให้ servo ปิด
  pinMode(LEDD0, OUTPUT);
  pinMode(LEDD4, OUTPUT);
  digitalWrite(LEDD0, LOW);
  digitalWrite(LEDD4, LOW);

ตอนไม่เชื่อมมันทำอะไรได้บ้างครับ

ทำอะไรไม่ได้เลยครับ ultrasonic ไม่อ่านค่าทั้ง 2 ตัว ไฟ led ก็ไม่ติดครับ

กด Serial ดู แล้วแคปมาครับ

ตอนนี้ไฟดับอยู่ครับเดี๋ยวถ้าไฟมาแล้วผมจะแคปให้ดูนะครับ


มันติดตรงนี้ครับ มันค้างหน้านี้ไม่เข้าลูป

ปกติแล้วถ้ามีไวไฟ เปิดมามันเข้าหน้านี้ทุกครั้งป่ะครับ หรือมันเข้าเลยเพราะเคยเซตไว้แล้วครั้งหนึ่ง

อันนี้เมื่อมันไม่เจอไวไฟตัวเดิมที่เคยเชื่อมันจะขึ้นแบบนี้ครับ มันยังไม่เชื่อมไวไฟเลยขึ้นแบบนี้ครับ

ในความเห็นของผมนะครับ
ในส่วนที่ 1
Code ชุด Wifi Manager ควรจะใช้ร่วมกับ Arduinojson และระบบการกดปุ่ม Config ตัว wifi ด้วยครับ ระบบจึงจะทำงานได้แบบมีเสถียรภาพ โดยมีลักษณะการทำงานคือ เมื่อกดปุ่ม Config ค่า WiFi แล้ว ถ้าเจอกรณี ที่ WiFiหาย ระบบจะทำการวนการเชื่อมต่อ WiFi ตัวเดิมที่ตั้งค่าไว้ ตลอดเวลา จนกว่า WiFi ชุดเดิมจะกลับมา โดยมันจะไม่ กลับไปที่การ Config ค่า WiFi ใหม่ทุกครั้งที่ WiFi มีปัญหา ถ้าเราทำจุดนี้ผ่านได้ การทำงานของระบบก็จะไม่เกิดปัญหา
ในส่วนที่ 2
เป็นเรื่องของการควบคุมอุปกรณ์ เช่นส่ง Line เมื่อระบบถูกกำหนดให้ทำงานตามเงื่อนไข ,อุปกรณ์ทำงานตามเงื่อนไข โดยต้องใช้ได้ทั้ง 2 กรณี คือมี WiFi และไม่มี WiFi ครับ

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

ใช่ครับ ผมคิดว่าเราควรแก้เรื่อง ระบบการเชื่อมต่อ WiFi ก่อนครับ

แก้ยังไงครับพอมีแนวทางไหมครับ

ลองดู Code ชุดนี้ครับ
ความต้องการของฮาร์ดแวร์และซอฟต์แวร์

  1. Esp 8266 v2
  2. Arduino ide 1.8.7 - 1.8.9
  3. ArduinoJson-5.13.3

สำหรับ Code ชุดนี้ จะมีขั้นตอนดังนี้

  1. ตั้งค่า AP Config เพื่อเชื่อมต่อ SSID และ Password ของ WiFi โดยกดปุ่ม Push button ค้างไว้ก่อน 5 วินาที (LED สีน้ำเงินจะทำการกระพริบ ) หลังจากที่อัพโหลด Code ครั้งแรก จากนั้น จะเข้าสู่ web portal ของ WiFi Manager แล้วเชื่อมต่อ ssid และ Password ของ WiFi ที่ต้องการ

  2. เมื่อ esp 8266 เชื่อมต่อ WiFi ได้แล้ว จะยังไม่ส่งข้อความออกมาทางไลน์ ต้องรอให้เชื่อมต่ออินเทอร์เน็ตได้เสียก่อน จึงจะส่งข้อความทางไลน์ออกมา ดูหลอด LED สีน้ำเงินจะติดค้าง เพื่อแสดงให้เรารู้ว่ามีการเชื่อมต่อ WiFi ได้และต่ออินเตอร์เน็ตได้เรียบร้อย

  3. ทดสอบปิด Modem Router เราจะเห็นว่า esp 8266 หลอด LED สีน้ำเงิน จะทำการกระพริบ เพื่อให้เราทราบว่าขณะนี้ การเชื่อมต่อ WiFi และอินเทอร์เน็ตมีปัญหา

  4. ทดสอบเปิด Modem Router esp 8266 ก็จะทำการเชื่อมต่อ WiFi อีกครั้งและถ้าเชื่อมต่อ WiFi ได้แล้ว จะยังไม่ส่งข้อความออกมาทางไลน์ ต้องรอให้เชื่อมต่ออินเทอร์เน็ตได้เสียก่อน จึงจะส่งข้อความทางไลน์ออกมา ดูหลอด LED สีน้ำเงินจะติดค้าง เพื่อแสดงให้เรารู้ว่ามีการเชื่อมต่อ WiFi ได้และต่ออินเตอร์เน็ตได้เรียบร้อย

  5. กรณีที่ปิด Router และปิด esc 8266 พร้อมกันหรือกรณีไฟดับเมื่อไฟมา esp 8266 และ Modem Router จะทำงานพร้อมกันแต่ Modem Router จะทำงานช้ากว่า esp 8266 จะทำงาน แต่ไฟจะไม่กระพริบ ต้องรอสักระยะหนึ่งเพื่อให้มันสามารถเชื่อมต่อ WiFi และอินเทอร์เน็ตได้จากนั้นมันจะส่งไลน์กลับมาให้เราและหลอด LED สีน้ำเงินก็จะติดซึ่งเป็นการพิสูจน์ว่าระบบจะกลับมาทำงานได้ปกติในทุกสภาวะ

    จากการทดสอบโปรแกรมเราจะเห็นได้ว่าในขณะที่การเชื่อมต่อ WiFi และอินเตอร์เน็ตมีปัญหา หลอดไฟยังสามารถกระพริบเป็นสัญญาณให้เรารู้ได้แสดงว่าช่วงที่ไม่มี Wifi โปรแกรมจะทำงานใน loop ด้วยเป็นปกติ ดังนั้น ใน loop เราสามารถเปลี่ยน Code ไปเป็น Code ควบคุมอุปกรณ์ตามที่เราต้องการได้ ครับ


#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <FS.h>
#include <DNSServer.h>
#include <ArduinoJson.h>                  //ArduinoJson-5.13.3                     


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

#define D0 16                     // ใช้ไฟ LED สีฟ้า ของบอร์ด MCU ESP8266 กำหนดโหมดใช้งานให้กับขา D0 เป็นขา สัญญาณไฟ ในสภาวะต่างๆ
#define D3 0                      // ใช้เป็นปุ่มกด เพื่อเข้า AP Config ได้ตามความต้องการของผู้ใช้


//การเรียกค่าา AP Config ที่เราตั้งค่าเอาไว้ ออกมาใช้งาน
bool shouldSaveConfig = false;
//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

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


long rssi;
int rssi_status = 0;
int rssi_status1 = 0;
#include <TridentTD_LineNotify.h>
#define LINE_TOKEN  "QerWyvEZdBShylI3iTTxKz1Pk8Zo1vLy23NQa7AXFgYLM"//ใส่ LINE_TOKEN ของคุณลงไป


const char* host = "www.google.co.th";    //ต้องการให้ส่งการติดต่อไปยัง Website นี้ เพื่อเป็นเงื่อนไขว่า ถ้าต่อ Net ได้ ก็ส่ง Line ได้
int internetok = 0;


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

void setup() {

  //****************************************************************************************************

  pinMode(D3, INPUT);//กำหนดโหมดใช้งานให้กับขา D3 เป็นขา กดปุ่ม ค้าง เพื่อตั้งค่า AP config
  pinMode(D0, OUTPUT);//กำหนดโหมดใช้งานให้กับขา D0 เป็นขา สัญญาณไฟ ในสภาวะต่างๆ
  digitalWrite(D0, LOW);//ให้หลอด LED สีฟ้าดับก่อน

  //***************************************************************************************************

  Serial.begin(115200);
  LINE.setToken(LINE_TOKEN);

  //*************************    การอ่านข้อมูลการตั้งค่า SSID และ Password ใน Arduinojson โดยอ่านข้อมูลเดิมที่มีอยู่   ***************

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

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");//แสดงข้อความใน Serial Monitor

    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");//แสดงข้อความใน Serial Monitor
      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");


        } else {
          Serial.println("failed to load json config");
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }
  //end read

  //*************************   จบการอ่านข้อมูลการตั้งค่า SSID และ Password ใน Arduinojson โดยอ่านข้อมูลเดิมที่มีอยู่   ***************









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


  WiFiManager wifiManager;

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

  //ตั้งค่ารอ 5 วินาที ว่ามีการกดปุ่มการตั้งค่า AP หรือไม่
  for (int i = 5; i > 0; i--) {
    digitalWrite(D0, LOW);
    delay(500);
    digitalWrite(D0, HIGH);
    delay(500);
    Serial.print (String(i) + " ");//แสดงข้อความใน Serial Monitor

  }


  if (digitalRead(D3) == LOW) {
    digitalWrite(D0, LOW);
    Serial.println("Button Pressed");
    wifiManager.resetSettings();//ให้ล้างค่า SSID และ Password ที่เคยบันทึกไว้

    if (!wifiManager.autoConnect("PUY IOT จ้า")) {
      Serial.println("failed to connect and hit timeout");
      delay(3000);
      //reset and try again, or maybe put it to deep sleep
      ESP.reset();
      delay(5000);

    }
  }


  Serial.println("connected........:)");


  //save the custom parameters to FS
  if (shouldSaveConfig) {
    Serial.println("saving config");//แสดงข้อความใน Serial Monitor
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    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");
  delay(100);
  Serial.println(WiFi.localIP());
  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());


}


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









//*****************************************************************************************************
//*******************************     void loop       *************************************************

void loop() {


  WiFiClient client;
  if (client.connect(host, 80))
  {
    //Serial.println("Internet connected");
    internetok = 1;

  }
  else {
    //Serial.println("connection failed!");
    internetok = 0;
  }



  rssi = WiFi.RSSI();

  if (rssi < 0 && rssi_status == 0 && internetok == 1) {

    digitalWrite(D0, LOW);
    LINE.notify("ระบบได้ถูกเชื่อมต่อกับ WiFi + Internet แล้ว และเดิมก่อนหน้านี้ ระบบอาจมีการ รีเซต หรือไม่สามารถเชื่อมต่อ WiFi + internet ได้");
    delay(200);
    rssi_status = 1;
    rssi_status1 = 0;
  }
  else if (rssi < 0 && rssi_status == 1) {
    delay(10);
    rssi_status1 = 1;
  }





  if (rssi >= -5 && rssi_status1 == 1 ) {
    digitalWrite(D0, HIGH);
    delay(500);
    digitalWrite(D0, LOW);
    delay(500);
    rssi_status = 0;
  }


  delay(200);

}

//*******************************   จบ  void loop     *************************************************
//*****************************************************************************************************



Wiring Diagram +ผลลัพธ์

1

ขอให้งานประสบความสำเร็จนะครับ

1 Likes