'getpushlength 'was not declared in this scope รบกวนสอบถามด้วยครับ ตูฟักไข่ครับ


//wire.h library
#include <Wire.h>

//I2C LCD library 4 line
#include <LiquidCrystal_I2C.h>

//eeprom library
#include <EEPROM.h>

//DHT library
//#include <dht.h>
#include <DHT.h>
#define DHTPIN A0


// Set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x27,20,4);

// Creat Characters
uint8_t arrow[8] = {0x1F, 0x17, 0x1B, 0x1D, 0x1D, 0x1B, 0x17, 0x1F,};

byte degree[8] = {
  B01100,
  B10010,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
};
// define pins for relay or leds
#define temperaturepin A1
#define humiditypin A2
#define motorpin 5
#define errorpin 4
#define fan 9

// define variable
float tl, tempset, tempdefference, errtemp; // variable for temperature
float humidityset, humiditydefference, errhumid; // variable for humidity

byte heat;  // is 1 heater and 0 for cooler
byte dry;  // is l dryer and 0 for wetter

//Define Buttons
#define BUT1 6    // - switch
#define BUT2 7    // + switch
#define BUT3 8    // MENU switch
#define BUT4 11    //limit switch for open door 
#define BUT5 10    // posistion 0

byte menu = 10; // if MENIU = 0 is initial menu
// if MENIU = 1 is for temperature set (tempset)
// if MENIU = 2 is for dt temperature (tempdefference)
// if MENIU = 3 is for humidity set (humidityset)
// if MENIU = 4 is for dh humidity (humiditydefference)
// if MENIU = 5 is for hours between turning eggs (hours)
// if MENIU = 6 is for time turning eggs (seconds)
// if MENIU = 7 is for error temperature
// if MENIU = 8 os for error humidity


//Time Variables
int is, im, ih, id, ida;                      // variables for time
float taim, s1, m1, h1, d1;                   //  Set up variables to calculate time
int timebetweenspinsHour, motorspinduration, hatchdays, dayremains;
unsigned long rotationtime, durationB4spin, durationONspin, hatchduration, hatchtimeduration;
int hour, minutes, seconds;
float rest;
unsigned long repeatrotationtime;
byte rotate = 0;
byte spin = 0;
byte temperror = 0;
byte humidityerror = 0;

// These variables are for the push button routine
int buttonstate = 0; //flag to see if the button has been pressed, used internal on the subroutine only
int pushlengthset = 4000; // value for a long push in mS
int pushlength = pushlengthset ; // set default pushlength

int pushstart = 0;// sets default push value for the button going low
int pushstop = 0;// sets the default value for when the button goes back high
boolean buttonflag = false; // default value for the button flag
unsigned long entrymenu;
unsigned long exitmenu = 60000; //
byte cancel = 0;
byte error = 0;



void setup() {

  Serial.begin(9600);
  // Initialize the I2C 20x4 LCD
  lcd.begin();
  //lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);

  // create custom symbol
  lcd.createChar(0, degree);
  lcd.createChar(1, arrow);

  // Turn on the blacklight and print a message.
  lcd.backlight();

  // define outputs
  pinMode(temperaturepin, OUTPUT);
  pinMode(humiditypin, OUTPUT);
  pinMode(motorpin, OUTPUT);
  pinMode(errorpin, OUTPUT);
  pinMode(fan, OUTPUT);

  // set the default state for outputs
  pinMode(temperaturepin, HIGH);
  pinMode(humiditypin, HIGH);
  pinMode(motorpin, HIGH);
  pinMode(errorpin, HIGH);
  pinMode(fan, HIGH);


  // set push buttons for menu
  pinMode(BUT1, INPUT);
  pinMode(BUT2, INPUT);
  pinMode(BUT3, INPUT);
  pinMode(BUT4, INPUT);
  //pinMode(BUT5, INPUT);
  digitalWrite(BUT1, INPUT); // pull-up on
  digitalWrite(BUT2, INPUT);
  digitalWrite(BUT3, INPUT);
  digitalWrite(BUT4, INPUT);
  //digitalWrite(BUT5, INPUT);

  lcd.setCursor(0, 1);
  lcd.print("Incubator with");

  lcd.setCursor(0, 2);
  lcd.print("humidity control");

  delay(3000);
  lcd.clear();

  lcd.setCursor(0, 2);
  lcd.print("  by: JOe Vohan  ");

  lcd.setCursor(0, 1);
  lcd.print("  version 2   ");
  delay(3000);
  lcd.clear();

  heat = 1;  // is 1 for heater and 0 for cooler (temp)
  dry = 1;   // is 1 for dryer and 0 for wetter  (humidity)

  // just first time uploading sketch... after must put commnent (//)
  // save initial setpoints to eeprom
  /*
    EEPROM.write(200,45);    // max hatching days
    EEPROM.write(201,1);     // tset1
    EEPROM.write(202,120);   // tset2
    EEPROM.write(203,5);    // dt x 10
    EEPROM.write(204,45);   // humidity set
    EEPROM.write(205,5);    // humidity defference
    EEPROM.write(206,2);    // time in hour between spins
    EEPROM.write(207,10);    // time in seconds for rotation
    EEPROM.write(208,20);   // errtemp (error temperature) x10
    EEPROM.write(209,3);    // errhumid (error humidity)

  */
  hatchdays = EEPROM.read(200);
  byte tset1 = EEPROM.read(201);
  byte tset2 = EEPROM.read(202);
  tempset = 256 * tset1 + tset2;  // recover the number
  tempset = tempset / 10;
  tempdefference = EEPROM.read(203);
  tempdefference = tempdefference / 10;
  humidityset = EEPROM.read(204);
  humiditydefference = EEPROM.read(205);
  timebetweenspinsHour = EEPROM.read(206);
  motorspinduration = EEPROM.read(207);
  errtemp = EEPROM.read(208);
  errtemp = errtemp / 10;
  errhumid = EEPROM.read(209);

  //durationB4spin = timebetweenspinsHour  * 60000;  // minute -> ms
  durationB4spin = timebetweenspinsHour * 3600000;  // hour -> ms
  durationONspin = motorspinduration * 1000; // seconds -> ms
  rotationtime = millis();
}


