#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <EEPROM.h>
// Define pins
#define DHTPIN 2 // DHT sensor pin
#define RELAY_PIN1 11 // Relay pin for heater/fan
#define RELAY_PIN2 12 // Relay pin for humidifier
#define BUTTON_PIN1 3 // Push button1 pin
#define BUTTON_PIN2 4 // Push button2 pin
#define BUTTON_PIN3 5 // SET button pin
float currentTemp = 0.0;
float currentHumidity = 0.0;
// Define saved var
const float savedTemp = 0.0;
const float savedHumidity = sizeof(float);
const float savedDiff_Temp = 2 * sizeof(float);
const float savedDiff_Humidity = 3 * sizeof(float);
// Define var for user input and save in EEP ROM
float diffTemp = 2.0 ;
float diffHumidity = 5.0 ;
float desiredTemp = 35.0 ;
float desiredHumidity = 60.0 ;
bool relay1_State = false;
bool relay2_State = false;
bool overHeat = false;
int var = 0;
int day = 0;
int modeNo = 0;
// char mode;
// Define sensor Library
#define DHTTYPE DHT22 // DHT 22 (AM2302)
// Initialize the DHT sensor
DHT dht(DHTPIN, DHTTYPE);
// Initialize the LCD (address 0x27, 16 columns and 2 rows)
LiquidCrystal_I2C lcd(0x27, 20, 4);
// To avoid long press button
int outputState = LOW; // tracks the current state of LED
int lastButtonState; // the previous state of button
int currentButtonState; // the current state of button
void writeValuesToEEPROM() {
EEPROM.put(savedTemp, desiredTemp);
EEPROM.put(savedHumidity, desiredHumidity);
EEPROM.put(savedDiff_Temp, diffTemp);
EEPROM.put(savedDiff_Humidity, diffHumidity);
}
void readValuesFromEEPROM() {
EEPROM.get(savedTemp, desiredTemp);
EEPROM.get(savedHumidity, desiredHumidity);
EEPROM.get(savedDiff_Temp, diffTemp);
EEPROM.get(savedDiff_Humidity, diffHumidity);
}
void setup() {
lcd.clear();
lcd.init();
lcd.backlight();
dht.begin();
// Serial.begin(9600);
pinMode(RELAY_PIN1, OUTPUT);
pinMode(RELAY_PIN2, OUTPUT);
pinMode(BUTTON_PIN1, INPUT);
pinMode(BUTTON_PIN2, INPUT);
lcd.setCursor(0,0);
lcd.print("NATURE ELECTRONICS");
lcd.setCursor(2,1);
lcd.print("INCUBATOR");
lcd.setCursor(8,2);
lcd.print("CONTROLLER");
lcd.setCursor(2,3);
lcd.print("V_0.1");
delay(3000);
lcd.clear();
readValuesFromEEPROM();
}
/////// Output temp and humidity relay
void Output(bool R1_State, bool R2_State) {
digitalWrite(RELAY_PIN1, R1_State);
digitalWrite(RELAY_PIN2, R2_State);
}
void loop() {
// Read current temperature & Humidity
currentTemp = dht.readTemperature();
currentHumidity = dht.readHumidity();
Output(relay1_State, relay2_State);
mainDisplay(); // PV , SV display sub function
setButton(); // SET button sub function
//////////
while( var == 1) {
Output(relay1_State = false, relay2_State = false); // Closed output relays
//Adjust(desiredTemperature, maximum, minimum, variable)
Adjust(desiredTemp, 45.0, 25.0, var ); // Adjust add or reduce temperature //sub
EEPROM.put(savedTemp, desiredTemp);
lcd.setCursor(2,0); lcd.print("SET TEMPERATURE");
lcd.setCursor(18,3); lcd.print(">>");
lcd.setCursor(5,2); lcd.print(savedTemp);
lcd.setCursor(13,2); lcd.print("'C");
setButton();
//Serial.println(savedTemp);
}
/////// Set different temperature
while( var == 2) {
Output(relay1_State = false, relay2_State = false); // Closed output relays
Adjust(diffTemp, 5.0, 0.2, var );
lcd.setCursor(3,0); lcd.print("SET TEMP DIFF.");
lcd.setCursor(18,3); lcd.print(">>");
lcd.setCursor(5,2); lcd.print(diffTemp);
lcd.setCursor(13,2); lcd.print("'C");
setButton();
}
//////// When SET button is pressed.
while( var == 3) {
Output(relay1_State = false, relay2_State = false); // Closed output relays
Adjust(desiredHumidity, 95.0, 45.0, var ); // Adjust add or reduce humidity
lcd.setCursor(3,0); lcd.print("SET HUMIDITY");
lcd.setCursor(18,3); lcd.print(">>");
lcd.setCursor(5,2); lcd.print(desiredHumidity);
lcd.setCursor(13,2); lcd.print(" %");
setButton();
}
//////////////
while( var == 4) {
lcd.setCursor(3,0); lcd.print("SET HUMI DIFF.");
lcd.setCursor(18,3); lcd.print(">>");
Output(relay1_State = false, relay2_State = false); // Closed output relays
Adjust(diffHumidity, 10.0, 3.0, var );
lcd.setCursor(5,2); lcd.print(diffHumidity);
lcd.setCursor(13,2); lcd.print(" %");
setButton();
}
if ( var == 5) {
var = var - 5;
lcd.setCursor(5,1); lcd.print("VALUE");
lcd.setCursor(10,2); lcd.print("SAVED");
delay(1500);
lcd.clear();
}
// Control the relay based on current temperature
if(currentTemp <= desiredTemp-diffTemp) {
relay1_State = true; }
else if (currentTemp < desiredTemp && relay1_State == true) {
relay1_State = true; }
else {
relay1_State = false; }
// Control the relay based on current humidity
if (currentHumidity <= desiredHumidity-diffHumidity) {
relay2_State = true; }
else if(currentHumidity < desiredHumidity && relay2_State == true) {
relay2_State = true; }
else {
relay2_State = false; }
// Notification to user by blinking LCD for over/under heat
if( currentTemp > 40.0) {
do{ blinkLCD(); }while(currentTemp <= 38.0 ); }
if(currentTemp < 30.0) {
do{ blinkLCD(); }while(currentTemp >= 37.0 ); }
// Notification to user by blinking LCD for over/under humidity
if(currentHumidity < 40) {
do{ blinkLCD(); }while(currentHumidity >= 60.0); }
if(currentHumidity > 90.0 ) {
do{ blinkLCD(); }while(currentHumidity <= 70.0 ); }
//delay(100); // Update every second
}
///////////
// PV and SV main display
void mainDisplay() {
lcd.setCursor(4, 0); lcd.print("PV");
lcd.setCursor(12,0); lcd.print("SV");
// Display the temperature and humidity on the LCD
lcd.setCursor(0, 1); lcd.print("T: "); lcd.print(currentTemp);
lcd.setCursor(17, 1); lcd.print("'C");
lcd.setCursor(0, 2); lcd.print("H: "); lcd.print(currentHumidity);
lcd.setCursor(17,2); lcd.print(" %");
lcd.setCursor(11, 1); lcd.print(desiredTemp);
lcd.setCursor(11, 2); lcd.print(desiredHumidity);
lcd.setCursor(0, 3); lcd.print("D:");
lcd.setCursor(3, 3); lcd.print(day);
// lcd.setCursor(9, 3); lcd.print("M:");
// lcd.setCursor(10, 3); lcd.print(modeNo);
// lcd.setCursor(14, 3); lcd.print(mode);
// lcd.setCursor(11, 3); lcd.print(mode);
if(relay1_State == true) {
lcd.setCursor(9,1); lcd.print("^"); }
if(relay1_State == false) {
lcd.setCursor(9,1); lcd.print(" "); }
if(relay2_State == true) {
lcd.setCursor(9,2); lcd.print("^"); }
if(relay2_State == false) {
lcd.setCursor(9,2); lcd.print(" "); }
}
/////////////////
//SET button
void setButton( ) {
lastButtonState = currentButtonState; // save the last state
currentButtonState = digitalRead(BUTTON_PIN3); // read new state
delay(50);
if(lastButtonState == HIGH && currentButtonState == LOW) {
// Serial.print("The SET button is pressed: ");
var += 1;
lcd.clear();
return; }
}
// Adjustment function
void Adjust(float mainValue, float valueMax, float valueMin, int sw) {
if (digitalRead(BUTTON_PIN1)) { // Plus temperature
delay(300); // Debounce delay
mainValue += 0.1; // Increase desired temperature by 1°C
if (mainValue > valueMax) { // Limit to 50°C if it exceeds 50°C
mainValue = valueMax;
} }
if (digitalRead(BUTTON_PIN2) == HIGH) { // Minus temperature
delay(300); // Debounce delay
mainValue -= 0.1; // decrease desired temperature by 1°C
if (mainValue < valueMin) { // Limit to 30°C if it exceeds 30°C
mainValue = valueMin;
} }
// Switching return values
if(sw == 1) { desiredTemp = mainValue; }// return (desiredTemp); }
if(sw == 2) { diffTemp = mainValue; }// return (diffTemp); }
if(sw == 3) { desiredHumidity = mainValue; }// return (desiredHumidity); }
if(sw == 4) { diffHumidity = mainValue; }// return (diffHumidity); }
// return (desiredTemp);
// return (desiredHumidity);
// return (diffTemp);
// return (diffHumidity);
}
// Function to blink the LCD
void blinkLCD() {
//for (int i = 0; i < times; i++) {
lcd.noBacklight(); // Turn on backlight
delay(300); // Wait for 500 ms
lcd.backlight(); // Turn off backlight
delay(200); // Wait for 500 ms
}