#include <Wire.h>
#include <RTClib.h>
#include <U8g2lib.h>
#include <EEPROM.h>
RTC_DS1307 rtc;
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);
#define BTN_SET 2
#define BTN_UP 3
#define BTN_DOWN 4
#define RELAY_PIN 8
#define BUZZER_PIN 9
// Timer-1
byte T1_ON_H = 6;
byte T1_ON_M = 0;
byte T1_OFF_H = 6;
byte T1_OFF_M = 1;
// Timer-2
byte T2_ON_H = 12;
byte T2_ON_M = 0;
byte T2_OFF_H = 12;
byte T2_OFF_M = 1;
// Timer-3
byte T3_ON_H = 18;
byte T3_ON_M = 0;
byte T3_OFF_H = 18;
byte T3_OFF_M = 1;
byte menuIndex = 0;
// part 2
//======================
// EEPROM ADDRESS
//======================
#define ADDR_T1_ON_H 0
#define ADDR_T1_ON_M 1
#define ADDR_T1_OFF_H 2
#define ADDR_T1_OFF_M 3
#define ADDR_T2_ON_H 4
#define ADDR_T2_ON_M 5
#define ADDR_T2_OFF_H 6
#define ADDR_T2_OFF_M 7
#define ADDR_T3_ON_H 8
#define ADDR_T3_ON_M 9
#define ADDR_T3_OFF_H 10
#define ADDR_T3_OFF_M 11
//======================
// SAVE SETTINGS
//======================
void saveSettings()
{
EEPROM.update(ADDR_T1_ON_H, T1_ON_H);
EEPROM.update(ADDR_T1_ON_M, T1_ON_M);
EEPROM.update(ADDR_T1_OFF_H, T1_OFF_H);
EEPROM.update(ADDR_T1_OFF_M, T1_OFF_M);
EEPROM.update(ADDR_T2_ON_H, T2_ON_H);
EEPROM.update(ADDR_T2_ON_M, T2_ON_M);
EEPROM.update(ADDR_T2_OFF_H, T2_OFF_H);
EEPROM.update(ADDR_T2_OFF_M, T2_OFF_M);
EEPROM.update(ADDR_T3_ON_H, T3_ON_H);
EEPROM.update(ADDR_T3_ON_M, T3_ON_M);
EEPROM.update(ADDR_T3_OFF_H, T3_OFF_H);
EEPROM.update(ADDR_T3_OFF_M, T3_OFF_M);
}
//======================
// LOAD SETTINGS
//======================
void loadSettings()
{
T1_ON_H = EEPROM.read(ADDR_T1_ON_H);
T1_ON_M = EEPROM.read(ADDR_T1_ON_M);
T1_OFF_H = EEPROM.read(ADDR_T1_OFF_H);
T1_OFF_M = EEPROM.read(ADDR_T1_OFF_M);
T2_ON_H = EEPROM.read(ADDR_T2_ON_H);
T2_ON_M = EEPROM.read(ADDR_T2_ON_M);
T2_OFF_H = EEPROM.read(ADDR_T2_OFF_H);
T2_OFF_M = EEPROM.read(ADDR_T2_OFF_M);
T3_ON_H = EEPROM.read(ADDR_T3_ON_H);
T3_ON_M = EEPROM.read(ADDR_T3_ON_M);
T3_OFF_H = EEPROM.read(ADDR_T3_OFF_H);
T3_OFF_M = EEPROM.read(ADDR_T3_OFF_M);
if(T1_ON_H > 23) T1_ON_H = 6;
if(T1_ON_M > 59) T1_ON_M = 0;
if(T1_OFF_H > 23) T1_OFF_H = 6;
if(T1_OFF_M > 59) T1_OFF_M = 1;
if(T2_ON_H > 23) T2_ON_H = 12;
if(T2_ON_M > 59) T2_ON_M = 0;
if(T2_OFF_H > 23) T2_OFF_H = 12;
if(T2_OFF_M > 59) T2_OFF_M = 1;
if(T3_ON_H > 23) T3_ON_H = 18;
if(T3_ON_M > 59) T3_ON_M = 0;
if(T3_OFF_H > 23) T3_OFF_H = 18;
if(T3_OFF_M > 59) T3_OFF_M = 1;
}
// Part-3
//======================
// INCREASE VALUE
//======================
void increaseValue()
{
switch(menuIndex)
{
case 1:
T1_ON_H = (T1_ON_H + 1) % 24;
break;
case 2:
T1_ON_M = (T1_ON_M + 1) % 60;
break;
case 3:
T1_OFF_H = (T1_OFF_H + 1) % 24;
break;
case 4:
T1_OFF_M = (T1_OFF_M + 1) % 60;
break;
case 5:
T2_ON_H = (T2_ON_H + 1) % 24;
break;
case 6:
T2_ON_M = (T2_ON_M + 1) % 60;
break;
case 7:
T2_OFF_H = (T2_OFF_H + 1) % 24;
break;
case 8:
T2_OFF_M = (T2_OFF_M + 1) % 60;
break;
case 9:
T3_ON_H = (T3_ON_H + 1) % 24;
break;
case 10:
T3_ON_M = (T3_ON_M + 1) % 60;
break;
case 11:
T3_OFF_H = (T3_OFF_H + 1) % 24;
break;
case 12:
T3_OFF_M = (T3_OFF_M + 1) % 60;
break;
}
saveSettings();
}
//Part 4
//======================
// DECREASE VALUE
//======================
void decreaseValue()
{
switch(menuIndex)
{
case 1:
T1_ON_H = (T1_ON_H + 23) % 24;
break;
case 2:
T1_ON_M = (T1_ON_M + 59) % 60;
break;
case 3:
T1_OFF_H = (T1_OFF_H + 23) % 24;
break;
case 4:
T1_OFF_M = (T1_OFF_M + 59) % 60;
break;
case 5:
T2_ON_H = (T2_ON_H + 23) % 24;
break;
case 6:
T2_ON_M = (T2_ON_M + 59) % 60;
break;
case 7:
T2_OFF_H = (T2_OFF_H + 23) % 24;
break;
case 8:
T2_OFF_M = (T2_OFF_M + 59) % 60;
break;
case 9:
T3_ON_H = (T3_ON_H + 23) % 24;
break;
case 10:
T3_ON_M = (T3_ON_M + 59) % 60;
break;
case 11:
T3_OFF_H = (T3_OFF_H + 23) % 24;
break;
case 12:
T3_OFF_M = (T3_OFF_M + 59) % 60;
break;
}
saveSettings();
}
//Part 5
//======================
// BUTTON CONTROL
//======================
void checkButtons()
{
// SET BUTTON
if(digitalRead(BTN_SET) == LOW)
{
buzzerBeep(50);
menuIndex++;
if(menuIndex > 12)
{
menuIndex = 0;
}
delay(300);
}
// UP BUTTON
if(digitalRead(BTN_UP) == LOW)
{
buzzerBeep(50);
increaseValue();
delay(200);
}
// DOWN BUTTON
if(digitalRead(BTN_DOWN) == LOW)
{
buzzerBeep(50);
decreaseValue();
delay(200);
}
}
//Part 6
//======================
// RELAY CONTROL
//======================
void checkRelay(DateTime now)
{
int currentTime =
(now.hour() * 60) +
now.minute();
bool relayState = false;
// Timer-1
int t1On =
(T1_ON_H * 60) +
T1_ON_M;
int t1Off =
(T1_OFF_H * 60) +
T1_OFF_M;
// Timer-2
int t2On =
(T2_ON_H * 60) +
T2_ON_M;
int t2Off =
(T2_OFF_H * 60) +
T2_OFF_M;
// Timer-3
int t3On =
(T3_ON_H * 60) +
T3_ON_M;
int t3Off =
(T3_OFF_H * 60) +
T3_OFF_M;
// Timer-1 Check
if(currentTime >= t1On &&
currentTime < t1Off)
{
relayState = true;
}
// Timer-2 Check
if(currentTime >= t2On &&
currentTime < t2Off)
{
relayState = true;
}
// Timer-3 Check
if(currentTime >= t3On &&
currentTime < t3Off)
{
relayState = true;
}
//======== buzzar on times =======
static int lastMinute = -1;
if(currentTime != lastMinute)
{
if(currentTime == t1On)
{
buzzerBeep(2000);
delay(1000);
buzzerBeep(2000);
}
if(currentTime == t2On)
{
buzzerBeep(2000);
delay(1000);
buzzerBeep(2000);
}
if(currentTime == t3On)
{
buzzerBeep(2000);
delay(1000);
buzzerBeep(2000);
}
lastMinute = currentTime;
}
//------ buzzr off times -------
static int lastOffMinute = -1;
if(currentTime != lastOffMinute)
{
if(currentTime == t1Off)
{
buzzerBeep(2000);
}
if(currentTime == t2Off)
{
buzzerBeep(2000);
}
if(currentTime == t3Off)
{
buzzerBeep(2000);
}
lastOffMinute = currentTime;
}
//===========================
// ACTIVE HIGH RELAY
if(relayState)
{
digitalWrite(RELAY_PIN, HIGH);
}
else
{
digitalWrite(RELAY_PIN, LOW);
}
}
//Part 7
//======================
// OLED DISPLAY
//======================
void drawScreen(DateTime now)
{
char buf[25];
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x12_tf);
//---------- Run Icon -------------
int currentTime = now.hour() * 60 + now.minute();
int t1On = T1_ON_H * 60 + T1_ON_M;
int t1Off = T1_OFF_H * 60 + T1_OFF_M;
int t2On = T2_ON_H * 60 + T2_ON_M;
int t2Off = T2_OFF_H * 60 + T2_OFF_M;
int t3On = T3_ON_H * 60 + T3_ON_M;
int t3Off = T3_OFF_H * 60 + T3_OFF_M;
//--------------Run End -----------
sprintf(buf,
"%02d:%02d:%02d",
now.hour(),
now.minute(),
now.second());
u8g2.drawStr(5,12,buf); //35,22
// Date Display
sprintf(buf,"%02d/%02d/%02d",
now.day(),
now.month(),
now.year() % 100);
u8g2.drawStr(72,12,buf);
/*
// Relay Status
if(digitalRead(RELAY_PIN))
{
u8g2.drawStr(95,12,"ON");
}
else
{
u8g2.drawStr(95,12,"OFF");
} */
//======= oled currsor time =======
//=========== Timer 1 ==========
u8g2.drawStr(0,28,"T1");
//-------- icon -------
if(currentTime >= t1On && currentTime < t1Off)
{
u8g2.drawDisc(110,24,3);
}
//------ icon end -------
sprintf(buf,"%02d",T1_ON_H);
if(menuIndex==1)
{
u8g2.drawBox(18,18,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(20,28,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(20,28,buf);
}
u8g2.drawStr(34,28,":");
sprintf(buf,"%02d",T1_ON_M);
if(menuIndex==2)
{
u8g2.drawBox(38,18,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(40,28,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(40,28,buf);
}
u8g2.drawStr(56,28,"-");
sprintf(buf,"%02d",T1_OFF_H);
if(menuIndex==3)
{
u8g2.drawBox(62,18,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(64,28,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(64,28,buf);
}
u8g2.drawStr(78,28,":");
sprintf(buf,"%02d",T1_OFF_M);
if(menuIndex==4)
{
u8g2.drawBox(82,18,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(84,28,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(84,28,buf);
}
//================ T2 =================
u8g2.drawStr(0,42,"T2");
//-------- icon ----------
if(currentTime >= t2On && currentTime < t2Off)
{
u8g2.drawDisc(110,38,3);
}
//-------- icon end -------
sprintf(buf,"%02d",T2_ON_H);
if(menuIndex==5)
{
u8g2.drawBox(18,32,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(20,42,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(20,42,buf);
}
u8g2.drawStr(34,42,":");
sprintf(buf,"%02d",T2_ON_M);
if(menuIndex==6)
{
u8g2.drawBox(38,32,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(40,42,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(40,42,buf);
}
u8g2.drawStr(56,42,"-");
sprintf(buf,"%02d",T2_OFF_H);
if(menuIndex==7)
{
u8g2.drawBox(62,32,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(64,42,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(64,42,buf);
}
u8g2.drawStr(78,42,":");
sprintf(buf,"%02d",T2_OFF_M);
if(menuIndex==8)
{
u8g2.drawBox(82,32,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(84,42,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(84,42,buf);
}
//================ T3 =================
u8g2.drawStr(0,56,"T3");
//-------- icon ----------
if(currentTime >= t3On && currentTime < t3Off)
{
u8g2.drawDisc(110,52,3);
}
//-------- icon end --------
sprintf(buf,"%02d",T3_ON_H);
if(menuIndex==9)
{
u8g2.drawBox(18,46,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(20,56,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(20,56,buf);
}
u8g2.drawStr(34,56,":");
sprintf(buf,"%02d",T3_ON_M);
if(menuIndex==10)
{
u8g2.drawBox(38,46,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(40,56,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(40,56,buf);
}
u8g2.drawStr(56,56,"-");
sprintf(buf,"%02d",T3_OFF_H);
if(menuIndex==11)
{
u8g2.drawBox(62,46,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(64,56,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(64,56,buf);
}
u8g2.drawStr(78,56,":");
sprintf(buf,"%02d",T3_OFF_M);
if(menuIndex==12)
{
u8g2.drawBox(82,46,16,12);
u8g2.setDrawColor(0);
u8g2.drawStr(84,56,buf);
u8g2.setDrawColor(1);
}
else
{
u8g2.drawStr(84,56,buf);
}
//==================================
u8g2.sendBuffer();
}
//======= buzzar Fanson ========
void buzzerBeep(int ms)
{
digitalWrite(BUZZER_PIN, HIGH);
delay(ms);
digitalWrite(BUZZER_PIN, LOW);
delay(20); // छोटा gap
}
//Part 8
//======================
// SETUP
//======================
void setup()
{
pinMode(BTN_SET, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Active HIGH Relay OFF
digitalWrite(RELAY_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
Wire.begin();
// rtc.begin();
u8g2.begin();
loadSettings();
// RTC not found
if (!rtc.begin())
{
while (1);
}
// DS1307 first time setup
if (!rtc.isrunning())
{
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
//======================
// LOOP
//======================
void loop()
{
DateTime now = rtc.now();
checkButtons();
checkRelay(now);
drawScreen(now);
delay(100);
}