void loop()
{
  if (menu >= 10)
  {
    lcd.clear();
    menu = 0;
  }

  if (menu == 0)
  {
    int doorstatus = digitalRead(BUT4);
    pushlength = pushlengthset;
    pushlength = getpushlength();
    delay (10);
   
    if (pushlength > pushlengthset)
    {
      menu = 1;

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("   please wait...  ");
      lcd.setCursor(0, 1);
      lcd.print("   Entering...  ");
      lcd.setCursor(0, 2);
      lcd.print("   Settings MENU  ");
      delay(2000);
      pushlength = pushlengthset;
      delay(50);
      entrymenu = millis(); // store time when enter is setup menu
    }
    if (pushlength < pushlengthset)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("   Press SET Button   ");
      lcd.setCursor(0, 1);
      lcd.print("   for 5 seconds  ");
      lcd.setCursor(0, 2);
      lcd.print("   to enter MENU  ");
      delay(3000);
      lcd.clear();
      pushlength = pushlengthset;
    }

    if (doorstatus == HIGH) {
      lcd.clear();
      lcd.setCursor(0, 2);
      lcd.print("   Door Open    ");
      lcd.setCursor(0, 3);
      lcd.print("   centering rack...  ");
      digitalWrite(motorpin, LOW);
      int pos0 = digitalRead(BUT5);
      if (pos0 == LOW) {
        digitalWrite(motorpin, HIGH);
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("   Door Open    ");
        lcd.setCursor(0, 3);
        lcd.print("   rack centered  ");
      }
      delay(1000);
    }
    if (doorstatus == HIGH) {
      digitalWrite(motorpin, HIGH);
    }
    //Reading temperature or humidity
    int readData = DHT.read22(DHTPIN);
    float humidityreading = DHT.humidity; // reads humidity
    float temperaturereading = DHT.temperature;

    //Check if any reads failed or exit early (to try again)
    if ((humidityreading < 0 && humidityreading > 100 && (temperaturereading < -40 && temperaturereading > 80))
  {
    lcd.clear();
      lcd.setCursor(0, 1);
      lcd.print("   Failed to Read    ");
      lcd.setCursor(0, 2);
      lcd.print("   DHT SENSOR  ");
      digitalWrite(temperaturepin, HIGH);
      digitalWrite(humiditypin, HIGH);
      digitalWrite(fan, HIGH);
      digitalWrite(motorpin, HIGH);
      delay(5000);
      return;
    }
    digitalWrite(fan, LOW);

    // start of inital menu (menu 0)

    lcd.setCursor(0, 0);
    lcd.print("Temp= ");
    if (temperaturereading < 0)
  {
    t1 = -temperaturereading;
  }
  else t1 = temperaturereading;

              if ( t1 < 10 )
    {
      lcd.print("  ");
      }
    if (temperaturereading > 0) lcd.print("+");
    if (temperaturereading == 0) lcd.print(" ");
      if (temperaturereading < 0) lcd.print("-");
        lcd.print(t1, 1);
        lcd.write(byte(0));
        lcd.print("C  ");

        lcd.setCursor(0, 1);
        lcd.print("Humidity=  ");
        lcd.print(humidityreading, 0);
        lcd.print("%RH   ");
        delay(790);
        if (temperaturereading >= 0) tempset = 0.1)
          {
            if (heat == 1) digitalWrite(temperaturepin, HIGH);
            if (heat == 0) digitalWrite(temperaturepin, LOW);
          }
    if (tempset - tempdefference > temperaturereading )
    {
      if (heat == 0) digitalWrite(temperaturepin, HIGH);
      if (heat == 1) digitalWrite(temperaturepin, LOW);
    }
    if (humidityreading > humidityset)
    {
      if (dry == 1) digitalWrite(humiditypin, HIGH);
      if (dry == 0) digitalWrite(humiditypin, LOW);
    }
    if (humidityreading < humidityset - humiditydefference)
    {
      if (dry == 0) digitalWrite(humiditypin, HIGH);
      if (dry == 1) digitalWrite(humiditypin, LOW);
    }
    if ((temperaturereading > tempset + errtemp) or (temperaturereading < tempset - errtemp))
    {
      temperror = 1;
      lcd.setCursor(17, 0);
      lcd.print("err");
    }
    else
    {
      temperror = 0;
      lcd.setCursor(17, 0);
      lcd.print("  ");
    }
    if ((humidityreading < humidityset - errhumid) or (humidityreading > humidityset + errhumid))
    {
      humidityerror = 1;
      lcd.setCursor(17, 1);
      lcd.print("err");
    }
    else
    {
      humidityerror = 0;
      lcd.setCursor(17, 1);
      lcd.print("  ");
    }

    if ((temperror == 1) or  < (humidityerror == 1))
    {
      error = 1;
    }

    if (error  == 1)
  {
    if (cancel == 0)
      }
    digitalWrite(errorpin, LOW);
    if ((digitalRead(BUT1) == LOW) or (digitalRead(BUT2) == LOW))
    {
      cancel = 1;
      delay(250);
    }
  }
  else
  {
    digitalWrite(errorpin, HIGH);
  }
}
else
{
  digitalWrite(errorpin, HIGH);
}

if ((temperror == 0) or  < (humidityerror == 0))
{
  error = 0;
  cancel = 0;
}

//part for day remaining
taim = millis();                            //  Get time in milliseconds since  the unit turn on
s1 = taim / 1000;                           //  Convert time to seconds, minutes, hours, days
m1 = s1 / 60;
h1 = m1 / 60;
d1 = h1 / 24;
id = int(d1);                               //  Strip out remainder to leave Days:Hours:Minutes:Seconds
ih = int((d1 - int(d1)) * 24);
im = int((h1 - int(h1)) * 60);
is = int((m1 - int(m1)) * 60);

// Calculate approximate days till hatch (maximum hatch setting 45 days )
ida = hatchdays - id;

