#include "RTClib.h"
#include <LiquidCrystal.h>
#include <Servo.h>
#include <BfButton.h>
#include <Encoder.h>
RTC_DS1307 rtc;
Servo servo;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
DateTime now;
DateTime shutTime;
DateTime openTime;
unsigned long currentMillis;
unsigned previousMillis =0;
const int blinkDelayTime = 500;
bool blinked = false;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
byte shutTime_Hours;
byte shutTime_Minutes;
byte openTime_Hours;
byte openTime_Minutes;
byte timeNow_Hours;
byte timeNow_Minutes;
bool timeSet = false;
long oldTime = 0;
long newTime = 0;
bool minSelected = true;
int btnPin=4; //GPIO #3-Push button on encoder
int DT=2; //GPIO #4-DT on encoder (Output B)
int CLK=3; //GPIO #5-CLK on encoder (Output A)
Encoder navigator(CLK, DT);
BfButton btn(BfButton::STANDALONE_DIGITAL, btnPin, true, LOW);
BfButton btn2(BfButton::STANDALONE_DIGITAL, 2, true, LOW);
int currentStateCLK;
int lastStateCLK;
const int servoPin = 6;
bool lockActivated;
enum displayState
{
CLOCK,
CHANGE_TIME,
CHANGE_SHUT,
CHANGE_OPEN,
};
displayState states = CLOCK;
void ChangeOpenTime()
{
//When minutes are selected
if(minSelected)
{
newTime = navigator.read();
if(newTime < oldTime)
{
oldTime = newTime;
openTime_Minutes -= 1;
}
if(newTime > oldTime)
{
oldTime = newTime;
openTime_Minutes += 1;
}
if(openTime_Minutes >= 60)
{
Serial.println("reset to 0");
openTime_Minutes = 0;
oldTime = newTime;
}
else if(openTime_Minutes < 0)
{
Serial.println("reset to 60");
openTime_Minutes = 59;
oldTime = newTime;
}
}
else if(!minSelected)
{
//Serial.println(timeNow_Minutes);
newTime = navigator.read();
//Serial.println(timeNow_Minutes);
if(newTime < oldTime)
{
oldTime = newTime;
openTime_Hours -=1;
}
if(newTime > oldTime)
{
oldTime = newTime;
openTime_Hours +=1;
}
if(openTime_Hours >= 24)
{
Serial.println("reset to 0");
openTime_Hours = 0;
oldTime = newTime;
}
else if(openTime_Hours < 0)
{
Serial.println("reset to 23");
openTime_Hours = 23;
oldTime = newTime;
}
}
lcd.setCursor(0,0);
lcd.print("open time");
lcd.setCursor(0,1);
if (currentMillis - previousMillis >= blinkDelayTime){
// save the last time you blinked the LED
previousMillis = currentMillis;
blinked = !blinked;
Serial.println(blinked);
}
if(!blinked || minSelected){
if(openTime_Hours < 10)
{
lcd.print("0");
lcd.setCursor(1,1);
}
lcd.print(openTime_Hours);
}
else if(blinked)
{
lcd.print(" ");
}
lcd.print(":");
lcd.setCursor(3,1);
if(!blinked || !minSelected){
if(openTime_Minutes < 10)
{
lcd.print("0");
}
lcd.print(openTime_Minutes);
}
else if(blinked)
{
lcd.print(" ");
}
lcd.setCursor(0,1);
}
/*******************/
/*CHANGE close TIME*/
/*******************/
void ChangeCloseTime()
{
if(minSelected)
{
newTime = navigator.read();
//Serial.println(timeNow_Minutes);
if(newTime < oldTime)
{
oldTime = newTime;
shutTime_Minutes -= 1;
}
if(newTime > oldTime)
{
oldTime = newTime;
shutTime_Minutes += 1;
}
if(shutTime_Minutes >= 60)
{
Serial.println("reset to 0");
shutTime_Minutes = 0;
oldTime = newTime;
}
else if(shutTime_Minutes < 0)
{
Serial.println("reset to 60");
shutTime_Minutes = 59;
oldTime = newTime;
}
}
else if(!minSelected)
{
//Serial.println(timeNow_Minutes);
newTime = navigator.read();
//Serial.println(timeNow_Minutes);
if(newTime < oldTime)
{
oldTime = newTime;
shutTime_Hours -=1;
}
if(newTime > oldTime)
{
oldTime = newTime;
shutTime_Hours +=1;
}
if(shutTime_Hours >= 24)
{
Serial.println("reset to 0");
shutTime_Hours = 0;
oldTime = newTime;
}
else if(shutTime_Hours < 0)
{
Serial.println("reset to 23");
shutTime_Hours = 23;
oldTime = newTime;
}
}
lcd.setCursor(0,0);
lcd.print("close time");
lcd.setCursor(0,1);
if (currentMillis - previousMillis >= blinkDelayTime){
// save the last time you blinked the LED
previousMillis = currentMillis;
blinked = !blinked;
Serial.println(blinked);
}
if(!blinked || minSelected){
if(shutTime_Hours < 10)
{
//lcd.setCursor(0,1);
lcd.print("0");
lcd.setCursor(1,1);
}
lcd.print(shutTime_Hours);
}
else if(blinked)
{
lcd.print(" ");
}
lcd.print(":");
lcd.setCursor(3,1);
if(!blinked || !minSelected){
if(shutTime_Minutes < 10)
{
lcd.print("0");
}
lcd.print(shutTime_Minutes);
}
else if(blinked)
{
lcd.print(" ");
}
lcd.setCursor(0,1);
}
/*************/
/*CHANGE TIME*/
/*************/
void ChangeTime()
{
if(minSelected)
{
newTime = navigator.read();
//Serial.println(timeNow_Minutes);
if(newTime < oldTime)
{
oldTime = newTime;
timeNow_Minutes -=1;
}
if(newTime > oldTime)
{
oldTime = newTime;
timeNow_Minutes +=1;
}
if(timeNow_Minutes >= 60)
{
Serial.println("reset to 0");
timeNow_Minutes = 0;
oldTime = newTime;
}
else if(timeNow_Minutes < 0)
{
Serial.println("reset to 60");
timeNow_Minutes = 59;
oldTime = newTime;
}
}
else if(!minSelected)
{
newTime = navigator.read();
if(newTime < oldTime)
{
oldTime = newTime;
timeNow_Hours -=1;
}
if(newTime > oldTime)
{
oldTime = newTime;
timeNow_Hours +=1;
}
if(timeNow_Hours >= 24)
{
Serial.println("reset to 0");
timeNow_Hours = 0;
}
else if(timeNow_Hours < 0)
{
Serial.println("reset to 23");
timeNow_Hours = 23;
}
}
lcd.setCursor(0,0);
lcd.print("Change time");
lcd.setCursor(0,1);
if (currentMillis - previousMillis >= blinkDelayTime){
// save the last time you blinked the LED
previousMillis = currentMillis;
blinked = !blinked;
Serial.println(blinked);
}
if(!blinked || minSelected){
if(timeNow_Hours < 10)
{
lcd.setCursor(0,1);
lcd.print("0");
lcd.setCursor(1,1);
}
lcd.print(timeNow_Hours);
}
else if(blinked)
{
lcd.print(" ");
}
lcd.print(":");
lcd.setCursor(3,1);
if(!blinked || !minSelected){
if(timeNow_Minutes < 10)
{
lcd.print("0");
}
lcd.print(timeNow_Minutes);
}
else if(blinked)
{
lcd.print(" ");
}
}
void setup () {
Serial.begin(115200);
btn.onPress(pressHandler)
.onDoublePress(pressHandler) // default timeout
.onPressFor(pressHandler, 500); // custom timeout for 1 second
lcd.begin(16,2);
lcd.print("ChknDoor(Cheap)");
lcd.setCursor(0,1);
lcd.print("By");
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("robotics");
lcd.setCursor(0,1);
lcd.print("W/Mr 2023");
delay(2000);
lcd.clear();
if (! rtc.begin()) {
lcd.println("something wrong!");
lcd.setCursor(0,1);
lcd.print("check RTC");
Serial.flush();
abort();
}
pinMode(LED_BUILTIN, OUTPUT);
servo.attach(servoPin);
}
void pressHandler (BfButton *btn2, BfButton::press_pattern_t pattern) {
switch (pattern) {
case BfButton::SINGLE_PRESS:
Serial.println("Single push");
minSelected = !minSelected;
break;
case BfButton::DOUBLE_PRESS:
Serial.println("Double push");
rtc.adjust(DateTime(now.year(), now.month(), now.day(), timeNow_Hours, timeNow_Minutes, 0));
states = CLOCK;
lcd.clear();
break;
case BfButton::LONG_PRESS:
Serial.println("Long push");
lcd.clear();
switch(states)
{
case CLOCK:
lcd.clear();
states = CHANGE_TIME;
Serial.println("change time");
break;
case CHANGE_TIME:
lcd.clear();
states = CHANGE_SHUT;
rtc.adjust(DateTime(now.year(), now.month(), now.day(), timeNow_Hours, timeNow_Minutes, 0));
Serial.println("change shut");
break;
case CHANGE_SHUT:
lcd.clear();
states = CHANGE_OPEN;
Serial.println("change open");
break;
case CHANGE_OPEN:
lcd.clear();
states = CLOCK;
Serial.println("clock");
break;
}
}
}
void updateClock()
{
lcd.setCursor(0,0);
now = rtc.now();
timeNow_Minutes = now.minute();
timeNow_Hours = now.hour();
shutTime = DateTime(now.year(), now.month(), now.day(), shutTime_Hours, shutTime_Minutes, 0);
openTime = DateTime(now.year(), now.month(), now.day(), openTime_Hours, openTime_Minutes, 0);
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.setCursor(0,1);
lcd.print(shutTime.hour() % now.hour(), DEC);
lcd.print(':');
lcd.print(shutTime.minute() % now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.print(" ");
lcd.print(openTime.hour() % now.hour(), DEC);
lcd.print(':');
lcd.print(openTime.minute() % now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
Serial.println(lockActivated);
if(shutTime.hour() == now.hour() &&
shutTime.minute() == now.minute() && lockActivated == false)
{
lockActivated = true;
digitalWrite(LED_BUILTIN, HIGH);
}
if(openTime.hour() == now.hour() &&
openTime.minute() == now.minute() && lockActivated == true)
{
lockActivated = false;
digitalWrite(LED_BUILTIN, LOW);
}
if (lockActivated)
servo.write(180);
else
servo.write(0);
}
void loop () {
currentMillis = millis();
btn.read();
switch(states)
{
case CLOCK:
updateClock();
break;
case CHANGE_TIME:
ChangeTime();
break;
case CHANGE_OPEN:
ChangeOpenTime();
break;
case CHANGE_SHUT:
ChangeCloseTime();
break;
}
}