#include<LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <TimerOne.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x27,20,4);
RTC_DS1307 rtc;
const uint8_t ROWS = 4;
const uint8_t COLS = 3;
char key[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
uint8_t colPins[COLS] = {5,4,3};
uint8_t rowPins[ROWS] = {9,8,7,6};
Keypad keypad1(makeKeymap(key),rowPins,colPins,ROWS,COLS);
void setup() {
Serial.begin(9600);
rtc.begin();
lcd.init();
// 最初閃爍三次
for (int i=0 ; i<2 ; i++)
{
lcd.backlight();
delay(500);
lcd.noBacklight();
delay(500);
}
lcd.backlight();
delay(500);
lcd.print("myClock: S1152009");
Timer1.initialize(10000);
Timer1.attachInterrupt(setTime);
}
bool _update = false;
int millisec = 99;
int _hour = 23;
int _min = 59;
int _sec = 59;
// Emerge > 0 時顯示冒號,反之使冒號消失
void colonEmerge(int Emerge)
{
if (Emerge)
{
lcd.setCursor(2,3);
lcd.print(":");
lcd.setCursor(5,3);
lcd.print(":");
}
else
{
lcd.setCursor(2,3);
lcd.print(" ");
lcd.setCursor(5,3);
lcd.print(" ");
}
}
int mode = 1; // 1為正常倒數 2為分號消失 3為分號顯現
int cnt=0; // 數setTimeOrFlash 被呼叫幾次
void setTime()
{
if (mode == 1)
{
if (millisec > 0) millisec--;
else
{
millisec = 99;
if (_sec > 0) _sec--;
else
{
_sec = 59;
if (_min > 0) _min--;
else
{
_min=59;
if (_hour > 0) _hour--;
else
{
millisec = 0;
_hour = 0;
_min = 0;
_sec = 0;
}
}
}
}
_update = true;
}
else if (mode == 2 || mode == 3)
cnt++;
}
int numOfInput = 0;
void loop() {
DateTime now = rtc.now();
char key = keypad1.getKey();
if (key != NO_KEY)
{
if (key == '#')
mode = 2;
else if (key == '*')
{
mode = 1;
lcd.setCursor(2,3);
lcd.print(":");
lcd.setCursor(5,3);
lcd.print(":");
}
else
{
if (numOfInput == 0) // 先將小時、分、秒歸零
{
_hour = 0;
_min = 0;
_sec = 0;
}
if (numOfInput < 2)
{
lcd.setCursor(numOfInput,3);
lcd.print(key);
_hour += ((int)key - 48)*(numOfInput%2 == 0 ? 10 : 1);
}
else if (numOfInput < 4)
{
lcd.setCursor(numOfInput+1,3);
lcd.print(key);
_min += ((int)key - 48)*(numOfInput%2 == 0 ? 10 : 1);
}
else if (numOfInput < 6)
{
lcd.setCursor(numOfInput+2,3);
lcd.print(key);
_sec += ((int)key - 48)*(numOfInput%2 == 0 ? 10 : 1);
}
numOfInput++;
numOfInput = (numOfInput == 6) ? 0 : numOfInput;
}
}
// 分號閃爍
if (cnt >= 50)
{
if (mode == 2)
{
colonEmerge(0);
mode = 3;
}
else if (mode == 3)
{
colonEmerge(1);
mode = 2;
}
cnt = 0; // 重新計時
}
lcd.setCursor(0,1);
lcd.print(now.year());
lcd.print('/');
lcd.print((now.month() >= 10) ? "" : "0");
lcd.print(now.month());
lcd.print('/');
lcd.print((now.day() >= 10) ? "" : "0");
lcd.print(now.day());
lcd.setCursor(0,2);
lcd.print((now.hour() >= 10) ? "" : "0");
lcd.print(now.hour());
lcd.print(':');
lcd.print((now.minute() >= 10) ? "" : "0");
lcd.print(now.minute());
lcd.print(':');
lcd.print((now.second() >= 10) ? "" : "0");
lcd.print(now.second());
if (_update)
{
lcd.setCursor(0,3);
lcd.print((_hour >= 10) ? "" : "0");
lcd.print(_hour);
lcd.print(':');
lcd.print((_min >= 10) ? "" : "0");
lcd.print(_min);
lcd.print(':');
lcd.print((_sec >= 10) ? "" : "0");
lcd.print(_sec);
lcd.print('.');
lcd.print((millisec >= 10) ? "" : "0");
// lcd.setCursor(11,3);
// lcd.print(" ");
lcd.setCursor(9,3);
lcd.print(millisec);
_update = false;
}
}