repeatrotationtime =  - millis() + durationB4spin + rotationtime;  // time to rotatitng again
repeatrotationtime = repeatrotationtime / 1000; // ms -> s
hour = repeatrotationtime / 3600;
rest = repeatrotationtime - 3600 * hour;
minutes = rest / 60;
seconds = rest - 60 * minutes;

lcd.setCursor(0, 2);
lcd.print("Tspin= ");
if (hour < 10) lcd.print("0");
lcd.print(hour);
lcd.print(":");
if (minutes < 10) lcd.print("0");
lcd.print(minutes);
lcd.print(":");
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print("Hatch in: ");
if ((ida >= 0) && (ida < 10)) lcd.print(" ");
lcd.print(ida);
lcd.print("day/s");

// spins part (turning eggs)
while (((millis() - sfrotatii) > taim11) && (rotit == 0))
{
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print(" Turning EGG's for!  ");
  lcd.setCursor(6, 2);
  lcd.print(motorspinduration);
  lcd.print(" seconds     ");
  digitalWrite(motorpin, LOW);
  delay(durationONspin);
  digitalWrite(motorpin, HIGH);
  rotate = 1;
}

if (rotate == 1)
{
  rotationtime = millis();
  rotate = 0;
  lcd.clear();
}
}
// last line for MENU = 0

if (menu == 1) {
  lcd.clear();
  while (menu == 1) {
    if (millis() - entrymenu > exitmenu) menu = 0;
    lcd.setCursor(0, 0);
    lcd.print("  Set Temperature:    ");
    lcd.setCursor(5, 1);
    lcd.print(byte(1));
    lcd.setCursor(7, 1);
    lcd.print(tempset, 1);
    lcd.write(byte(0));
    lcd.print("C  ");

    lcd.setCursor(0, 2);
    lcd.print("  Temp Defference:  ");
    lcd.setCursor(7, 3);
    lcd.print(tempdefference, 1);
    lcd.write(byte(0));
    lcd.print("C  ");


    if (digitalRead(BUT1) == LOW)
    { tempset = tempset - 0.1;
      delay(250);
    }
    if (digitalRead(BUT2) == LOW)
    { tempset = tempset + 0.1;
      delay(250);
    }
    int tes2 = tempset * 10;  // because single eeprom address can't save decimal points thats why its multiplied by 10
    byte tset1 = tes2 / 256;
    byte tset2 = tes2 - tset1 * 256;

    if (digitalRead(BUT3) == LOW)
    {
      EEPROM.write(201, tset1);  // save temp setting to eeprom
      EEPROM.write(202, tset2);   // rest
      menu = 2;
      delay(250);
      lcd.clear();
    }
  }
  delay(100);
}
// end loop for MENU = 1

if (menu == 2) {
  while (menu == 2) {
    if (millis() - entrymenu > exitmenu) menu = 0;
    lcd.setCursor(0, 0);
    lcd.print("  Set Temperature:    ");
    lcd.setCursor(7, 1);
    lcd.print(tempset, 1);
    lcd.write(byte(0));
    lcd.print("C  ");

    lcd.setCursor(0, 2);
    lcd.print("  Temp Defference:  ");
    lcd.setCursor(5, 3);
    lcd.write(byte(1));
    lcd.setCursor(7, 3);
    lcd.print(tempdefference, 1);
    lcd.write(byte(0));
    lcd.print("C  ");

    if (digitalRead(BUT1) == LOW)
    { tempdefference = tempdefference - 0.1;
      delay(250);
    }
    if (digitalRead(BUT2) == LOW)
    { tempdefference = tempdefference + 0.1;
      delay(250);
    }
    if (tempdefference < 0.1) tempdefference = 0.1;

    if (digitalRead(BUT3) == LOW)
    {
      EEPROM.write(203, tempdefference * 10); // because single eeprom address can't save decimal points thats why its multiplied by 10
      menu = 3;
      delay(250);
      lcd.clear();
    }
  }
  // end loop for MENU = 2

  if (menu == 3) {
    while (menu == 3) {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("  Set Humidity:    ");
      lcd.setCursor(5, 1);
      lcd.write(byte(1));
      lcd.setCursor(7, 1);
      lcd.print(humidityset, 1);
      lcd.print("%RH  ");

      lcd.setCursor(0, 2);
      lcd.print("  Humidity Defference:  ");
      lcd.setCursor(7, 3);
      lcd.print(humiditydefference);
      lcd.print("%RH  ");

      if (digitalRead(BUT1) == LOW)
      { humidityset = humidityset - 1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { humidityset = humidityset + 1;
        delay(250);
      }
      if (digitalRead(BUT3) == LOW)
      {
        EEPROM.write(204, humidityset);
        menu = 4
               delay(250);
        lcd.clear();
      }
    }
    delay(250);
  }
  // end loop for MENU = 3

  if (menu == 4) {
    while (menu == 4) {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("  Set Humidity:    ");
      lcd.setCursor(7, 1);
      lcd.print(humidityset, 1);
      lcd.write(byte(0));
      lcd.print("%RH  ");

      lcd.setCursor(0, 2);
      lcd.print("  Humidity Defference:  ");
      lcd.setCursor(5, 3);
      lcd.write(byte(1));
      lcd.setCursor(7, 3);
      lcd.print(humiditydefference);
      lcd.write(byte(0));
      lcd.print("%RH  ");

      if (digitalRead(BUT1) == LOW)
      { humiditydefference = humiditydefference - 1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { humiditydefference = humiditydefference + 1;
        delay(250);
      }
      if (digitalRead(BUT3) == LOW)
        EEPROM.write(205, humiditydefference);
      menu = 5;
      delay(250);
      lcd.clear();
    }
    if (humiditydefference < 1) humiditydefference = 1;
  }
}
// end loop for MENU = 4

if (menu == 5) {
  while (menu == 5) {
    if (millis() - entrymenu > exitmenu) menu = 0;
    lcd.setCursor(0, 0);
    lcd.print("  Time between Spins:");

    if (digitalRead(BUT1) == LOW)
    { timebetweenspinsHour = timebetweenspinsHour - 1;
      delay(250);
    }
    if (digitalRead(BUT2) == LOW)
    { timebetweenspinsHour = timebetweenspinsHour + 1;
      delay(250);
    }

    if (timebetweenspinsHour < 1) timebetweenspinsHour = 24;
    if (timebetweenspinsHour < 24) timebetweenspinsHour = 1 ;

    lcd.setCursor(5, 2);
    lcd.write(byte(1));
    lcd.setCursor(6, 2);
    lcd.print(timebetweenspinsHour);
    lcd.print(" hour/s  ");

    if (digitalRead(BUT3) == LOW)
      EEPROM.write(206, humidityset);
    delay(250);
    lcd.clear();
    durationB4spin = timebetweenspinsHour // 3600000; // hour -> ms
                     menu = 6;
  }
}
}
// end loop for end MENU = 5

if (menu == 6) {
  while (menu == 6) {
    if (millis() - entrymenu > exitmenu) menu = 0;
    lcd.setCursor(0, 0);
    lcd.print("Running Duration of");
    lcd.setCursor(0, 1);
    lcd.print(" egg's tilt Motor:   ");


    if (digitalRead(BUT1) == LOW)
    { motorspinduration = motorspinduration - 1;
      delay(250);
    }
    if (digitalRead(BUT2) == LOW)
    { motorspinduration = motorspinduration  + 1;
      delay(250);
    }

    if (motorspinduration < 3) motorspinduration = 60;
    if (motorspinduration > 60) motorspinduration = 3 ;

    lcd.setCursor(4, 3);
    lcd.write(byte(1));
    lcd.setCursor(6, 3);
    lcd.print(motorspinduration);
    lcd.print(" seconds  ");

    if (digitalRead(BUT3) == LOW)
      EEPROM.write(207, motorspinduration);
    delay(250);
    lcd.clear();
    durationB4spin = motorspinduration * 1000; //   seconds -> ms
    menu = 7;
  }
}
}
// end loop for end MENU = 6

