//Nicolas Jarpa
//Multiple Timer 2 Timers+RTC3231+LCD+independet Relays+Everyday+eeprom
#include "DHT.h"
#include <EEPROM.h>
#include <RTClib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);//0x3F is my lcd address, maybe not yours!
RTC_DS3231 RTC;
#define DHTPIN 11
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
int D, M, A;
//-----------------------//
//------Variables--------//
//-----------------------//
//------First Timer
byte onhour1;
byte onmin1;
byte onsec1;
byte offhour1;
byte offmin1;
byte offsec1;
//-----Second Timer
byte onhour2;
byte onmin2;
byte onsec2;
byte offhour2;
byte offmin2;
byte offsec2;
//------Pages or menus
int page_counter=1;
int subpage1_counter=0; //Timer 1 on/off
int subpage2_counter=0; //Timer 2 on/off
//-------To convert clock into single number
unsigned long Time;
unsigned long Hour;
unsigned long Min;
unsigned long Sec;
//------To convert first timer into Single number
unsigned long on_Time1;
unsigned long on_hour1;
unsigned long on_min1;
unsigned long on_sec1;
unsigned long off_Time1;
unsigned long off_hour1;
unsigned long off_min1;
unsigned long off_sec1;
//------To convert second timer into Single number
unsigned long on_Time2;
unsigned long on_hour2;
unsigned long on_min2;
unsigned long on_sec2;
unsigned long off_Time2;
unsigned long off_hour2;
unsigned long off_min2;
unsigned long off_sec2;
//-------Push buttons current/last state
boolean current_up = LOW;
boolean last_up=LOW;
boolean current_sel = LOW;
boolean last_sel = LOW;
boolean last_down = LOW;
boolean current_down = LOW;
//-------Pins
byte Relay1 =13;//Relay 1 to pin 13
byte Relay2 =12;//Relay 2 to pin 12
int up=2; //Up button to pin 2 //All buttons configured as pulldown
int sel=3; //Select button to pin 3
int down=4; //Down button to pin 4
//------Relay States
boolean RelayState1;
boolean RelayState2;
byte grau[8] ={ B00001100,
B00010010,
B00010010,
B00001100,
B00000000,
B00000000,
B00000000,
B00000000,};
//Custom return char
byte back[8] = {
0b00100,
0b01000,
0b11111,
0b01001,
0b00101,
0b00001,
0b00001,
0b11111
};
//Custom arrow char
byte arrow[8] = {
0b01000,
0b00100,
0b00010,
0b11111,
0b00010,
0b00100,
0b01000,
0b00000
};
void setup() {
pinMode(Relay1, OUTPUT);
pinMode(Relay2,OUTPUT);
Serial.begin(9600); //Inicializa a serial
lcd.begin(16,2); //Inicializa LCD
lcd.clear(); //Limpa o LCD
//Cria o caractere customizado com o simbolo do grau
lcd.createChar(0, grau);
dht.begin();
Wire.begin();
RTC.begin();
lcd.init();
lcd.backlight();
lcd.clear();
lcd.createChar(1, back);//Custom chars
lcd.createChar(2, arrow);
//--------eePROM read values-------//
//------First Timer
onhour1=EEPROM.read(0);
onmin1=EEPROM.read(1);
onsec1=EEPROM.read(2);
offhour1=EEPROM.read(3);
offmin1=EEPROM.read(4);
offsec1=EEPROM.read(5);
//------Second Timer
onhour2=EEPROM.read(6);
onmin2=EEPROM.read(7);
onsec2=EEPROM.read(8);
offhour2=EEPROM.read(9);
offmin2=EEPROM.read(10);
offsec2=EEPROM.read(11);
}//void setup
//---- De-bouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(10);
current = digitalRead(pin);
}
return current;
}
void loop() {
float h = dht.readHumidity(); //Le o valor da umidade
float t = dht.readTemperature(); //Le o valor da temperatura
current_up = debounce(last_up, up); //Debounce for Up button
current_sel = debounce(last_sel, sel); //Debounce for Select button
current_down = debounce(last_down, down); //Debounce for Down button
DateTime now = RTC.now(); // Clock call
now = RTC.now();
//-----Up/Down functions to move main pages------///
if(subpage1_counter==0 && subpage2_counter==0){ //up/down buttons enabled if subpages counters are 0,Disabled if 1,2..etc to work on submenus
//Page Up
if (last_up== LOW && current_up == HIGH){ //Up button pressed
lcd.clear(); //Clear lcd if page is changed to print new one
if(page_counter <4){ //Page counter never higher than 4(total of pages)
page_counter ++; //Page up
}
else{
page_counter= 1; //If higher than 4 (last page)go to main page
}
}
last_up = current_up; //Save up button last state
//Page Down
if (last_down== LOW && current_down == HIGH){//Down button pressed
lcd.clear(); //Clear lcd if page is changed to print new one
if(page_counter >1){ //Page counter never lower than 1
page_counter --; //Page down
}
else{
page_counter= 4; //If lower than 1(first page)go to last page
}
}
last_down = current_down; //Save down button last state
}
//------------Pages and submenus display and control----------//
switch (page_counter){
case 1: //Content of main page
last_sel=current_sel; //Salvar o último estado do botão de seleção quando saltarmos da tela de salvamento
lcd.setCursor(0,0);
lcd.print(" TEMPORIZADOR ");
lcd.setCursor(0,1);
lcd.print("Hora");
lcd.setCursor(0,2);
lcd.print("Temp : ");
lcd.setCursor(13,2);
lcd.print("C");
lcd.print(" ");
lcd.setCursor(7,2);
lcd.print(t,1);
lcd.setCursor(12,2);
//Mostra o simbolo do grau formado pelo array
lcd.write((byte)0);
//Mostra o simbolo do grau quadrado
//lcd.print((char)223);
lcd.setCursor(0,3);
lcd.print("Umid : ");
lcd.setCursor(13,3);
lcd.print("RH");
lcd.print(" ");
lcd.setCursor(7,3);
lcd.print(h,1);
lcd.setCursor(12,3);
lcd.print("%");
//Intervalo recomendado para leitura do sensor
//--------Show Time On LCD
lcd.setCursor(7,1);
if(now.hour() < 10)
{
lcd.print("0");
}
lcd.print(now.hour(), DEC); //Print hour
lcd.print(':');
if(now.minute() < 10)
{
lcd.print("0");
}
lcd.print(now.minute(), DEC); //Print min
lcd.print(':');
if(now.second() < 10)
{
lcd.print("0");
}
lcd.print(now.second(), DEC); //Print sec
//case 1
break;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
case 2: //Content and functions of page 2
lcd.setCursor(0,0);
lcd.print(" Temporizador 1 ");
lcd.setCursor(3,2);
lcd.print("ON");
lcd.setCursor(1,3);
lcd.write(byte(1));
lcd.setCursor(3,3);
lcd.print("OFF");
lcd.setCursor(7,2); //Printing on/off values
if(onhour1<9){
lcd.print("0");
}
lcd.print(onhour1);
lcd.setCursor(10,2);
if(onmin1<10){
lcd.print("0");
}
lcd.print(onmin1);
lcd.setCursor(13,2);
if(onsec1<10){
lcd.print("0");
}
lcd.print(onsec1);
lcd.setCursor(7,3);
if(offhour1<10){
lcd.print("0");
}
lcd.print(offhour1);
lcd.setCursor(10,3);
if(offmin1<10){
lcd.print("0");
}
lcd.print(offmin1);
lcd.setCursor(13,3);
if(offsec1<10){
lcd.print("0");
}
lcd.print(offsec1);
//--------------Modifying on/off values-------//
// Sub counter control
if (last_sel== LOW && current_sel == HIGH){ //select button pressed
if(subpage1_counter <7){ // subpage counter never higher than 7 (total of items)
subpage1_counter ++; //subcounter to move beetwen submenu
}
else{ //If subpage higher than 7 (total of items) return to first item
subpage1_counter=1;
}
}
last_sel=current_sel; //Save last state of select button
//First item control(subpage_counter =1) onhour1
if(subpage1_counter==1){
lcd.setCursor(0,3); //Delete last arrow position (back)
lcd.print(" ");
lcd.setCursor(6,2); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(onhour1 < 23){
onhour1 ++;
}
else{
onhour1 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(onhour1 >0){
onhour1 --;
}
else{
onhour1=23;
}
}
last_down=current_down;
}//subpage1_counter 1
//Second item control(subpage_counter =2) onmin1
if(subpage1_counter==2){
lcd.setCursor(6,2); //Delete last arrow position (onhour1)
lcd.print(" ");
lcd.setCursor(9,2); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(onmin1 < 59){
onmin1 ++;
}
else{
onmin1 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(onmin1 >0){
onmin1 --;
}
else{
onmin1=59;
}
}
last_down=current_down;
}//subpage1_counter 2
//Thirth item control(subpage_counter =3) onsec1
if(subpage1_counter==3){
lcd.setCursor(9,2); //Delete last arrow position (onmin1)
lcd.print(" ");
lcd.setCursor(12,2); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(onsec1 < 59){
onsec1 ++;
}
else{
onsec1 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(onsec1 >0){
onsec1 --;
}
else{
onsec1=59;
}
}
last_down=current_down;
}//subpage1_counter 3
//fourth item control(subpage_counter =4) offhour1
if(subpage1_counter==4){
lcd.setCursor(12,2); //Delete last arrow position (onsec1)
lcd.print(" ");
lcd.setCursor(6,3); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(offhour1 < 23){
offhour1 ++;
}
else{
offhour1 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(offhour1 >0){
offhour1 --;
}
else{
offhour1=23;
}
}
last_down=current_down;
}//subpage1_counter 4
//fifth item control(subpage_counter =5) offmin1
if(subpage1_counter==5){
lcd.setCursor(6,3); //Delete last arrow position (offhour1)
lcd.print(" ");
lcd.setCursor(9,3); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(offmin1 < 59){
offmin1 ++;
}
else{
offmin1 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(offmin1 >0){
offmin1 --;
}
else{
offmin1=59;
}
}
last_down=current_down;
}//subpage1_counter 5
//sixth item control(subpage_counter =6) offsec1
if(subpage1_counter==6){
lcd.setCursor(9,3); //Delete last arrow position (offmin1)
lcd.print(" ");
lcd.setCursor(12,3); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(offsec1 < 59){
offsec1 ++;
}
else{
offsec1 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(offsec1 >0){
offsec1 --;
}
else{
offsec1=59;
}
}
last_down=current_down;
}//subpage1_counter 6
//seventh item control(subpage_counter =7) back
if(subpage1_counter==7){
lcd.setCursor(12,3); //Delete last arrow position (offsec1)
lcd.print(" ");
lcd.setCursor(0,3); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
lcd.setCursor(0,3); //Delete last arrow position (back) to exit
lcd.print(" ");
subpage1_counter=0; //Exit submenu. Up/down butons enabled to move main pages
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
lcd.setCursor(0,3); //Delete last arrow position (back)
lcd.print(" ");
subpage1_counter=1; //Go to first item (onhour1)
}
last_down=current_down;
}//subpage1_counter 7
//case 2
break;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
case 3: //Content and functions of page 3
lcd.setCursor(0,0);
lcd.print(" Temporizador 2 ");
lcd.setCursor(3,2);
lcd.print("ON");
lcd.setCursor(1,3);
lcd.write(byte(1));
lcd.setCursor(3,3);
lcd.print("OFF");
lcd.setCursor(7,2); //Printing on/off values
if(onhour2<10){
lcd.print("0");
}
lcd.print(onhour2);
lcd.setCursor(10,2);
if(onmin2<10){
lcd.print("0");
}
lcd.print(onmin2);
lcd.setCursor(13,2);
if(onsec2<10){
lcd.print("0");
}
lcd.print(onsec2);
lcd.setCursor(7,3);
if(offhour2<10){
lcd.print("0");
}
lcd.print(offhour2);
lcd.setCursor(10,3);
if(offmin2<10){
lcd.print("0");
}
lcd.print(offmin2);
lcd.setCursor(13,3);
if(offsec2<10){
lcd.print("0");
}
lcd.print(offsec2);
//--------------Modifying on/off values-------//
// Sub counter control
if (last_sel== LOW && current_sel == HIGH){ //select button pressed
if(subpage2_counter <7){ // subpage counter never higher than 7 (total of items)
subpage2_counter ++; //subcounter to move beetwen submenu
}
else{ //If subpage higher than 7 (total of items) return to first item
subpage2_counter=1;
}
}
last_sel=current_sel; //Save last state of select button
//First item control(subpage2_counter =1) onhour2
if(subpage2_counter==1){
lcd.setCursor(0,3); //Delete last arrow position (back)
lcd.print(" ");
lcd.setCursor(6,2); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(onhour2 < 23){
onhour2 ++;
}
else{
onhour2 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(onhour2 >0){
onhour2 --;
}
else{
onhour2=23;
}
}
last_down=current_down;
}//subpage2_counter 1
//Second item control(subpage2_counter =2) onmin2
if(subpage2_counter==2){
lcd.setCursor(6,2); //Delete last arrow position (onhour1)
lcd.print(" ");
lcd.setCursor(9,2); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(onmin2 < 59){
onmin2 ++;
}
else{
onmin2 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(onmin2 >0){
onmin2 --;
}
else{
onmin2=59;
}
}
last_down=current_down;
}//subpage2_counter 2
//Thirth item control(subpage2_counter =3) onsec2
if(subpage2_counter==3){
lcd.setCursor(9,2); //Delete last arrow position (onmin1)
lcd.print(" ");
lcd.setCursor(12,2); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(onsec2 < 59){
onsec2 ++;
}
else{
onsec2 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(onsec2 >0){
onsec2 --;
}
else{
onsec2=59;
}
}
last_down=current_down;
}//subpage2_counter 3
//fourth item control(subpage2_counter =4) offhour2
if(subpage2_counter==4){
lcd.setCursor(12,2); //Delete last arrow position (onsec1)
lcd.print(" ");
lcd.setCursor(6,3); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(offhour2 < 23){
offhour2 ++;
}
else{
offhour2 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(offhour2 >0){
offhour2 --;
}
else{
offhour2=23;
}
}
last_down=current_down;
}//subpage2_counter 4
//fifth item control(subpage2_counter =5) offmin2
if(subpage2_counter==5){
lcd.setCursor(6,3); //Delete last arrow position (offhour1)
lcd.print(" ");
lcd.setCursor(9,3); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(offmin2 < 59){
offmin2 ++;
}
else{
offmin2 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(offmin2 >0){
offmin2 --;
}
else{
offmin2=59;
}
}
last_down=current_down;
}//subpage2_counter 5
//sixth item control(subpage2_counter =6) offsec2
if(subpage2_counter==6){
lcd.setCursor(9,3); //Delete last arrow position (offmin1)
lcd.print(" ");
lcd.setCursor(12,3); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
if(offsec2 < 59){
offsec2 ++;
}
else{
offsec2 =0;
}
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
if(offsec2 >0){
offsec2 --;
}
else{
offsec2=59;
}
}
last_down=current_down;
}//subpage2_counter 6
//seventh item control(subpage2_counter =7) back
if(subpage2_counter==7){
lcd.setCursor(12,3); //Delete last arrow position (offsec1)
lcd.print(" ");
lcd.setCursor(0,3); //Place arrow in front of selected item
lcd.write(byte(2));
//Move item + or -
if (last_up== LOW && current_up == HIGH){ //Up
lcd.setCursor(0,3); //Delete last arrow position (back) to exit
lcd.print(" ");
subpage2_counter=0; //Exit submenu. Up/down butons enabled to move main pages
}
last_up=current_up;
if(last_down== LOW && current_down == HIGH){//Down
lcd.setCursor(0,3); //Delete last arrow position (back)
lcd.print(" ");
subpage2_counter=1; //Go to first item (onhour2)
}
last_down=current_down;
}//subpage2_counter 7
//case 3
break;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
case 4: //Page 3 display and functions
lcd.setCursor(0,0);
lcd.print(" PRESSIONE OK ");
lcd.setCursor(0,2);
lcd.print(" PARA SALVAR: ");
if (last_sel== LOW && current_sel == HIGH){ //select button pressed.Save settings to eeprom
EEPROM.write(0, onhour1);
EEPROM.write(1, onmin1);
EEPROM.write(2, onsec1);
EEPROM.write(3, offhour1);
EEPROM.write(4, offmin1);
EEPROM.write(5, offsec1);
EEPROM.write(6, onhour2);
EEPROM.write(7, onmin2);
EEPROM.write(8, onsec2);
EEPROM.write(9, offhour2);
EEPROM.write(10, offmin2);
EEPROM.write(11, offsec2);
lcd.clear(); //Print message "SAVED!"
lcd.setCursor(0,2);
lcd.print(" SALVO! ");
delay(2000);
lcd.clear(); //Clear lcd and go to main page
page_counter=1;
}
last_sel=current_sel; //Save last state of select button
//Case 4
break;
}//switch
//-------------Conversion----------//
//---------Converting clock time into single number
Hour = now.hour();
Min = now.minute();
Sec = now.second();
Time = (Hour*10000+ Min*100 +Sec*1);
//--------Converting firt timer on/off into single number
on_hour1=onhour1;
on_min1=onmin1;
on_sec1=onsec1;
on_Time1=(on_hour1*10000 + on_min1*100 + on_sec1);
off_hour1=offhour1;
off_min1=offmin1;
off_sec1=offsec1;
off_Time1=(off_hour1*10000 + off_min1*100 + off_sec1);
//--------Converting second timer on/off into single number
on_hour2=onhour2;
on_min2=onmin2;
on_sec2=onsec2;
on_Time2=(on_hour2*10000 + on_min2*100 + on_sec2);
off_hour2=offhour2;
off_min2=offmin2;
off_sec2=offsec2;
off_Time2=(off_hour2*10000 + off_min2*100 + off_sec2);
//----RelayState1 Function----//
if(onhour1 == offhour1 && onmin1==offmin1 && onsec1==offsec1){
RelayState1=LOW;
}
if(on_Time1 < off_Time1){
if(Time >= on_Time1 && Time < off_Time1){ //Start
RelayState1= HIGH;
}
else if(Time >= off_Time1) {
RelayState1= LOW;
}
else{
RelayState1= LOW;
}
}
if (on_Time1 > off_Time1){
if(Time >= on_Time1 && Time <= 235959){ //Start
RelayState1= HIGH;
}
else if(Time < off_Time1 ){
RelayState1= HIGH;
}
else if(Time >= off_Time1 && Time < on_Time1){
RelayState1= LOW;
}
}
//----RelayState2 Function----//
if(onhour2 == offhour2 && onmin2==offmin2 && onsec2==offsec2){
RelayState2=LOW;
}
if(on_Time2 < off_Time2){
if(Time >= on_Time2 && Time < off_Time2){ //Start
RelayState2= HIGH;
}
else if(Time >= off_Time2) {
RelayState2= LOW;
}
else{
RelayState2= LOW;
}
}
if (on_Time2 > off_Time2){
if(Time >= on_Time2 && Time <= 235959){ //Start
RelayState2= HIGH;
}
else if(Time < off_Time2 ){
RelayState2= HIGH;
}
else if(Time >= off_Time2 && Time < on_Time2){
RelayState2= LOW;
}
}
//-------Relays function
if(RelayState1 ==HIGH ){
digitalWrite(Relay1,HIGH);
}
else{
digitalWrite(Relay1,LOW);
}
if(RelayState2 ==HIGH ){
digitalWrite(Relay2,HIGH);
}
else{
digitalWrite(Relay2,LOW);
}
}//void loop