//////////////////////////////////////////////////////////////////////
//REMINDER * change DHT TYPE TO DHT11
// set relay inverted to HIGH
//////////////////////////////////////////////////////////////////////
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#define DHTPIN 14
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16,2);
byte Humidity_down_pin = 34;
byte timer_pin = 35; //pin for the timer dry button
byte on_off_button = 15;
byte Heaterandfanpin = 12;
byte buzzerPin = 23;
int defaulthumiditytarget = 50;
int min_humidity_target = 10;
unsigned long dry_timer = 30; //minutes
int alarm_temp = 50;
bool state_changed = HIGH; // set HIGH to start in OFF state, low to start in dehumidify state
//saved in eeprom
int max_temp = 45;
unsigned long backlight_timeout = 1; //timout in minutes
bool Default_to_prev_humidity = LOW; // HIGH - revert to previous humidity, LOW - revert to off
bool relay_is_inverterd = HIGH; // set to high if relay changing is inverted
unsigned long Main_timeout = 4; //timout in hours
//////////////////////////////////////////////////////////////////////
//dont edit below//dont edit below//dont edit below//dont edit below//
//////////////////////////////////////////////////////////////////////
byte mode = 0;
int savedtemp = 0;
int savedhum = 0;
bool on_off_state = LOW;
int newhumiditytarget = 50; //default humidity target
bool refresh = HIGH;
int before_timer_humidity = 30;
bool timer_already_tripped = HIGH;
int temperature;
int humidity;
bool on_off_pressed_once = LOW;
bool backlight_state = HIGH;
bool high_temp_state = LOW;
unsigned long dehumidify_time1 ; //counter to check
unsigned long dehumidify_time2 ; //counter to check
unsigned long saved_dehumidify_time2 ;
bool already_in_mode_0;
bool already_in_mode_1;
bool already_in_mode_2;
bool already_in_mode_3;
bool Humidity_down_pin_state = LOW;
unsigned long time1 ; //couter to check
unsigned long time2 ; //counter to check
unsigned long time3 ; //time1 - time2
unsigned long time4 = 250; //click check maximum for click, minimum for long click
unsigned long any_button_timer ; //couter to check
void setup() {
Serial.begin(9600);
dht.begin();
lcd.init();
lcd.backlight();
pinMode(on_off_button, INPUT);
pinMode(Humidity_down_pin, INPUT);
pinMode(timer_pin, INPUT);
pinMode(Heaterandfanpin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
digitalWrite(Heaterandfanpin, relay_is_inverterd);
EEPROM.get(0, max_temp);
EEPROM.get(10, backlight_timeout);
EEPROM.get(20, Main_timeout);
EEPROM.get(30, Default_to_prev_humidity);
EEPROM.get(40, relay_is_inverterd);
}
void loop() {
temperature = dht.readTemperature();
humidity = dht.readHumidity();
//Read on off button for click
if(digitalRead(on_off_button) == LOW && on_off_pressed_once == LOW){
on_off_pressed_once = HIGH;
lcd.backlight();
any_button_timer = millis();
time1 = millis();
state_changed = LOW;
delay(50);
}
if(digitalRead(on_off_button) == HIGH && on_off_pressed_once == HIGH){
on_off_pressed_once = LOW;
time2 = millis();
delay(50);
}
time3 = time2 - time1; // DEFINITION OF time3 - DONT CHANGE THIS - for click and long click
if(time3 < time4 && state_changed == LOW){
state_changed = HIGH;
if(mode >= 4){
mode = mode + 1;
refresh = HIGH;
}
}
if(millis() - any_button_timer >= Main_timeout*60000*60){
mode = 0;
}
//Backlight timeout
if(millis() - any_button_timer >= backlight_timeout*60000){
lcd.noBacklight();
}
//menu
if(digitalRead(on_off_button) == LOW && (mode == 1 || mode == 2 || mode == 3)){
mode = 0;
refresh = HIGH;
}
//menu - MAX TEMP
if(time3 > time4 && state_changed == LOW && on_off_pressed_once == LOW){
state_changed = HIGH;
refresh = HIGH;
if(mode >= 0 && mode <=3){
mode = 4;
}
else if( mode >=4){
mode = 0;
}
}
//menu - MAX TEMP - change
if (mode == 4){
if(digitalRead(Humidity_down_pin) == LOW){
max_temp = max_temp + 1;
refresh = HIGH;
delay(500);
}
if(digitalRead(timer_pin) == LOW){
max_temp = max_temp - 1;
refresh = HIGH;
delay(500);
}
}
if(mode == 5){
if(backlight_timeout >= 0 && backlight_timeout < 10){
if(digitalRead(Humidity_down_pin) == LOW){
backlight_timeout = backlight_timeout + 1;
refresh = HIGH;
delay(500);
}
if(digitalRead(timer_pin) == LOW){
backlight_timeout = backlight_timeout - 1;
refresh = HIGH;
delay(500);
}
}
else if(backlight_timeout >= 10){
if(digitalRead(Humidity_down_pin) == LOW){
backlight_timeout = backlight_timeout + 10;
refresh = HIGH;
delay(500);
}
if(digitalRead(timer_pin) == LOW){
backlight_timeout = backlight_timeout - 10;
refresh = HIGH;
delay(500);
}
}
}
if(mode == 6){
if(digitalRead(Humidity_down_pin) == LOW){
Main_timeout = Main_timeout + 1;
refresh = HIGH;
delay(500);
}
if(digitalRead(timer_pin) == LOW && Main_timeout > 1){
Main_timeout = Main_timeout - 1;
refresh = HIGH;
delay(500);
}
}
if(mode == 7){
if(digitalRead(Humidity_down_pin) == LOW){
Default_to_prev_humidity = LOW;
refresh = HIGH;
delay(500);
}
if(digitalRead(timer_pin) == LOW && Main_timeout > 1){
Default_to_prev_humidity = HIGH;
refresh = HIGH;
delay(500);
}
}
if(mode == 8){
if(digitalRead(Humidity_down_pin) == LOW){
relay_is_inverterd = LOW;
refresh = HIGH;
delay(500);
}
if(digitalRead(timer_pin) == LOW){
relay_is_inverterd = HIGH;
refresh = HIGH;
delay(500);
}
}
if(mode == 9){
if(digitalRead(Humidity_down_pin) == LOW){
EEPROM.put(0, max_temp);
EEPROM.put(10, backlight_timeout);
EEPROM.put(20, Main_timeout);
EEPROM.put(30, Default_to_prev_humidity);
EEPROM.put(40, relay_is_inverterd);
lcd.setCursor(0,0);
lcd.print("SAVED TO EEPROM!");
delay(2000);
mode = 0;
refresh = HIGH;
}
}
//Refresh dislay if TEMPERATURE value change
if(savedtemp < temperature || savedtemp > temperature){ //refresh the display only if this value changes
savedtemp = temperature;
refresh = HIGH;
}
//Refresh dislay if HUMIDITY value change
if(savedhum < humidity || savedhum > humidity){ //refresh the display only if this value changes
savedhum = humidity;
refresh = HIGH;
}
//HIGH TEMPSTATE
if(temperature > max_temp && high_temp_state == LOW){
digitalWrite(Heaterandfanpin, relay_is_inverterd);
high_temp_state = HIGH;
refresh = HIGH;
}
//LOW TEMPSTATE
if (temperature <= max_temp && high_temp_state == HIGH){
digitalWrite(Heaterandfanpin, !relay_is_inverterd);
high_temp_state = LOW;
refresh = HIGH;
}
//ALARM STATE
if(temperature >= alarm_temp){
tone(buzzerPin, 2300);
on_off_state = LOW;
delay(100);
} else if(temperature < max_temp){
noTone(buzzerPin);
}
//MODE 0 - OFF
if(mode == 0 && already_in_mode_0 == LOW){
already_in_mode_0 = HIGH;
already_in_mode_1 = LOW;
already_in_mode_2 = LOW;
already_in_mode_3 = LOW;
digitalWrite(Heaterandfanpin, relay_is_inverterd);
newhumiditytarget = defaulthumiditytarget;
timer_already_tripped = HIGH;
lcd.backlight();
refresh = HIGH;
}
//MODE 1 - STANDBY
if(mode == 1 && already_in_mode_1 == LOW){
already_in_mode_0 = LOW;
already_in_mode_1 = HIGH;
already_in_mode_2 = LOW;
already_in_mode_3 = LOW;
digitalWrite(Heaterandfanpin, relay_is_inverterd); //turn off the heater
lcd.backlight();
refresh = HIGH;
}
//MODE 1 - AUTO ON INTO MODE 2
if(temperature < max_temp && mode == 1 && humidity > newhumiditytarget){ //only if below max temp
mode = 2;
}
//MODE 2 - DEHUMIDFYING
//MODE 2 - DEHUMIDIFYING BUTTON
if(digitalRead(Humidity_down_pin) == LOW && Humidity_down_pin_state == LOW && (mode == 0 || mode == 1 || mode == 2 || mode == 3)){
Humidity_down_pin_state = HIGH;
lcd.backlight();
any_button_timer = millis();
//REDUCE TARGET HUMIDITY
if(newhumiditytarget > min_humidity_target){ //if the humidity above min humidity
newhumiditytarget = newhumiditytarget - 5; //subtract 5%
refresh = HIGH;
}
//GO BACK TO DEFAULT HUMIDITY
else {
newhumiditytarget = defaulthumiditytarget; //otherwise reset to default min
refresh = HIGH;
}
mode = 2;
}
else if(digitalRead(Humidity_down_pin) == HIGH){
Humidity_down_pin_state = LOW;
}
//MODE 2 - EXECUTE - TURN OFF
if(mode == 2 && already_in_mode_2 == LOW){ //set to mode 0 if "off"
already_in_mode_0 = LOW;
already_in_mode_1 = LOW;
already_in_mode_2 = HIGH;
already_in_mode_3 = LOW;
digitalWrite(Heaterandfanpin, !relay_is_inverterd); //turn off the heater
timer_already_tripped = LOW;
refresh = HIGH;
delay(500); //delay prevents multiclicking
}
if(mode == 2 && humidity < newhumiditytarget){ //only if below max temp
mode = 1;
}
//MODE 3 - TIMER
if(digitalRead(timer_pin) == LOW && (mode == 0 || mode == 1 || mode == 2 || mode == 3)){
mode = 3;
lcd.backlight();
any_button_timer = millis();
on_off_pressed_once = LOW;
already_in_mode_0 = LOW;
digitalWrite(Heaterandfanpin, !relay_is_inverterd);
dehumidify_time1 = millis();
timer_already_tripped = LOW;
saved_dehumidify_time2 = 0;
if(newhumiditytarget != 0){ //save the non 0 value of prev humidity target
before_timer_humidity = newhumiditytarget;
newhumiditytarget = 0;
refresh = HIGH;
}
}
if(mode == 3){ //refresh the display only if this value changes
dehumidify_time2 = millis() - dehumidify_time1;
if(dehumidify_time2 >= saved_dehumidify_time2 + 1000){
saved_dehumidify_time2 = dehumidify_time2;
}
}
if(dehumidify_time2 >= dry_timer*60000 && timer_already_tripped == LOW && mode == 3){ //execute this once after timer elapsed
timer_already_tripped = HIGH;
newhumiditytarget = before_timer_humidity; // restore to prev humidity target
refresh = HIGH;
if(Default_to_prev_humidity == HIGH){
mode = 2;
}
else{
mode = 0;
on_off_state = LOW;
}
}
//LCD
if(refresh == HIGH){
lcd.clear();
refresh = LOW;
if(mode == 0){
lcd.setCursor(0,0);
lcd.print("OFF");
lcd.setCursor(0,1);
lcd.print(temperature);
lcd.print((char)223);
lcd.print("C");
if(temperature > max_temp){
lcd.print("!");
}
lcd.setCursor(8,1);
lcd.print(humidity);
lcd.print("%");
}
if(mode == 1){
lcd.setCursor(0,0);
lcd.print("STANDBY");
lcd.setCursor(0,1);
lcd.print(temperature);
lcd.print((char)223);
lcd.print("C");
if(temperature > max_temp){
lcd.print("!");
}
lcd.setCursor(8,1);
lcd.print(humidity);
lcd.print("%");
lcd.print((char)126);
lcd.print(newhumiditytarget);
lcd.print("%");
}
if(mode == 2){
lcd.setCursor(0,0);
lcd.print("DRYING FILAMENT");
lcd.setCursor(0,1);
lcd.print(temperature);
lcd.print((char)223);
lcd.print("C");
if(temperature > max_temp){
lcd.print("!");
}
lcd.setCursor(8,1);
lcd.print(humidity);
lcd.print("%");
lcd.print((char)126);
lcd.print(newhumiditytarget);
lcd.print("%");
}
if(mode == 3){
lcd.setCursor(0,0);
lcd.print("TIMER");
lcd.setCursor(8,0);
lcd.print(dry_timer - dehumidify_time2/60000);
lcd.print(" min");
lcd.setCursor(0,1);
lcd.print(temperature);
lcd.print((char)223);
lcd.print("C");
if(temperature > max_temp){
lcd.print("!");
}
lcd.setCursor(8,1);
lcd.print(humidity);
lcd.print("%");
lcd.print((char)126);
lcd.print(newhumiditytarget);
lcd.print("%");
}
if(mode == 4){
lcd.setCursor(0,0);
lcd.print((char)127);
lcd.print("MAX TEMP");
lcd.setCursor(15,0);
lcd.print((char)126);
lcd.setCursor(1,1);
lcd.print(max_temp);
lcd.print((char)223);
}
if(mode == 5){
lcd.setCursor(0,0);
lcd.print((char)127);
lcd.print("LIGHT TIMEOUT");
lcd.setCursor(15,0);
lcd.print((char)126);
lcd.setCursor(1,1);
lcd.print(backlight_timeout);
if(backlight_timeout == 1){
lcd.print(" MINUTE");
}
else{
lcd.print(" MINUTES");
}
}
if(mode == 6){
lcd.setCursor(0,0);
lcd.print((char)127);
lcd.print("MAIN TIMEOUT");
lcd.setCursor(15,0);
lcd.print((char)126);
lcd.setCursor(1,1);
lcd.print(Main_timeout);
if(Main_timeout == 1){
lcd.print(" HOUR");
}
else{
lcd.print(" HOURS");
}
}
if(mode == 7){
lcd.setCursor(0,0);
lcd.print((char)127);
lcd.print("TIME END INTO");
lcd.setCursor(15,0);
lcd.print((char)126);
lcd.setCursor(1,1);
if(Default_to_prev_humidity == HIGH){
lcd.print("DEHUMIDIFY");
}
else{
lcd.print("OFF MODE");
}
}
if(mode == 8){
lcd.setCursor(0,0);
lcd.print((char)127);
lcd.print("RELAY MODE");
lcd.setCursor(15,0);
lcd.print((char)126);
lcd.setCursor(1,1);
if(relay_is_inverterd == HIGH){
lcd.print("INVERTED");
}
else{
lcd.print("NORMAL");
}
}
if(mode == 9){
lcd.setCursor(0,0);
lcd.print((char)127);
lcd.print("SAVE TO EEPROM");
}
}
}
LOWERS THE HUMIDITY TARGET BY 5%
SETS 30 MIN TIMER @ 0% HUMIDTY
(RESETS TO PREVIOUS HUMIDITY TARGET)
ON/OFF