if (menu == 7) {
  while (menu == 7) {
    if (millis() - entrymenu > exitmenu) menu = 0;
    lcd.setCursor(0, 0);
    lcd.print("  Temp Tolerance  ");
    lcd.setCursor(0, 1);
    lcd.print(" (Define as Error) ");

    lcd.setCursor(4, 3);
    lcd.write(byte(1));
    lcd.setCursor(6, 3);
    lcd.print(" +/- ");
    lcd.print(errtemp, 1);
    lcd.write(byte(0));
    lcd.print("C  ");



    if (digitalRead(BUT1) == LOW)
    { errtemp = errtemp - 0.1;
      delay(250);
    }
    if (digitalRead(BUT2) == LOW)
    { errtemp = errtemp  + 0.1;
      delay(250);
    }

    if (errtemp < 0.1) errtemp = 0.1;
    if (errtemp > 3.0) errtemp = 3.0 ;

    if (digitalRead(BUT3) == LOW)
    {
      EEPROM.write(208, errtemp * 10); // because single eeprom address can't save decimal points thats why its multiplied by 10
      menu = 8;
      delay(250);
      lcd.clear();
    }
  }
}
// end loop for MENU = 7

if (menu == 8) {
  while (menu == 8) {
    if (millis() - entrymenu > exitmenu) menu = 0;
    lcd.setCursor(0, 0);
    lcd.print("  Humidity Tolerance  ");
    lcd.setCursor(0, 1);
    lcd.print(" (Define as Error) ");

    lcd.setCursor(4, 3);
    lcd.write(byte(1));
    lcd.setCursor(6, 3);
    lcd.print(" +/- ");
    lcd.print(errhumid);
    lcd.write(byte(0));
    lcd.print("%RH");



    if (digitalRead(BUT1) == LOW)
    { errhumid = errhumid - 1;
      delay(250);
    }
    if (digitalRead(BUT2) == LOW)
    { errhumid = errhumid  + 1;
      delay(250);
    }

    if (digitalRead(BUT3) == LOW)
    {
      EEPROM.write(209, errhumid);
      delay(250);
      lcd.clear();
      menu = 9;
    }
    if (errtemp < 0.1) errtemp = 0.1;
    if (errtemp > 3.0) errtemp = 3.0 ;
  }
}
// end loop for MENU = 8

if (menu == 9) {
  while (menu == 9) {
    if (millis() - entrymenu > exitmenu) menu = 0;
    lcd.setCursor(0, 0);
    lcd.print("  Set Egg's Hatch  ");
    lcd.setCursor(0, 1);
    lcd.print(" Duration ");

    lcd.setCursor(4, 3);
    lcd.write(byte(1));
    lcd.setCursor(6, 3);
    lcd.print(hatchdays);
    lcd.print(" day/s ");


    if (digitalRead(BUT1) == LOW)
    { hatchdays = hatchdays - 1;
      delay(250);
    }
    if (digitalRead(BUT2) == LOW)
    { hatchdays = hatchdays  + 1;
      delay(250);
    }

    if (digitalRead(BUT3) == LOW)
    {
      EEPROM.write(200, hatchdays);
      delay(250);
      lcd.clear();
      menu = 0;
    }
    if (hatchdays < 1) hatchdays = 1;
    if (hatchdays > 45) hatchdays = 45 ;
  }
}
// end loop for MENU = 9

if (menu == 10) {
  while (menu == 10) {
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("  door open...  ");
    if (digitalRead(BUT1) == LOW) {
      lcd.clear();
      menu = 0;
    }
  }
}

}
}
// last line in main loop


// subroutine to return the length of the button push.
int getpushlength () {
  buttonstate = digitalRead(BUT3);
  if (buttonstate == LOW && buttonflag == false) {
    pushstart = millis();
    buttonflag = true;
  };

  if (buttonstate == HIGH && buttonflag == true) {
    pushstop = millis ();
    pushlength = pushstop - pushstart;
    buttonflag = false;
  };
  return pushlength;
}

