/*
  Library  ที่สามารถใช้งานได้  ใน Project นี้

  GPIO Port Esp8266

  #define D0 16  //LED Build in ESP8266
  #define D1 5   //SCL
  #define D2 4   //SDA
  #define D3 0
  #define D4 2
  #define D5 14
  #define D6 12
  #define D7 13

   --------------------------------------------------------------------------------------------------------------------------------------------------
  #include "Scheduler.h"

  class Task_1 : public Task {
  protected:
    void setup() { }

    void loop()  { }
  } Task_1_task;

  class Task_2 : public Task {
  protected:
    void setup() { }

    void loop()  { }
  } Task_2_task;

  class Task_3 : public Task {
  protected:
    void setup() { }

    void loop()  { }
  } Task_3_task;



  void setup() {

  Scheduler.start(&Task_1_task);
  Scheduler.start(&Task_2_task);
  Scheduler.start(&Task_3_task);
  Scheduler.begin();

  }
  --------------------------------------------------------------------------------------------------------------------------------------------------



  #include "PCF8574.h"
  PCF8574 pcf8574_1(0x38);
  unsigned long timeElapsed;

  void setup() {

  pcf8574_1.begin();
  timeElapsed = millis();
  pcf8574_1.pinMode(P0, OUTPUT);
  pcf8574_1.digitalWrite(P0, 1);
  uint8_t  curBtnState1 = pcf8575_1.digitalRead(P0);
  }

  --------------------------------------------------------------------------------------------------------------------------------------------------
  int L11;
  int L21;
  int L31;


  // ThingSpeak Settings //
  char thingSpeakAddress[] = "api.thingspeak.com";
  String writeAPIKey = "BBV6V6YXBCETIKLR"; // ไปเอาคีย์จากเมนู key Api เอาแบบ write
  WiFiClient client;

  void setup() { }
  void loop() {

  sendThingSpeak();

  }


  void sendThingSpeak()//1 วันได้แค่ 8200 ครั้ง (ฟรี)
  {

  String L1_thingspeak = (String) L11; // แปลงเป็น string
  String L2_thingspeak = (String) L21;
  String L3_thingspeak = (String) L31;
  String data = "field1=" + L1_thingspeak + "&field2=" + L2_thingspeak + "&field3=" + L3_thingspeak; // แปลงเป็น string ให้หมดเพื่อจะส่ง

  if (client.connect(thingSpeakAddress, 80)) {
    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: " + writeAPIKey + "\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(data.length());
    client.print("\n\n");
    client.print(data); // ข้อมูลเรานะครับ
  }



  delay(20000);


  }

  --------------------------------------------------------------------------------------------------------------------------------------------------

  #include "TridentTD_LineNotify.h"
  char line_token[45] = "";

  String LineText;
  String string1 = "https://www.google.com/maps/place/";
  String string2 = ",+";
  String string3 = "/@";
  String string4 = "@";
  String string5 = ",18z";


  void setup() {
  LINE.setToken(line_token);
  LineText = string1 + latitude + string2 + longitude + string3 + latitude + string4 + longitude + string5;
  }

  void loop() {

  LINE.notify("L1 ติด ปกติ");
  LINE.notify("https://thingspeak.com/channels/1024767");
  LINE.notify(LineText);
    delay(200);
  }
  --------------------------------------------------------------------------------------------------------------------------------------------------

  //RTC Library
  #include "Arduino.h"
  #include "Wire.h"
  #include "uRTCLib.h"
  // uRTCLib rtc;
  uRTCLib rtc(0x68);
  int year_;

  void setup() {


  #ifdef ARDUINO_ARCH_ESP8266
  Wire.begin(4, 5); // GPIO4 = D2 and GPIO5 = D1 on ESP8266
  #else
  Wire.begin();
  #endif

  //rtc.set(0, 17, 15, 3, 5, 3, 20);//ใช้เฉพาะตั้งเวลา ถ้าจะตั้งก็ เอา // ออก เมื่อตั้งได้ตรงแล้วก็เอา // ใส่กลับไปเหมือนเดิม
  //  RTCLib::set(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)

  }


  void loop() {

    rtc.refresh();
  year_ = rtc.year() + 2543; //+43 เพื่อให้ได้ปี พ.ศ. 63
  rtc.day();
  rtc.month();
  rtc.hour();
  rtc.minute();
  rtc.second();


  }

  --------------------------------------------------------------------------------------------------------------------------------------------------
  #include "Bounce2.h"

  #define inputPIR 5
  #define input_Relay1 8
  #define input_Relay2 9

  Bounce debouncerPIR = Bounce();
  Bounce debouncerinputRelay1 = Bounce();
  Bounce debouncerinputRelay2 = Bounce();



  void setup() {

  pinMode(inputPIR, INPUT_PULLUP);
  debouncerPIR.attach(inputPIR);
  debouncerPIR.interval(5); // interval in ms  กำหนดการรับค่าหลังจากการแกว่งของตัว Push button switch

  pinMode(input_Relay1, INPUT_PULLUP);
  debouncerinputRelay1.attach(input_Relay1);
  debouncerinputRelay1.interval(5); // interval in ms  กำหนดการรับค่าหลังจากการแกว่งของตัว Push button switch

  pinMode(input_Relay2, INPUT_PULLUP);
  debouncerinputRelay2.attach(input_Relay2);
  debouncerinputRelay2.interval(5); // interval in ms  กำหนดการรับค่าหลังจากการแกว่งของตัว Push button switch


  }


  void loop() {

  // Update the Bounce instances :
  debouncerPIR.update();
  debouncerinputRelay1.update();
  debouncerinputRelay2.update();


  int PIR = digitalRead(inputPIR);
  int inputRelay1 = digitalRead(input_Relay1);
  int inputRelay2 = digitalRead(input_Relay2);



  if (PIR == 0) {
    digitalWrite(outputRelay1, 0);
    digitalWrite(outputRelay2, 1);
    if (inputRelay1 == 1 and  inputRelay11 == 0 ) {


      char msg[] = {0x05, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x0, 0x00 , 0x05};
      RS232Serial.write(msg, sizeof(msg));
      inputRelay11 = 1;
      delay(1000);
    }

    if (inputRelay1 == 1) {

      digitalWrite(outputRelay1, 1);
      digitalWrite(outputRelay2, 1);
      inputRelay21 = 0;
      delay(1000);
    }


  }


  if (PIR == 1) {

    digitalWrite(outputRelay1, 1);
    digitalWrite(outputRelay2, 0);
    if (inputRelay2 == 1 and  inputRelay21 == 0 ) {


      char msg[] = {0x05, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x0, 0x00 , 0x05};
      RS232Serial.write(msg, sizeof(msg));
      inputRelay21 = 1;
      delay(1000);
    }

    if (inputRelay21 == 1) {

      digitalWrite(outputRelay1, 1);
      digitalWrite(outputRelay2, 1);
      inputRelay11 = 0;
      delay(1000);
    }

  }



  delay(300);



  }

  --------------------------------------------------------------------------------------------------------------------------------------------------
  //ตังอย่าง Bounce แบบ Toggle

  #include <Bounce2.h>

  #define BUTTON_1 30
  Bounce debouncer1 = Bounce();

  //กำหนดสถานะให้กับปุ่มต่างๆ เพื่อให้สามารถแยกระหว่างการติดหรือดับของ PB
  int Btn1 = 0;

  void setup{

  pinMode(BUTTON_1, INPUT_PULLUP); // กำหนดให้ตัวแปรชื่อ BUTTON_PIN_1 (เป็นขาที่ 2 ของ ARDUINO MEGA) เป็นแบบ input pull up
  // After setting up the button, setup the Bounce instance :หลังจากที่ตั้งค่าปุ่มแล้ว ก็ให้ตั้งค่า  Bounce
  debouncer1.attach(BUTTON_1);   debouncer1.interval(25); // interval in ms  กำหนดการรับค่าหลังจากการแกว่งของตัว Push button switch 5ms

  }

  void loop{

  debouncer1.update();
   //--Toggle SW  PB 1 -----------------------------------------------------------------------------------
  //ส่งข้อมูลไปยัง NODE MCU ESP 8266
  
  if ( debouncer1.fell() ) {  // Call code if button transitions from HIGH to LOW
    Btn1 = !Btn1; // Toggle LED state

    if ( Btn1 == 1 ) {

      MEGA1.print(10); //Print buttonState to Serial Port
      MEGA1.print('\n');
    }



    if ( Btn1 == 0 ) {

      MEGA1.print(11); //Print buttonState to Serial Port
      MEGA1.print('\n');
    }


  }



  }//loop
  --------------------------------------------------------------------------------------------------------------------------------------------------


  const long oneSecond  = 1000;               // 1000 มิลลิวินาที = 1 วินาทีเท่ากับ
  const long oneMinute  = oneSecond * 60;     //    1 นาที     = 1 วินาที  x 60 วินาที
  const long oneHour    = oneMinute * 60;     //    1 ชั่วโมง   = 1 นาที   x 60 นาที
  const long oneDay     = oneHour * 24;       //    1 วัน      = 1 ชั่วโมง x 24 ชั่วโมง
  const long twoDay     = oneDay * 2;         //    2 วัน      = 1 วัน    x 2 วัน
  const long threeDay   = oneDay * 3;         //    3 วัน      = 1 วัน    x 3 วัน
  const long fourDay    = oneDay * 4;         //    4 วัน      = 1 วัน    x 4 วัน
  const long fiveDay    = oneDay * 5;         //    5 วัน      = 1 วัน    x 5 วัน
  const long sixDay     = oneDay * 6;         //    6 วัน      = 1 วัน    x 6 วัน
  const long sevenDay   = oneDay * 7;         //    7 วัน      = 1 วัน    x 7 วัน

  --------------------------------------------------------------------------------------------------------------------------------------------------




  --------------------------------------------------------------------------------------------------------------------------------------------------

  #include "DHT.h"
  #define DHTTYPE DHT22
  #define DHTPIN  D1 //Beer D1
  DHT dht(DHTPIN, DHTTYPE);
  float h ;
  float t ;


  int countcheckHT = 0;


  void setup() {

  dht.begin();


  }


  void loop() {

  countcheckHT++;
  if (countcheckHT == 4) {//ทุกๆ 3 วินาที เชค temp + humid 1 ครั้ง
    checkT_H();
  }
  if (countcheckHT == 5) {//ทุกๆ 3 วินาที เชค temp + humid 1 ครั้ง
    countcheckHT = 0;
  }

  }

  void checkT_H()
  { loop:
  t = dht.readTemperature();
  h = dht.readHumidity();


  //-----------------ถ้าอ่านค่าไม่ได้ ให้  t = 0 ,h = 0 เพื่อสะดวกในการวิเคราะห์ค่า---------
  if (isnan(h) || isnan(t)) {
    //Serial.println("Failed to read from DHT sensor!");
    //delay(500);
    //display.clear();
    //display.drawString(5, 0, "Failed DHT22");
    //t = 0;
    //h = 0;
    Serial.println("***อ่านค่าไม่ได้***");
    delay(1000);
    goto loop ;
  }
  //---------------------------------------------------------------------
  else {
    Serial.println("อ่านค่าได้แล้ว");
    return;//ถ้าไม่ใส่มันจะไม่ return ค่า =0,h=0
  }

  }

  --------------------------------------------------------------------------------------------------------------------------------------------------

  //------------------------------  ระบบเวลาและการเชื่อมต่อ Web Server  ของNTP Server  -----------------------------------------//
  #include <time.h>
  int timezone = 7 * 3600; //ตั้งค่า TimeZone ตามเวลาประเทศไทย
  int dst = 0; //กำหนดค่า Date Swing Time


  void setup() {

  configTime(timezone, dst, "1.th.pool.ntp.org", "0.asia.pool.ntp.org", "3.asia.pool.ntp.org"); //แสดงเวลาปัจจุบัน ดึงจากServer
  while (!time(nullptr)) {//วนจนกว่า ค่าเวลา จะถูกต้อง แล้วจึงปล่อยออกไป
    delay(500);


  }


  void loop() {

    time_t now = time(nullptr);
  struct tm* p_tm = localtime(&now);

  String now_time = "";
  now_time = now_time + p_tm->tm_hour;      // hour
  now_time = now_time + ":";                // hour:
  now_time = now_time + p_tm->tm_min;       // hour:min
  now_time = now_time + ":";                // hour:min:
  now_time = now_time + p_tm->tm_sec;       // hour:min:sec
  //Serial.println(now_time);                 // ส่งข้อความออกทาง Serial Monitor พร้อมขึ้นบรรทัดใหม่

  String now_day = "";
  now_day = now_day + (p_tm->tm_year + 1900);     // year
  now_day = now_day + "-";                        // year-
  now_day = now_day + (p_tm->tm_mon + 1);         // year-mon
  now_day = now_day + "-";                        // year-mon-
  now_day = now_day + p_tm->tm_mday;              // year-mon-day

  //Serial.println(now_day);                        // ส่งข้อความออกทาง Serial Monitor พร้อมขึ้นบรรทัดใหม่
  String dateTime = now_day + " ";                // day-mon-year

  }

  //ใช้ตัวแปรไปดำเนินการ  p_tm->tm_hour;    p_tm->tm_min;     p_tm->tm_sec;  p_tm->tm_mday;   p_tm->tm_mon;     p_tm->tm_year;

  --------------------------------------------------------------------------------------------------------------------------------------------------
  // การแปลงค่า
  char Tmin[10] = "";
  String St_Tmin;
  float Tmin_;


  char Tcount[6] = "10";
  String St_Tcount;
  int Tcount_;


  void setup() {
  IP = WiFi.localIP().toString();
  Serial.print(IP);

  //----------------แปลงค่า Char >String > Float--------------------//
  // char Tmin[10] = "29.00";
  // String St_Tmin;
  // float Tmin_;

  Serial.println("เชคว่าค่าที่บันทึกได้ถูกแปลงเป็น Float แล้ว");

  for (int i = 0; i < sizeof(Tmin); i++)//แปลง chat>string
    St_Tmin += Tmin[i];  // เอาตัวแปร String มารับค่าที่แปลงได้
  Tmin_ = St_Tmin.toFloat(); // เอาตัวแปร Float มารับ ผลจากการแปลง String > Float
  Serial.print("Float Tmin = ");
  Serial.println(Tmin_);


  //----------------แปลงค่า Char >String > Int--------------------//

  //char Tcount[6] = "10";
  //String St_Tcount;
  //int Tcount_;
  Serial.println("เชคว่าค่าที่บันทึกได้ถูกแปลงเป็น Int แล้ว");

  for (int i = 0; i < sizeof(Tcount); i++)//แปลง chat>string
    St_Tcount += Tcount[i];// เอาตัวแปร String มารับค่าที่แปลงได้
  Tcount_ = St_Tcount.toInt(); // เอาตัวแปร Int มารับ ผลจากการแปลง String > Float
  Serial.print("Int Tcount = ");
  Serial.println(Tcount_);

  Tcount_1 = Tcount_ * 60; //นำค่าไปกระทำการใดๆ


  }


  --------------------------------------------------------------------------------------------------------------------------------------------------
  //  โค้ดชุดนี้จะเป็นการวัดระดับสัญญาณ WiFi 3 ระดับโดยใช้แอลอีดี 3 ดวงซึ่งแสดงค่าเป็น 0 ถึง 30 เปอร์เซ็นต์ 30 ถึง 50 เปอร์เซ็นต์และ 50 เปอร์เซ็นต์ถึง 60 เปอร์เซ็นต์ ซึ่งอ้างอิงจากค่า rssi
  // แปลงมาเป็นเปอร์เซ็นส่วนคำสั่งที่อยู่ใน If และ else ก็สามารถเปลี่ยนคำสั่งอื่นๆ เข้ามาได้ครับ (โค้ดชุดนี้ผมตัดออกมาจากชุดโค้ดหลัก) ถ้ามีการเชื่อมต่อ WiFi สำเร็จหลอดแอลอีดีก็จะติดและขึ้น
  //  เป็นระดับตามความแรงของสัญญาณ WiFi แต่ถ้าเชื่อมต่อไม่ติดหลอดแอลอีดีก็จะดับครับ

  long rssi;
  int rssiled;

  void setup() {}

  void loop() {

  rssi = WiFi.RSSI();

  rssiled = ((((rssi * 100) / -127) - 100) * -1);// ทำให้เป็น % ความแรงของ WiFi จะดูง่ายกว่า

  if (rssi < 0  ) {
    //เชคระดับสัญญาณ WiFi >= 60%
    if (rssiled >= 60  ) {
      } else  { }


    //เชคระดับสัญญาณ WiFi >= 50%
    if (rssiled >= 50  ) {
    } else  {   }


    //เชคระดับสัญญาณ WiFi 0-30%
    } else  {  }


  //Serial.println(rssi);
  if (rssi >= -5  ) {
      }


  delay(1000);
  yield();

  }

  --------------------------------------------------------------------------------------------------------------------------------------------------

  Library name : New-LiquidCrystal-master
  // ------------------------โหลดไลบารี่ของจอ LCD มาใช้งาน โดยแบบนี้จะสามารถ Create Characterได้ -------------------------------//


  #include <LCD.h>                          // บรรทัดที่ 1 และ 2 สามารถสลับบรรทัดกันได้
  #include <Wire.h>                         // บรรทัดที่ 1 และ 2 สามารถสลับบรรทัดกันได้
  #include <LiquidCrystal_I2C.h>            //บรรทัดนี้ต้องอยู่ในบรรทัดที่ 3 เท่านั้น ถ้าไปอยู่บรรทัดที่ 1 และ 2 จะคอมไพล์ไม่ผ่าน

  LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //// ตั้งค่า Address ของอุปกรณ์จอ LCD ที่มีการเชื่อมต่อแบบ I2C

  //------------------ / Create Character https: //maxpromer.github.io/LCD-Character-Creator/  -----------------------------//

  //------------------------------------------------------------------------------------------------------------------------//
  byte WifiL1[8] = {B00000, B00000, B00000, B00000, B00000,  B00011, B00111, B11111};  //icon  สัญญาณ WiFi ระดับที่ 1
  //------------------------------------------------------------------------------------------------------------------------//
  byte WifiL2[8] = {B00000, B00000, B00011, B00111, B11111, B11111, B11111, B11111};   //icon  สัญญาณ WiFi ระดับที่ 2
  //------------------------------------------------------------------------------------------------------------------------//
  byte WifiL3[8] = {B00011, B00111, B11111, B11111, B11111, B11111, B11111, B11111};   //icon  สัญญาณ WiFi ระดับที่ 3
  //------------------------------------------------------------------------------------------------------------------------//
  byte Temp[8]   = {B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110};   //icon สัญญาณอุณหภูมิ
  //-----------------------------------------------------------------------------------------------------------------------//
  byte RH[8]     = {B00100, B00100, B01010, B01010, B10001, B10001, B10001, B01110,};  //icon สัญญาณความชื้น
  //------------------------------------------------------------------------------------------------------------------------//

  void setup() {

  lcd.begin(20, 4);

  lcd.createChar(1, WifiL1);
  lcd.createChar(2, WifiL2);
  lcd.createChar(3, WifiL3);
  //lcd.createChar(4, Wifibase);
  lcd.createChar(5, Temp);
  lcd.createChar(6, RH);
  lcd.setCursor(5, 1);



  lcd.print(">PUY  IOT<");
  lcd.setCursor(5, 2);
  lcd.print("083 3899191");
  delay(3000);


  char_menu1(); //สร้าง Function





  }


  //------------------------------------//
  void char_menu1() {

  // lcd.setCursor(0, 3);
  //lcd.write(4);

  lcd.setCursor(0, 2);
  lcd.print("B");

  lcd.setCursor(0, 1);
  lcd.print("I");

  lcd.setCursor(6, 2);
  lcd.print(">");



  lcd.setCursor(9, 2);
  lcd.print("1");

  lcd.setCursor(12 , 2);
  lcd.print("2");

  lcd.setCursor(15, 2);
  lcd.print("3");

  lcd.setCursor(18, 2);
  lcd.print("4");



  }



  void loop() { }
  //คำสั่งที่ใช้
  // lcd.setCursor(0, 2);
  // lcd.print((char)0x20); Character ว่าง ไม่มีสี
  // lcd.print((char)0xFF);//ดำ Character สีดำ
  // lcd.print("B");
  // lcd.write(6);  ใส่ค่า Character ที่อยู่ใน address ที่ 6 ตามที่กำหนดไว้ใน void loop()ในชุดคำสั่งของ LCD
  // lcd.print((char)223);สัญลักษณ์องศา  lcd.print("C");

  --------------------------------------------------------------------------------------------------------------------------------------------------










*/
