#include "incubator_cfg.h"

LiquidCrystal_I2C lcd(0x27, LCD_ROW_LEN ,LCD_COLUMN_LEN); // set the LCD address to 0x27 for a 16 chars and 2 line display
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 rtc;

TaskHandle_t Task1;
TaskHandle_t Task2;

float cur_TEMP = 0, cur_HUM = 0;
time_t last_time_sec = 1715640024; //future edit
uint32_t motorON_sec = 0 ;

uint8_t MenuButtonState = 0;
uint8_t IncButtonState = 0;
uint8_t DecButtonState = 0;
uint32_t MenuB_On_time = 0;
uint32_t IncB_On_time = 0;
uint32_t DecB_On_time = 0;

uint8_t TERMINATE_TASK_1 = 0;
uint8_t LOCK_LCD_USAGE = 0;

Button menu_pin= {"MenuPin",MENU_PIN_NUM, 0, false, true, 0, 0, 0};
Button inc_pin = {"IncPin", INCREASE_PIN_NUM, 0, false, true, 0, 0, 0};
Button dec_pin = {"DecPin", DECREASE_PIN_NUM, 0, false, true, 0, 0, 0};

uint8_t set_hour = 0, set_min = 0, set_sec = 25; //future edit
uint8_t motorDealy_min = 0, motorDealy_sec = 10; //future edit.
float max_temp = 40, min_temp = 35, max_hum = 80, min_hum = 60; //future edit

void console_print(char* print_str)
{
  Serial.print(print_str);
}
void lcd_init()
{ 
  lcd.init();
  lcd.backlight();
}

void dht_init()
{
  dht.begin();
}

void FS_init()
{
  if (FILE_SYSTEM.begin(true))
  {
    Serial.println("FILE SYSTEM BEGIN SUCCESSFULL :)");
  }
  else
  {
    Serial.println("FILE SYSTEM BEGIN FAILED !!!");
  } 

  File fp_1 = FILE_SYSTEM.open( "sample.txt" , "w");
  if(!fp_1)
  {
    Serial.printf("Failed to open for Writing !!!\n");
  }
}