ใช้กับบอร์ดอะไรครับถ่ายมาดูหน่อย

copy error เต็มๆ มาดูด้วย

/wire.h library
#include <Wire.h>

//I2C LCD library 4 line
#include <LiquidCrystal_I2C.h>

//eeprom library
#include <EEPROM.h>

//DHT library
//#include <dht.h>
#include "DHT.h"
#define DHTPIN A0
//#define DHTTYPE DHT22
#define DHTTYPE DHT11  
// Set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);

// Creat Characters
uint8_t arrow[8] = {0x1F, 0x17, 0x1B, 0x1D, 0x1D, 0x1B, 0x17, 0x1F,};

byte degree[8] = {
  B01100,
  B10010,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
};
// define pins for relay or leds
#define temperaturepin A1
#define humiditypin A2
#define motorpin 5
#define errorpin 4
#define fan 9

// define variable
float t1, tl, tempset, tempdefference, errtemp; // variable for temperature
float humidityset, humiditydefference, errhumid; // variable for humidity

byte heat;  // is 1 heater and 0 for cooler
byte dry;  // is l dryer and 0 for wetter

//Define Buttons
#define BUT1 6    // - switch
#define BUT2 7    // + switch
#define BUT3 8    // MENU switch
#define BUT4 11    //limit switch for open door 
#define BUT5 10    // posistion 0

byte menu = 10; // if MENIU = 0 is initial menu
// if MENIU = 1 is for temperature set (tempset)
// if MENIU = 2 is for dt temperature (tempdefference)
// if MENIU = 3 is for humidity set (humidityset)
// if MENIU = 4 is for dh humidity (humiditydefference)
// if MENIU = 5 is for hours between turning eggs (hours)
// if MENIU = 6 is for time turning eggs (seconds)
// if MENIU = 7 is for error temperature
// if MENIU = 8 os for error humidity


//Time Variables
int is, im, ih, id, ida;                      // variables for time
float taim, s1, m1, h1, d1;                   //  Set up variables to calculate time
int timebetweenspinsHour, motorspinduration, hatchdays, dayremains;
unsigned long rotationtime, durationB4spin, durationONspin, hatchduration, hatchtimeduration, sfrotatii, taim11;
int hour, minutes, seconds;
float rest;
unsigned long repeatrotationtime;
byte rotate = 0;
byte spin = 0;
byte temperror = 0;
byte humidityerror = 0;

// These variables are for the push button routine
int buttonstate = 0; //flag to see if the button has been pressed, used internal on the subroutine only
int pushlengthset = 4000; // value for a long push in mS
int pushlength = pushlengthset ; // set default pushlength

int pushstart = 0;// sets default push value for the button going low
int pushstop = 0;// sets the default value for when the button goes back high
boolean buttonflag = false; // default value for the button flag
unsigned long entrymenu;
unsigned long exitmenu = 60000; //
byte cancel = 0;
byte error = 0;

int rotit;
DHT dht(DHTPIN, DHTTYPE);
void setup() {

  Serial.begin(9600);
  // Initialize the I2C 20x4 LCD
  lcd.begin();
  //lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);

  // create custom symbol
  lcd.createChar(0, degree);
  lcd.createChar(1, arrow);

  // Turn on the blacklight and print a message.
  lcd.backlight();

  // define outputs
  pinMode(temperaturepin, OUTPUT);
  pinMode(humiditypin, OUTPUT);
  pinMode(motorpin, OUTPUT);
  pinMode(errorpin, OUTPUT);
  pinMode(fan, OUTPUT);

  // set the default state for outputs
  pinMode(temperaturepin, HIGH);
  pinMode(humiditypin, HIGH);
  pinMode(motorpin, HIGH);
  pinMode(errorpin, HIGH);
  pinMode(fan, HIGH);


  // set push buttons for menu
  pinMode(BUT1, INPUT);
  pinMode(BUT2, INPUT);
  pinMode(BUT3, INPUT);
  pinMode(BUT4, INPUT);
  pinMode(BUT5, INPUT);
  digitalWrite(BUT1, INPUT); // pull-up on
  digitalWrite(BUT2, INPUT);
  digitalWrite(BUT3, INPUT);
  digitalWrite(BUT4, INPUT);
  digitalWrite(BUT5, INPUT);

  lcd.setCursor(0, 1);
  lcd.print("Incubator with");

  lcd.setCursor(0, 2);
  lcd.print("humidity control");

  delay(3000);
  lcd.clear();

  lcd.setCursor(0, 2);
  lcd.print("  by: JOe Vohan  ");

  lcd.setCursor(0, 1);
  lcd.print("  version 2   ");
  delay(3000);
  lcd.clear();

  heat = 1;  // is 1 for heater and 0 for cooler (temp)
  dry = 1;   // is 1 for dryer and 0 for wetter  (humidity)

  // just first time uploading sketch... after must put commnent (//)
  // save initial setpoints to eeprom
  /*
    EEPROM.write(200,45);    // max hatching days
    EEPROM.write(201,1);     // tset1
    EEPROM.write(202,120);   // tset2
    EEPROM.write(203,5);    // dt x 10
    EEPROM.write(204,45);   // humidity set
    EEPROM.write(205,5);    // humidity defference
    EEPROM.write(206,2);    // time in hour between spins
    EEPROM.write(207,10);    // time in seconds for rotation
    EEPROM.write(208,20);   // errtemp (error temperature) x10
    EEPROM.write(209,3);    // errhumid (error humidity)

  */
  hatchdays = EEPROM.read(200);
  byte tset1 = EEPROM.read(201);
  byte tset2 = EEPROM.read(202);
  tempset = 256 * tset1 + tset2;  // recover the number
  tempset = tempset / 10;
  tempdefference = EEPROM.read(203);
  tempdefference = tempdefference / 10;
  humidityset = EEPROM.read(204);
  humiditydefference = EEPROM.read(205);
  timebetweenspinsHour = EEPROM.read(206);
  motorspinduration = EEPROM.read(207);
  errtemp = EEPROM.read(208);
  errtemp = errtemp / 10;
  errhumid = EEPROM.read(209);

  //durationB4spin = timebetweenspinsHour  * 60000;  // minute -> ms
  durationB4spin = timebetweenspinsHour * 3600000;  // hour -> ms
  durationONspin = motorspinduration * 1000; // seconds -> ms
  rotationtime = millis();
  dht.begin();
}


