#include <Wire.h>
#include "LiquidCrystal_I2C.h"
#include <EEPROM.h>
#include <dht.h>
#define DHTPIN A0 // DHT data pin we're connected to A0
dht DHT; // creates DHT object
LiquidCrystal_I2C lcd(0x27,20 ,4); // set the LCD address to 0x27 for 20 chars and 4 lines display (other I2C address is 0x3F)
uint8_t arrow[8] = {0x1F, 0x17, 0x1B, 0x1D, 0x17, 0x1F}; // creates arrow char
byte degree[8] = {B01100, B10010, B10010, B01100, B00000, B00000, B00000}; // creates degress char
// define pins for relays or LEDs
#define temperaturepin A1
#define humiditypin A2
#define motorpin 5
#define errorpin 4
#define fan 9
// define global variables
float t1, tempset, tempdefference, errtemp; // variables for time
float humidityset, humiditydefference, errhumid; // variables for humidity
byte heat; // value of 1 is for heater and value of 0 is for cooler
byte dry; // value of 1 is for dryer and value of 0 is for wetter
// define buttons
#define BUT1 6 // decreament button
#define BUT2 7 // increament button
#define BUT3 8 // MENU button
#define BUT4 11 // limit switch for open door
#define BUT5 10 // egg rack posistion 0
// creates number of menus
byte menu = 10; // MENU = 0 ---> initial MENU
// MENU = 1 ---> set temp
// MENU = 2 ---> set temp defference
// MENU = 3 ---> humidity set
// MENU = 4 ---> humidity defference
// MENU = 5 ---> set time for egg turner interval (hours)
// MENU = 6 ---> set time for egg turner motor duration (seconds)
// MENU = 7 ---> set temp error
// MENU = 8 ---> set humidity error
// time variables
int is, im, ih, id, ida; // variables for time
float taim, sl, ml, hl, dl; // set up variables to calculate time
int timebetweenspinsHour, motorspinduration, hatchdays, remainingdays, daysremains;
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 pushbuttons routine
int buttonstate = 0; // flag to see if the button has been pressed, used internal on the subroutine only
int pushlenghtset = 4000; // value for long press in Ms
int pushlenght = pushlenghtset; // set default pushlenght
int pushstart = 0; // set default push value for the button going low
int pushstop = 0; // set default value for 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()
{
// initialize the I2C 20x4 LCD
lcd.begin(20, 4);
// lcd.setBacklightPin(3, POSITIVE);
lcd.setBacklight(HIGH);
// create custom symbol
lcd.createChar(0, degree);
lcd.createChar(1, arrow);
// Turn on backlight
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
digitalWrite(temperaturepin, HIGH);
digitalWrite(humiditypin, HIGH);
digitalWrite(motorpin, HIGH);
digitalWrite(errorpin, HIGH);;
//SET PUSH BUTTONS FOR MENU
pinMode(BUT1, INPUT);
pinMode(BUT2, INPUT);
pinMode(BUT3, INPUT);
pinMode(BUT4, INPUT);
pinMode(BUT5, INPUT);
digitalWrite(BUT1, HIGH); // pull-ups on
digitalWrite(BUT2, HIGH);
digitalWrite(BUT3, HIGH);
digitalWrite(BUT4, HIGH);
digitalWrite(BUT5, HIGH);
lcd.setCursor(0,1);
lcd.print(" CHOCADEIRA COM ");
lcd.setCursor(0,2);
lcd.print("CONTROLE DE HUMIDADE");
delay(3000);
lcd.clear();
lcd.setCursor(0,2);
lcd.print(" EDY ELETRONICA ");
lcd.setCursor(0,1);
lcd.print(" VERSAO 1 ");
delay(3000);
lcd.clear();
heat = 1 ; // 1 for heater and 0 for cooler (temp)
dry = 1; // 1 for dryer and 0 for wetter (humidity)
//just first time uploading sketch... after must put comment (//)
// save intitial setpoint to eepron
/* 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 apints
EEPROM.Write(207,10); // time in seconds for rotations
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 * 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);
pushlenght = pushlenghtset;
pushlenght = getpushlenght();
delay(10);
if (pushlenght > pushlenghtset)
{
menu = 1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("PORVAFOR, AGUARDE...");
lcd.setCursor(0,1);
lcd.print(" ENTRANDO ");
lcd.setCursor(0,2);
lcd.print(" MENU CONFIGURACOES ");
delay(2000);
pushlenght = pushlenghtset;
delay(50);
entrymenu = millis(); // store time when enter in setup menu
}
if (pushlenght < pushlenghtset)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("PRESSIO. BOTAO ENTER");
lcd.setCursor(0,1);
lcd.print(" POR 5 SEGUNDOS ");
lcd.setCursor(0,2);
lcd.print("PARA ENTRAR NO MENU");
delay(3000);
lcd.clear();
pushlenght = pushlenghtset;
}
if (doorstatus == HIGH){
lcd.clear();
lcd.setCursor(0,2);
lcd.print(" Door is 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 is Open ");
lcd.setCursor(0,3);
lcd.print(" Rack is Centered ");
}
delay(1000);
}
if (doorstatus == LOW) {
digitalWrite(motorpin, HIGH);
}
// reading DHT sensor for Temperature and Humidity
int readData = DHT.read22(DHTPIN);
float humidityreading = DHT.humidity; // read humidity
float temperaturereading = DHT.temperature; // read temperature
//check DHT sensor if any reads failed or exit early ( to try read 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 MENU 0
lcd.setCursor(0,0);
lcd.print("Temper= ");
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("Umidade= ");
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) 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) and (humidityerror == 0))
{
error = 0;
cancel = 0;
}
// part of remaining days
taim = millis(); // get time in milliseconds since the unit turns on
sl = taim/1000; // convert time to seconds, minutes, hours, days
ml = sl/60;
hl = ml/60;
dl = hl/24;
id = int(dl);
ih = int((dl-int(dl))*24); // strip out remainder to leave Days:Hours:Minutes:Seconds
im = int((hl-int(dl))*60);
is = int((ml-int(ml))*60);
// calculate approximate days till hatch (maximum hatch settings is 45 days)
ida = hatchdays - id;
repeatrotationtime = - millis() + durationB4spin - rotationtime; // time to repeat egg turner
repeatrotationtime = repeatrotationtime/1000; // ms --> sec
hour = repeatrotationtime/3600;
rest = repeatrotationtime - 3600*hour;
minutes = rest/60;
seconds = rest - 60*minutes;
lcd.setCursor(0,2);
lcd.print("Tempo= ");
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("Chocar em: ");
if ((ida >=0) && (ida <10)) lcd.print(" ");
lcd.print(ida);
lcd.print(" dias");
// spins part (egg turner)
while (((millis() - rotationtime) > durationB4spin) && (rotate == 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 of menu 0
//------------------------------------------//
if (menu == 1) {
lcd.clear();
while (menu == 1) {
if (millis() - entrymenu > exitmenu) menu = 0;
lcd.setCursor(0,0);
lcd.print("DEFINIR TEMPERATURA:");
lcd.setCursor(5,1);
lcd.write(byte(1));
lcd.setCursor(7,1);
lcd.print(tempset,1);
lcd.write(byte(0));
lcd.print("C ");
lcd.setCursor(0,2);
lcd.print("DIFERENCA DA TEMPER:");
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;
byte tset1 = tes2 / 256;
byte tset2 = tes2 - tset1 * 256;
if (digitalRead(BUT3) == LOW)
{
EEPROM.write(201, tset1); // save temp settings to eeprom
EEPROM.write(202, tset2); // save temp setpoint to eeprom
menu = 2;
delay(250);
lcd.clear();
}
}
delay(100);
}
// end of menu 1
if (menu == 2) {
while (menu == 2) {
if (millis() - entrymenu > exitmenu) menu = 0;
lcd.setCursor(0,0);
lcd.print("DEFINIR TEMPERATURA:");
lcd.setCursor(7,1);
lcd.print(tempset,1);
lcd.write(byte(0));
lcd.print("C ");
lcd.setCursor(0,2);
lcd.print("DIFERENCA DA TEMPER:");
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); // save tempdefference settings to eeprom
menu = 3;
delay(250);
lcd.clear();
}
}
// end of menu 2
//---------------------------------------------------//
if (menu == 3) {
while (menu == 3) {
if (millis() - entrymenu > exitmenu) menu = 0;
lcd.setCursor(0,0);
lcd.print(" Definir Umidade: ");
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("DIFERENCIA UMIDADE:");
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); // save humidity settings to eeprom
menu = 4;
delay(250);
lcd.clear();
}
}
delay(250);
}
// end of menu 3
//---------------------------------------------------//
if (menu == 4) {
while (menu == 4) {
if (millis() - entrymenu > exitmenu) menu = 0;
lcd.setCursor(0,0);
lcd.print(" Definir Umidade: ");
lcd.setCursor(7,1);
lcd.print(humidityset);
lcd.write(byte(0));
lcd.print("%RH ");
lcd.setCursor(0,2);
lcd.print("DIFERENCIA UMIDADE");
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); // save humiditydefference settings to eeprom
menu = 5;
delay(250);
lcd.clear();
}
if (humiditydefference <1) humiditydefference = 1;
}
}
// end of menu 4
//---------------------------------------------//
if (menu == 5) {
while (menu == 5) {
if (millis() - entrymenu > exitmenu) menu = 0;
lcd.setCursor(0,0);
lcd.print("Tempo Rolagem do Ovo");
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 > 1) 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, timebetweenspinsHour); // save time interval between spins settings to eeprom
delay(250);
lcd.clear();
durationB4spin = timebetweenspinsHour * 3600000; // hrs --> ms
menu = 6;
}
}
}
// end of menu 5
//-----------------------------------------------------------//
if (menu == 6) {
while (menu == 6) {
if (millis() - entrymenu > exitmenu) menu = 0;
lcd.setCursor(0,0);
lcd.print("Duracao da Execucao");
lcd.setCursor(0,1);
lcd.print("do Motor em rotacao ");
lcd.setCursor(0,2);
lcd.print(" do Ovo: ");
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); // save time settings for running duration of tilt motor to eeprom
delay(250);
lcd.clear();
durationONspin = motorspinduration * 1000; // sec --> ms
menu = 7;
}
}
}
// end of 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); // save settings to eeprom for tolerance of error message to appear on lcd screen(temperature)
menu = 8;
delay(250);
lcd.clear();
}
}
}
// end of 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 (errhumid < 1) errhumid = 1;
if (errhumid > 10) errhumid = 10;
if (digitalRead(BUT3) == LOW)
{
EEPROM.write(209, errhumid); // save settings to eeprom for tolerance of error message to appear on lcd screen(humidity)
menu = 9;
delay(250);
lcd.clear();
}
}
}
// end of 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 (hatchdays < 1) hatchdays = 1;
if (hatchdays > 45) hatchdays = 45;
if (digitalRead(BUT3) == LOW)
{
EEPROM.write(200, hatchdays); // save hatch day settings to eeprom
menu = 0;
delay(250);
lcd.clear();
}
}
}
// end of menu 9
//-----------------------------------------------------------//
if (menu == 10) {
while (menu == 10) {
lcd.clear();
lcd.setCursor(0,1);
lcd.print(" Door is Open... ");
if (digitalRead(BUT4 == LOW)) {
lcd.clear();
menu = 0;
}
}
}
}
}
// last line of void loop
//-----------------------------------------------------//
// subroutine to return the lenght of the push button
int getpushlenght() {
buttonstate = digitalRead(BUT3);
if (buttonstate == LOW && buttonflag == false) {
pushstart = millis();
buttonflag = true;
};
if (buttonstate == HIGH && buttonflag == true) {
pushstop = millis();
pushlenght = pushstop - pushstart;
buttonflag = false;
};
return pushlenght;
}
//--------------- END OF PROGRAM ---------------//