void rtc_init()
{
  if (! rtc.begin()) 
  {
    Serial.println("Couldn't find RTC");
    Serial.flush();
  }
  else
  {
    Serial.println("RTC BEGIN SUCCESSFUL");
  }

  if (! rtc.isrunning()) 
  {
    Serial.println("RTC is NOT running, let's set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}


void init_system()
{
  for(int cnt =0 ; cnt < LCD_ROW_LEN -strlen(LOADING_STR_NAME) ; cnt++)
  {
    switch(cnt)
    {
      case 0:
      {
        console_print("Initializing LCD...\n");
        lcd_init();
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(LOADING_STR_NAME);
        break;
      }
      case 1:
      {
        console_print("Initializing DHT sensor...\n");
        dht_init();
        break;
      } 
      case 2:
      {
        console_print("Initializing File system...\n");
        FS_init();
        break;
      }
      case 3:
      {
        console_print("Initializing RTC...\n");
        rtc_init();
        break;
      }

    }
    lcd.setCursor(strlen(LOADING_STR_NAME) + cnt, 0);
    lcd.print(".");
    delay(50);
  }
}

void dht_read()
{
  float cal_t = 1.0;
  float cal_h = 1.0;
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
  cur_TEMP = (t-cal_t);
  cur_HUM = (h-cal_h);
  
  if (isnan(h) || isnan(t))
  {
    Serial.println("Failed to read from DHT sensor !!!");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Failed To");
    lcd.setCursor(0, 1);
    lcd.print("Read Sensor!");
    lcd.clear();
    lcd.setCursor(0, 0);
    return;
  }
  
  char lcd_buf[LCD_BUF_SIZE];
  memset(&lcd_buf, 0 , LCD_BUF_SIZE);
  sprintf(lcd_buf, "T:%0.2f H:%0.2f",cur_TEMP, cur_HUM);

  if(LOCK_LCD_USAGE != 1)
  {
    // lcd.clear();
    lcd.setCursor(0, 0);
    strncat(lcd_buf, SPACE_STRING,LCD_BUF_SIZE-strlen(lcd_buf)-1);
    lcd.print(lcd_buf);
  }
  Serial.printf("DHT DATUM : cur_TEMP: %f  cur_HUM: %f\n",cur_TEMP, cur_HUM);

  Serial.printf("max_temp : %f   min_temp: %f\n",max_temp,min_temp);
  if(cur_TEMP < min_temp)
  {

    // Masukan Perintah 
    // lcd.setCursor(0, 1);
    // lcd.print("Alert! Temp high");
    Serial.printf("Alert! Temp LOW\n");
    digitalWrite(HEATER_PIN, HIGH);
  }
  if(cur_TEMP > max_temp)
  {

    // Masukan Perintah 
    // lcd.setCursor(0, 1);
    // lcd.print("Alert! Temp high");
    Serial.printf("Alert! Temp HIGH\n");
    digitalWrite(HEATER_PIN, LOW);
  }
  if(cur_HUM < min_hum)
  {
    Serial.printf("Alert! Hum LOW\n");
    digitalWrite(HUMIDIFIER_PIN, HIGH); 
  }
  if(cur_HUM > max_hum)
  {

    // Masukan Perintah 
    // lcd.setCursor(0, 1);
    // lcd.print("Alert! Temp high");
    Serial.printf("Alert! Hum HIGH\n");
    digitalWrite(HUMIDIFIER_PIN, LOW);
  }
}


void rtc_read()
{
  while(1)
  {
    DateTime curr_time = rtc.now();
    uint32_t curr_sec = curr_time.unixtime();
    uint32_t sec_overed = curr_sec-last_time_sec;

    Serial.printf("curr_time.unixtime() : %d\n",curr_time.unixtime());
    //Full Timestamp
    Serial.println(String("DateTime::TIMESTAMP_FULL:\t")+curr_time.timestamp(DateTime::TIMESTAMP_FULL));
    //Date Only
    Serial.println(String("DateTime::TIMESTAMP_DATE:\t")+curr_time.timestamp(DateTime::TIMESTAMP_DATE));
    //Full Timestamp
    Serial.println(String("DateTime::TIMESTAMP_TIME:\t")+curr_time.timestamp(DateTime::TIMESTAMP_TIME));
    Serial.println("\n");
   

    uint32_t wait_sec = (set_hour * 3600) + (set_min * 60) + set_sec;
    uint32_t sec_left = wait_sec - sec_overed;

    Serial.printf("SEC left : %d\n",sec_left);

    uint8_t hour = (sec_left/3600);
    uint8_t min = (sec_left%3600 ) / 60;
    uint8_t sec = (sec_left%3600 ) % 60;
    
    Serial.printf("REMAINING hr: %d  min: %d  sec: %d\n",hour, min, sec);
    if(LOCK_LCD_USAGE != 1)
    {
      lcd.setCursor(0, 1);
    }
    char lcd_buf[LCD_BUF_SIZE];
    memset(&lcd_buf, 0, LCD_BUF_SIZE);

    if(sec_overed >= wait_sec)
    {
      uint16_t motorDelay_sec = (motorDealy_min * 60) + motorDealy_sec;

      Serial.printf("curr_sec : %u  motor_on_sec : %u  motorDelay_sec : %u\n",curr_sec,motorON_sec,motorDelay_sec);
      if(motorON_sec == 0)
      {
        motorON_sec = curr_sec;
        digitalWrite(MOTOR_PIN, HIGH);
        Serial.printf("MOTOR ON\n");
      }
      else if ( (curr_sec - motorON_sec) >= motorDelay_sec)
      {
        digitalWrite(MOTOR_PIN, LOW);
        curr_time = rtc.now();
        last_time_sec = curr_time.unixtime();
        motorON_sec = 0;
        Serial.printf("MOTOR OFF\n");
        continue;
      }  

      min = (motorDelay_sec - (curr_sec - motorON_sec)) / 60;
      sec = (motorDelay_sec - (curr_sec - motorON_sec)) %60;
      Serial.printf("curr_sec : %u  motor_on_sec : %u  motorDelay_sec : %u\n",curr_sec,motorON_sec,motorDelay_sec);
      sprintf(lcd_buf, "M ON [%02u:%02u]",min, sec);
      // Serial.printf("MIN : %02u sec : %02u\n",min, sec); 
    }
    else
    {
      sprintf(lcd_buf, "M OFF %02u:%02u:%02u",hour, min, sec);
    }
    strncat(lcd_buf, SPACE_STRING,LCD_BUF_SIZE-strlen(lcd_buf)-1);
    if(LOCK_LCD_USAGE != 1)
    {
      lcd.print(lcd_buf);
    }
    Serial.printf("RTC LCD PRINTED DATUM :   ==%s==\n",lcd_buf);
    break;
  }
}

void factory_reset()
{
  TERMINATE_TASK_1 = 1;
  delay(1000);
  Serial.printf("Factory Resetting ");
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(RESETTING_STR_NAME);
  for(int cnt =0 ; cnt < LCD_ROW_LEN -strlen(RESETTING_STR_NAME) ; cnt++)
  {
    //...........
    //future work
    //..........
    lcd.setCursor(strlen(RESETTING_STR_NAME) + cnt, 0);
    lcd.print(".");
    delay(1000);
    Serial.printf(".");
  }
  lcd.clear();
  Serial.printf("\n>> RESTARTING DEVICE <<\n");
  delay(2000);
  ESP.restart();
}

void buttons_read()
{
  // Serial.println("\n\nFree HEAP memory AT STARTING THE PROGRAM  : " + String(xPortGetFreeHeapSize()) + " bytes");
  
  // if (menu_pin.pressed)
  // {
  //   Serial.printf("MENU button has been pressed %lu times\n", menu_pin.numberKeyPresses);
  //   menu_pin.pressed = false;
  // }
  // if (inc_pin.pressed)
  // {
  //   Serial.printf("INC button has been pressed %lu times\n", inc_pin.numberKeyPresses);
  //   inc_pin.pressed = false;
  // }
  // if (dec_pin.pressed)
  // {
  //   Serial.printf("DEC button has been pressed %lu times\n", dec_pin.numberKeyPresses);
  //   dec_pin.pressed = false;
  // }
  if( ( (menu_pin.pressed == true) && ((millis() -menu_pin.pressed_time) > 5000) ) &&
     ( (inc_pin.pressed == true) && ((millis() -inc_pin.pressed_time) > 5000) ) &&
     ( (dec_pin.pressed == true) && ((millis() -dec_pin.pressed_time) > 5000) ) )
  {
    Serial.printf("MENU button pressed time : %ld curr_time : %ld  pressed %lu times\n", menu_pin.pressed_time, millis(), menu_pin.numberKeyPresses);
    factory_reset();
  }
  if ( (menu_pin.pressed == true) && ((millis() -menu_pin.pressed_time) > 2500) )
  {
    uint8_t SET_EN = 0, blynk_pos= 0, first_tym = 1, digit_start_pos =0 , digit_len =0;
    uint32_t last_blnk_time = 0;
    LOCK_LCD_USAGE =1;
    char lcd_buf[LCD_BUF_SIZE];
    int display_state = 1;
    int menu_key_prs_cnt = menu_pin.numberKeyPresses;
    int inc_key_prs_cnt = inc_pin.numberKeyPresses;
    int dec_key_prs_cnt = dec_pin.numberKeyPresses;
    lcd.clear();
    char min_temp_str[8], max_temp_str[8], min_hum_str[8], max_hum_str[8];
    memset(min_temp_str, 0, sizeof(min_temp_str));
    memset(max_temp_str, 0, sizeof(max_temp_str));
    memset(min_hum_str , 0, sizeof(min_hum_str));
    memset(max_hum_str , 0, sizeof(max_hum_str));

    sprintf(min_temp_str, "%0.3f",min_temp);
    sprintf(max_temp_str, "%0.3f",max_temp);
    sprintf(min_hum_str, "%0.3f",min_hum);
    sprintf(max_hum_str, "%0.3f",max_hum);

    char *str_ptr;
    while(1) //BUTTON MAIN
    {
      lcd.setCursor(0, 0);
      memset(&lcd_buf, 0, LCD_BUF_SIZE);

      switch(display_state)
      {
        case 1:
          // str_ptr = min_temp_str;
          // sprintf(str_ptr, "%f", min_temp_str);
          snprintf(lcd_buf, LCD_BUF_SIZE, "MinTEMP : %s",min_temp_str); //causing stack err
          break;
        case 2:
          // str_ptr = max_temp_str;
          snprintf(lcd_buf, LCD_BUF_SIZE, "MaxTEMP : %s",max_temp_str); //causing stack err
          break;
        case 3:
          // str_ptr = min_hum_str;
          snprintf(lcd_buf, LCD_BUF_SIZE, "MinHUM : %s",min_hum_str); //causing stack err
          break;
        case 4:
          // str_ptr = max_hum_str;
          snprintf(lcd_buf, LCD_BUF_SIZE, "MaxHUM : %s",max_hum_str); //causing stack err
          break;
      }
      // lcd.print(lcd_buf);
      // lcd.print("sanjay");

      if(SET_EN == 1)
      {
        while(first_tym == 1)
        {
          if(isDigit(lcd_buf[blynk_pos]) == 1)
          {
            digit_start_pos = blynk_pos;
            digit_len = strlen(lcd_buf);
            first_tym = 0;
            break;
          }
          blynk_pos++;
        }
        if( (millis()-last_blnk_time) >= 250 )
        {
          lcd_buf[blynk_pos] = ' ';
          if( (millis()-last_blnk_time) >= 400 )
          {
            last_blnk_time =millis();
          }
        }
        if( (menu_pin.pressed == true) && ((millis() -menu_pin.pressed_time) >2500) )
        {
          Serial.printf("SETTING DATUM...\n");
          SET_EN = 0;
          first_tym =1;
        }
      }

      lcd.print(lcd_buf);


      if( ((millis()-menu_pin.state_ch_time) > 4000) && 
          ((millis()-inc_pin.state_ch_time) > 4000)  &&
          ((millis()-dec_pin.state_ch_time) > 4000) )
      { 
        Serial.printf("####### Released time: %ld  cur time: %ld \n",menu_pin.released_time,millis());
        LOCK_LCD_USAGE =0;
        break;
      }

      if ( (SET_EN == 1) && (menu_pin.pressed == true) && ((millis() -menu_pin.pressed_time) > 2500) )
      {
        switch(display_state)
        {
          case 1:
            // Serial.printf("SANJAY.... min str : %s\n",min_temp_str);
            min_temp = atof(min_temp_str);
            // Serial.printf("FLOAT VAL MIN TEMP : %0.3f",min_temp);
            // snprintf(lcd_buf, LCD_BUF_SIZE, "MinTEMP : %s",min_temp_str); //causing stack err
            break;
          case 2:
            max_temp = atof(max_temp_str);
            // snprintf(lcd_buf, LCD_BUF_SIZE, "MaxTEMP : %s",max_temp_str); //causing stack err
            break;
          case 3:
            min_hum = atof(min_hum_str);
            // snprintf(lcd_buf, LCD_BUF_SIZE, "MinHUM : %s",min_hum_str); //causing stack err
            break;
          case 4:
            max_hum = atof(max_hum_str);
            // snprintf(lcd_buf, LCD_BUF_SIZE, "MaxHUM : %s",max_hum_str); //causing stack err
            break;
        }
        SET_EN =0;
      }

      if ( (menu_key_prs_cnt != menu_pin.numberKeyPresses) )
      {
        menu_key_prs_cnt = menu_pin.numberKeyPresses;
        Serial.printf("####### MENU pin Released time: %ld  cur time: %ld \n",menu_pin.released_time,millis());
        // lcd.clear(); //pos fixed
        if(SET_EN == 1)
        {
          blynk_pos==digit_len-1 ? blynk_pos = digit_start_pos : blynk_pos++;
          lcd_buf[blynk_pos] == '.' ? blynk_pos++ : 0;
        }
        else
        {
          SET_EN = 1;
        }
        Serial.printf("Setting Enable : %d\n", SET_EN);
      }
      if ( (inc_key_prs_cnt != inc_pin.numberKeyPresses) )
      {
        inc_key_prs_cnt = inc_pin.numberKeyPresses;
        Serial.printf("####### INC pin Released time: %ld  cur time: %ld \n",inc_pin.released_time,millis());
        Serial.printf("SET_EN : %d\n", SET_EN);
        if(SET_EN == 0)
        {
          display_state==4 ? display_state = 1 : display_state++;
          lcd.clear(); //pos fixed
        }
        else
        {
          Serial.printf("min_temp_str[blynk_pos] : %c\n", min_temp_str[blynk_pos-digit_start_pos]);
          // str_ptr[blynk_pos-digit_start_pos] = str_ptr[blynk_pos-digit_start_pos]+1;
          // Serial.printf("STR_PTR [%d] : %s\n",blynk_pos-digit_start_pos,str_ptr[0] );
          (min_temp_str[blynk_pos-digit_start_pos] == '9' ) ?  min_temp_str[blynk_pos-digit_start_pos] = '0':min_temp_str[blynk_pos-digit_start_pos] += 1;
        }
        // else
        // {
        //   blynk_pos==digit_len-1 ? blynk_pos = digit_start_pos : blynk_pos++;
        // }
      }
      if ( (dec_key_prs_cnt != dec_pin.numberKeyPresses) )
      {
        dec_key_prs_cnt = dec_pin.numberKeyPresses;
        Serial.printf("####### DEC pin Released time: %ld  cur time: %ld \n",dec_pin.released_time,millis());
        if(SET_EN == 0)
        {
          display_state==1 ? display_state = 4 : display_state--;
          lcd.clear(); //pos fixed
        }
        else
        {
          (min_temp_str[blynk_pos-digit_start_pos] == '0' ) ?  min_temp_str[blynk_pos-digit_start_pos] = '9':min_temp_str[blynk_pos-digit_start_pos] -= 1;
        }
      }
      // Serial.printf("inside loop \n");
    }
    // Serial.printf("####### Menu pressed time : %ld  curr time : %ld press_num : %d #######33\n",menu_pin.pressed_time, millis(),  menu_pin.numberKeyPresses);
  }
  if(menu_pin.pressed == true)
  {
    Serial.printf("####### MENU pressed time : %ld  curr time : %ld press_num : %d #######33\n",menu_pin.pressed_time, millis(),  menu_pin.numberKeyPresses);
  }
  if(inc_pin.pressed == true)
  {
    Serial.printf("####### INC pressed time : %ld  curr time : %ld press_num : %d #######33\n",inc_pin.pressed_time, millis(),  inc_pin.numberKeyPresses);
  }
  // MenuButtonState = digitalRead(MENU_PIN_NUM);
  // IncButtonState  = digitalRead(INCREASE_PIN_NUM);
  // DecButtonState  = digitalRead(DECREASE_PIN_NUM);
  // DateTime curr_time = rtc.now(); //pos fixed
  // Serial.printf("Button States\nMenu : %d\nINC : %d\nDEC : %d\n",MenuButtonState, IncButtonState, DecButtonState);

  // ( (MenuButtonState == true) && (MenuB_On_time == 0) ) ? MenuB_On_time = curr_time.unixtime() : 0;
  // ( (IncButtonState == LOW)  && (IncB_On_time  == 0) ) ? IncB_On_time  = curr_time.unixtime() : 0;
  // ( (DecButtonState == LOW)  && (DecB_On_time  == 0) ) ? DecB_On_time  = curr_time.unixtime() : 0;

  // ( (MenuButtonState == HIGH)  && (MenuB_On_time != 0) ) ? MenuB_On_time = 0   : 0;
  // ( (IncButtonState == HIGH)   && (IncB_On_time  != 0) ) ? IncB_On_time  = 0   : 0;
  // ( (DecButtonState == HIGH)   && (DecB_On_time  != 0) ) ? DecB_On_time  = 0   : 0;

  // if ( (MenuButtonState == LOW) && (IncButtonState == LOW) && (DecButtonState == LOW))
  // {
  //   curr_time = rtc.now();
  //   if ( ((curr_time.unixtime()-MenuB_On_time) > 120) &&  ((curr_time.unixtime()-IncButtonState) > 120) &&  ((curr_time.unixtime()-DecButtonState) > 120) )
  //   {
  //     factory_reset();
  //   }
  // }
  // Serial.println("\n\nFree HEAP memory AT ENDING THE PROGRAM  : " + String(xPortGetFreeHeapSize()) + " bytes");
  // Serial.printf("Button States\nMenu : %d\nINC : %d\nDEC : %d\n",MenuButtonState, IncButtonState, DecButtonState);
  // Serial.printf("PRITINNG NOTHING\n");
  // delay(200);
  return;
}

void ARDUINO_ISR_ATTR isr(void *arg) 
{
  Button *s = static_cast<Button *>(arg);

  if( (s->released == true) && ((millis()-s->state_ch_time) > 5))
  {
    s->pressed = true;
    s->released = false;
    s->pressed_time = millis();
    s->state_ch_time = millis();
    s->numberKeyPresses += 1;
  }
  else if( (s->pressed == true) && ((millis()-s->state_ch_time) > 5))
  {
    s->released = true;
    s->pressed = false;
    s->released_time = millis();
    s->state_ch_time = millis();
    // s->numberKeyPresses += 1;
  }
  Serial.printf("############# %s is pressed ###########\n",s->pin_name);
}

//Task1code
void Task1code( void * pvParameters )
{
  while (!TERMINATE_TASK_1)
  {
    Serial.printf("CORE_%d : Reading DHT data\n", xPortGetCoreID());
    dht_read();
    rtc_read();
    delay(800);
  } 
  Serial.printf("CORE_%d : TASK 1 Terminated Successfully\n");
  while(1)
  {
    delay(10000);
  }
}

//Task2code
void Task2code( void * pvParameters )
{
  while(1)
  {
    Serial.printf("CORE_%d : Reading BUTTONS state\n", xPortGetCoreID());
    buttons_read();
    // static uint32_t lastMillis = 0;
    // if (millis() - lastMillis > 10000) 
    // {
    //   printf("*********** checking ***********\n");
    //   lastMillis = millis();
    //   // detachInterrupt(menu_pin.PIN);
    //   // detachInterrupt(inc_pin.PIN);
    //   // detachInterrupt(dec_pin.PIN);
    // }
    // Serial.printf("HLO TN....\n");
    delay(100);
  }
}

void init_tasks()
{
  //create a task that will be executed in the Task1code() function, 
  //with priority 1 and executed on core 0
  xTaskCreatePinnedToCore(
    Task1code, /* Task function. */
    "Task1", /* name of task. */
    10000, /* Stack size of task */
    NULL, /* parameter of the task */
    1, /* priority of the task */
    &Task1, // Task handle to keep track of created task 
    0    /* pin task to core 0 */ 
  ); 
  delay(500);

  //Task 2 on core 1
  xTaskCreatePinnedToCore(
    Task2code, /* Task function. */
    "Task2", /* name of task. */
    10000, /* Stack size of task */
    NULL, /* parameter of the task */
    1, /* priority of the task */
    &Task2, /* Task handle to keep track of created task */
    1); /* pin task to core 1 */
  delay(500); 
}

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

  pinMode(MENU_PIN_NUM, INPUT_PULLUP );
  attachInterruptArg(menu_pin.pin_num, isr, &menu_pin, CHANGE);
  pinMode(INCREASE_PIN_NUM, INPUT_PULLUP );
  attachInterruptArg(inc_pin.pin_num, isr, &inc_pin, CHANGE);
  pinMode(DECREASE_PIN_NUM, INPUT_PULLUP );
  attachInterruptArg(dec_pin.pin_num, isr, &dec_pin, CHANGE);

  Serial.printf("PIN: %d\tpin nam: %s\n",menu_pin.pin_num, menu_pin.pin_name);
  Serial.printf("PIN: %d\tpin nam: %s\n",inc_pin.pin_num, inc_pin.pin_name);
  Serial.printf("PIN: %d\tpin nam: %s\n",dec_pin.pin_num, dec_pin.pin_name);

  pinMode(MOTOR_PIN, OUTPUT);
  pinMode(HEATER_PIN, OUTPUT);
  pinMode(HUMIDIFIER_PIN, OUTPUT);

  digitalWrite(MOTOR_PIN, LOW);
  digitalWrite(HEATER_PIN, LOW);
  digitalWrite(HUMIDIFIER_PIN, LOW);
  
  init_system();
  init_tasks();
}

void loop() //dummy won't work
{
  delay(100);
}
GND5VSDASCLSQWRTCDS1307+