void loop()
{
  if (menu >= 10)
  {
    lcd.clear();
    menu = 0;
  }

  if (menu == 0)
  {
    int doorstatus = digitalRead(BUT4);
    pushlength = pushlengthset;
    pushlength = getpushlength();
    delay (10);

    if (pushlength > pushlengthset)
    {
      menu = 1;

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("   please wait...  ");
      lcd.setCursor(0, 1);
      lcd.print("   Entering...  ");
      lcd.setCursor(0, 2);
      lcd.print("   Settings MENU  ");
      delay(2000);
      pushlength = pushlengthset;
      delay(50);
     // entrymenu = millis(); // store time when enter is setup menu
    }
    if (pushlength < pushlengthset)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("   Press SET Button   ");
      lcd.setCursor(0, 1);
      lcd.print("   for 5 seconds  ");
      lcd.setCursor(0, 2);
      lcd.print("   to enter MENU  ");
      delay(3000);
      lcd.clear();
      pushlength = pushlengthset;
    }

    if (doorstatus == HIGH) {
      lcd.clear();
      lcd.setCursor(0, 2);
      lcd.print("   Door Open    ");
      lcd.setCursor(0, 3);
      lcd.print("   centering rack...  ");
      digitalWrite(motorpin, LOW);
      int pos0 = digitalRead(BUT5);
      if (pos0 == LOW) {
        digitalWrite(motorpin, HIGH);
        lcd.clear();
        lcd.setCursor(0, 2);
        lcd.print("   Door Open    ");
        lcd.setCursor(0, 3);
        lcd.print("   rack centered  ");
      }
      delay(1000);
    }
    
//    if (doorstatus == HIGH) {
//      digitalWrite(motorpin, HIGH);
//    }
    //Reading temperature or humidity
    //int readData = DHT.read22(DHTPIN);
    float humidityreading = dht.readHumidity(); // reads humidity
    float temperaturereading = dht.readTemperature();

    //Check if any reads failed or exit early (to try again)
    if ((humidityreading < 0 && humidityreading > 100) && (temperaturereading < -40 && temperaturereading > 80))
    {
      lcd.clear();
      lcd.setCursor(0, 1);
      lcd.print("   Failed to Read    ");
      lcd.setCursor(0, 2);
      lcd.print("   DHT SENSOR  ");
      digitalWrite(temperaturepin, HIGH);
      digitalWrite(humiditypin, HIGH);
      digitalWrite(fan, HIGH);
      digitalWrite(motorpin, HIGH);
      delay(5000);
      return;
    }
    digitalWrite(fan, LOW);

    // start of inital menu (menu 0)

    lcd.setCursor(0, 0);
    lcd.print("Temp= ");
    if (temperaturereading < 0)
    {
      t1 = -temperaturereading;
    }
    else t1 = temperaturereading;

    if ( t1 < 10 )
    {
      lcd.print("  ");
    }
    if (temperaturereading > 0) lcd.print("+");
    if (temperaturereading == 0) lcd.print(" ");
    if (temperaturereading < 0) lcd.print("-");
    lcd.print(t1, 1);
    lcd.write(byte(0));
    lcd.print("C  ");

    lcd.setCursor(0, 1);
    lcd.print("Humidity=  ");
    lcd.print(humidityreading, 0);
    lcd.print("%RH   ");
    delay(790);
    if (temperaturereading >=  tempset == 0.1)
    {
      if (heat == 1) digitalWrite(temperaturepin, HIGH);
      if (heat == 0) digitalWrite(temperaturepin, LOW);
    }
    if (tempset - tempdefference > temperaturereading )
    {
      if (heat == 0) digitalWrite(temperaturepin, HIGH);
      if (heat == 1) digitalWrite(temperaturepin, LOW);
    }
    if (humidityreading > humidityset)
    {
      if (dry == 1) digitalWrite(humiditypin, HIGH);
      if (dry == 0) digitalWrite(humiditypin, LOW);
    }
    if (humidityreading < humidityset - humiditydefference)
    {
      if (dry == 0) digitalWrite(humiditypin, HIGH);
      if (dry == 1) digitalWrite(humiditypin, LOW);
    }
    if ((temperaturereading > tempset + errtemp) or (temperaturereading < tempset - errtemp))
    {
      temperror = 1;
      lcd.setCursor(17, 0);
      lcd.print("err");
    }
    else
    {
      temperror = 0;
      lcd.setCursor(17, 0);
      lcd.print("  ");
    }
    if ((humidityreading < humidityset - errhumid) or (humidityreading > humidityset + errhumid))
    {
      humidityerror = 1;
      lcd.setCursor(17, 1);
      lcd.print("err");
    }
    else
    {
      humidityerror = 0;
      lcd.setCursor(17, 1);
      lcd.print("  ");
    }

    if ((temperror == 1) || (humidityerror == 1))
    {
      error = 1;
    }

    if (error  == 1)
    {
      if (cancel == 0)
      {
        digitalWrite(errorpin, LOW);
        if ((digitalRead(BUT1) == LOW) or (digitalRead(BUT2) == LOW))
        {
          cancel = 1;
          delay(250);
        }
      }
    }
    else
    {
      digitalWrite(errorpin, HIGH);
    }
  }
  else
  {
    digitalWrite(errorpin, HIGH);
  }

  if ((temperror == 0) || (humidityerror == 0))
  {
    error = 0;
    cancel = 0;
  }

  //part for day remaining
  taim = millis();                            //  Get time in milliseconds since  the unit turn on
  s1 = taim / 1000;                           //  Convert time to seconds, minutes, hours, days
  m1 = s1 / 60;
  h1 = m1 / 60;
  d1 = h1 / 24;
  id = int(d1);                               //  Strip out remainder to leave Days:Hours:Minutes:Seconds
  ih = int((d1 - int(d1)) * 24);
  im = int((h1 - int(h1)) * 60);
  is = int((m1 - int(m1)) * 60);

  // Calculate approximate days till hatch (maximum hatch setting 45 days )
  ida = hatchdays - id;

  repeatrotationtime =  - millis() + durationB4spin + rotationtime;  // time to rotatitng again
  repeatrotationtime = repeatrotationtime / 1000; // ms -> s
  hour = repeatrotationtime / 3600;
  rest = repeatrotationtime - 3600 * hour;
  minutes = rest / 60;
  seconds = rest - 60 * minutes;

  lcd.setCursor(0, 2);
  lcd.print("Tspin= ");
  if (hour < 10) lcd.print("0");
  lcd.print(hour);
  lcd.print(":");
  if (minutes < 10) lcd.print("0");
  lcd.print(minutes);
  lcd.print(":");
  if (seconds < 10) lcd.print("0");
  lcd.print(seconds);
  lcd.print(" ");
  lcd.setCursor(0, 3);
  lcd.print("Hatch in: ");
  if ((ida >= 0) && (ida < 10)) lcd.print(" ");
  lcd.print(ida);
  lcd.print("day/s");

  // spins part (turning eggs)
 /* while (((millis() - sfrotatii) > taim11) && (rotit == 0))
  {
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print(" Turning EGG's for!  ");
    lcd.setCursor(6, 2);
    lcd.print(motorspinduration);
    lcd.print(" seconds     ");
    digitalWrite(motorpin, LOW);
    delay(durationONspin);
    digitalWrite(motorpin, HIGH);
    
   lcd.clear();
 }

 if (rotate == 1)
  {
   rotationtime = millis();
    rotate = 0;
    
   lcd.clear();
  }
*/
  // last line for MENU = 0

 if (menu == 1)
 {
   lcd.clear();
   while (menu == 1)
  {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("  Set Temperature:    ");
      lcd.setCursor(5, 1);
      lcd.print(byte(1));
      lcd.setCursor(7, 1);
      lcd.print(tempset, 1);
      lcd.write(byte(0));
      lcd.print("C  ");

      lcd.setCursor(0, 2);
      lcd.print("  Temp Defference:  ");
      lcd.setCursor(7, 3);
      lcd.print(tempdefference, 1);
      lcd.write(byte(0));
      lcd.print("C  ");


      if (digitalRead(BUT1) == LOW)
      { tempset = tempset - 0.1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { tempset = tempset + 0.1;
        delay(250);
      }
      int tes2 = tempset * 10;  // because single eeprom address can't save decimal points thats why its multiplied by 10
      byte tset1 = tes2 / 256;
      byte tset2 = tes2 - tset1 * 256;

      if (digitalRead(BUT3) == LOW)
      {
        EEPROM.write(201, tset1);  // save temp setting to eeprom
        EEPROM.write(202, tset2);   // rest
        menu = 2;
        delay(250);
        lcd.clear();
      }
    }
   delay(100);
  }
  // end loop for MENU = 1

  if (menu == 2) {
    while (menu == 2) {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("  Set Temperature:    ");
      lcd.setCursor(7, 1);
      lcd.print(tempset, 1);
      lcd.write(byte(0));
      lcd.print("C  ");

      lcd.setCursor(0, 2);
      lcd.print("  Temp Defference:  ");
      lcd.setCursor(5, 3);
      lcd.write(byte(1));
      lcd.setCursor(7, 3);
      lcd.print(tempdefference, 1);
      lcd.write(byte(0));
      lcd.print("C  ");

      if (digitalRead(BUT1) == LOW)
      { tempdefference = tempdefference - 0.1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { tempdefference = tempdefference + 0.1;
        delay(250);
      }
      if (tempdefference < 0.1) tempdefference = 0.1;

      if (digitalRead(BUT3) == LOW)
      {
        EEPROM.write(203, tempdefference * 10); // because single eeprom address can't save decimal points thats why its multiplied by 10
        menu = 3;
        delay(250);
        lcd.clear();
      }
    }
    // end loop for MENU = 2

    if (menu == 3) {
      while (menu == 3) {
        if (millis() - entrymenu > exitmenu) menu = 0;
        lcd.setCursor(0, 0);
        lcd.print("  Set Humidity:    ");
        lcd.setCursor(5, 1);
        lcd.write(byte(1));
        lcd.setCursor(7, 1);
        lcd.print(humidityset, 1);
        lcd.print("%RH  ");

        lcd.setCursor(0, 2);
        lcd.print("  Humidity Defference:  ");
        lcd.setCursor(7, 3);
        lcd.print(humiditydefference);
        lcd.print("%RH  ");

        if (digitalRead(BUT1) == LOW)
        { humidityset = humidityset - 1;
          delay(250);
        }
        if (digitalRead(BUT2) == LOW)
        { humidityset = humidityset + 1;
          delay(250);
        }
        if (digitalRead(BUT3) == LOW)
        {
          EEPROM.write(204, humidityset);
          menu = 4;
          delay(250);
          lcd.clear();
        }
      }
      delay(250);
    }
    // end loop for MENU = 3

    if (menu == 4) {
      while (menu == 4) {
        if (millis() - entrymenu > exitmenu) menu = 0;
        lcd.setCursor(0, 0);
        lcd.print("  Set Humidity:    ");
        lcd.setCursor(7, 1);
        lcd.print(humidityset, 1);
        lcd.write(byte(0));
        lcd.print("%RH  ");

        lcd.setCursor(0, 2);
        lcd.print("  Humidity Defference:  ");
        lcd.setCursor(5, 3);
        lcd.write(byte(1));
        lcd.setCursor(7, 3);
        lcd.print(humiditydefference);
        lcd.write(byte(0));
        lcd.print("%RH  ");

        if (digitalRead(BUT1) == LOW)
        { humiditydefference = humiditydefference - 1;
          delay(250);
        }
        if (digitalRead(BUT2) == LOW)
        { humiditydefference = humiditydefference + 1;
          delay(250);
        }
        if (digitalRead(BUT3) == LOW)
          EEPROM.write(205, humiditydefference);
        menu = 5;
        delay(250);
        lcd.clear();
      }
      if (humiditydefference < 1) humiditydefference = 1;
    }
  }
  // end loop for MENU = 4

  if (menu == 5) {
    while (menu == 5) {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("  Time between Spins:");

      if (digitalRead(BUT1) == LOW)
      { timebetweenspinsHour = timebetweenspinsHour - 1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { timebetweenspinsHour = timebetweenspinsHour + 1;
        delay(250);
      }

      if (timebetweenspinsHour < 1) timebetweenspinsHour = 24;
      if (timebetweenspinsHour < 24) timebetweenspinsHour = 1 ;

      lcd.setCursor(5, 2);
      lcd.write(byte(1));
      lcd.setCursor(6, 2);
      lcd.print(timebetweenspinsHour);
      lcd.print(" hour/s  ");

      if (digitalRead(BUT3) == LOW)
        EEPROM.write(206, humidityset);
      delay(250);
      lcd.clear();
      durationB4spin = timebetweenspinsHour; // 3600000; // hour -> ms
      menu = 6;
    }
  }

  // end loop for end MENU = 5

  if (menu == 6) {
    while (menu == 6) {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("Running Duration of");
      lcd.setCursor(0, 1);
      lcd.print(" egg's tilt Motor:   ");


      if (digitalRead(BUT1) == LOW)
      { motorspinduration = motorspinduration - 1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { motorspinduration = motorspinduration  + 1;
        delay(250);
      }

      if (motorspinduration < 3) motorspinduration = 60;
      if (motorspinduration > 60) motorspinduration = 3 ;

      lcd.setCursor(4, 3);
      lcd.write(byte(1));
      lcd.setCursor(6, 3);
      lcd.print(motorspinduration);
      lcd.print(" seconds  ");

      if (digitalRead(BUT3) == LOW)
        EEPROM.write(207, motorspinduration);
      delay(250);
      lcd.clear();
      durationB4spin = motorspinduration * 1000; //   seconds -> ms
      menu = 7;
    }
  }

  // end loop for end MENU = 6

  if (menu == 7) {
    while (menu == 7) {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("  Temp Tolerance  ");
      lcd.setCursor(0, 1);
      lcd.print(" (Define as Error) ");

      lcd.setCursor(4, 3);
      lcd.write(byte(1));
      lcd.setCursor(6, 3);
      lcd.print(" +/- ");
      lcd.print(errtemp, 1);
      lcd.write(byte(0));
      lcd.print("C  ");



      if (digitalRead(BUT1) == LOW)
      { errtemp = errtemp - 0.1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { errtemp = errtemp  + 0.1;
        delay(250);
      }

      if (errtemp < 0.1) errtemp = 0.1;
      if (errtemp > 3.0) errtemp = 3.0 ;

      if (digitalRead(BUT3) == LOW)
      {
        EEPROM.write(208, errtemp * 10); // because single eeprom address can't save decimal points thats why its multiplied by 10
        menu = 8;
        delay(250);
        lcd.clear();
      }
    }
  }
  // end loop for MENU = 7

  if (menu == 8) {
    while (menu == 8) {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("  Humidity Tolerance  ");
      lcd.setCursor(0, 1);
      lcd.print(" (Define as Error) ");

      lcd.setCursor(4, 3);
      lcd.write(byte(1));
      lcd.setCursor(6, 3);
      lcd.print(" +/- ");
      lcd.print(errhumid);
      lcd.write(byte(0));
      lcd.print("%RH");



      if (digitalRead(BUT1) == LOW)
      { errhumid = errhumid - 1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { errhumid = errhumid  + 1;
        delay(250);
      }

      if (digitalRead(BUT3) == LOW)
      {
        EEPROM.write(209, errhumid);
        delay(250);
        lcd.clear();
        menu = 9;
      }
      if (errtemp < 0.1) errtemp = 0.1;
      if (errtemp > 3.0) errtemp = 3.0 ;
    }
  }
  // end loop for MENU = 8

  if (menu == 9) {
    while (menu == 9) {
      if (millis() - entrymenu > exitmenu) menu = 0;
      lcd.setCursor(0, 0);
      lcd.print("  Set Egg's Hatch  ");
      lcd.setCursor(0, 1);
      lcd.print(" Duration ");

      lcd.setCursor(4, 3);
      lcd.write(byte(1));
      lcd.setCursor(6, 3);
      lcd.print(hatchdays);
      lcd.print(" day/s ");


      if (digitalRead(BUT1) == LOW)
      { hatchdays = hatchdays - 1;
        delay(250);
      }
      if (digitalRead(BUT2) == LOW)
      { hatchdays = hatchdays  + 1;
        delay(250);
      }

      if (digitalRead(BUT3) == LOW)
      {
        EEPROM.write(200, hatchdays);
        delay(250);
        lcd.clear();
        menu = 0;
      }
      if (hatchdays < 1) hatchdays = 1;
      if (hatchdays > 45) hatchdays = 45 ;
    }
  }
  // end loop for MENU = 9

 if (menu == 10) {
   while (menu == 10) {
     lcd.clear();
     lcd.setCursor(0, 1);
     lcd.print("  door open...  ");
      if (digitalRead(BUT1) == LOW) {
        lcd.clear();
        menu = 0;
      }
    }
  }
}


// last line in main loop


// subroutine to return the length of the button push.
int getpushlength () {
  buttonstate = digitalRead(BUT3);
  if (buttonstate == LOW && buttonflag == false) {
    pushstart = millis();
    buttonflag = true;
  };

  if (buttonstate == HIGH && buttonflag == true) {
    pushstop = millis ();
    pushlength = pushstop - pushstart;
    buttonflag = false;
  };
  return pushlength;
}

ยังไม่กด ปุ่ม มันก็เลื่อนไปเองครับ