This is an automatic incubator code, with a countdown for egg rolling. It turns out that the count that should be from an hour (00:59:59) to hours, minutes and seconds. Returns a wrong count, like: 1999H: 555M: 2222S.
//EGG INCUBATOR Version 1.0
//|------------------------------------------------------------------------------------------------------|//
//|******************************************************************************************************|//
//|* EGG INCUBATOR CONTROLLER *|//
//|* with TEMPERATURE and HUMIDITY CONTROL *|//
//|* version 1.0 by: RACKS TheNoobTech *|//
//|* November 10, 2019 *|//
//|******************************************************************************************************|//
//|------------------------------------------------------------------------------------------------------|//
// libraries
#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, 2, 1, 0, 4, 5, 6, 7); // 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(" Incubator with ");
lcd.setCursor(0, 2);
lcd.print(" humidity control ");
delay(3000);
lcd.clear();
lcd.setCursor(0, 2);
lcd.print(" by: R a c k s ");
lcd.setCursor(0, 1);
lcd.print(" v e r s i o n 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(" please wait... ");
lcd.setCursor(0, 1);
lcd.print(" Entering ");
lcd.setCursor(0, 2);
lcd.print(" Settings MENU ");
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(" 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();
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("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) 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("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 (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(" Set Temperature: ");
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(" 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;
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(" 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); // 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(" 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); // 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(" Set Humidity: ");
lcd.setCursor(7, 1);
lcd.print(humidityset);
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); // 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("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 > 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("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); // 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 ---------------//