#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
//===== I/O =====
#define pinTrig 2
#define pinReset 3
#define pinEdit 4
int menuCount = 0;
//===== LCD =====
LiquidCrystal_I2C lcd(0x27, 20, 4);
//===== RTC =====
RTC_DS1307 rtc;
//===== SD =====
File savedFile;
//===== DISPLAY =====
char text[20];
unsigned long lt = 0;
unsigned long hourMeter, secondMeter = 4500, per10; //SETING AWAL HITUNGAN PADA JAM, UNTUK RESET = HAPUS DATA PADA SD CARD
void setup() {
//===== INIT I/O =====
pinMode(pinTrig, INPUT_PULLUP);
pinMode(pinReset, INPUT_PULLUP);
pinMode(pinEdit, INPUT_PULLUP);
//===== INIT SERIAL DAN LCD =====
lcd.init(); lcd.backlight();
lcd.setCursor(0, 0); lcd.print("[ HOUR-METER ]");
lcd.setCursor(0, 1); lcd.print("-- by OPELIOT --");
Serial.begin(115200); delay(100);
Serial.println("Inisialisasi...");
// blinkLCD(200, 100, 5);
//===== RTC =====
if (! rtc.begin()) {
Serial.println("RTC ERROR");
lcd.setCursor(0, 1); lcd.print(" RTC ERROR! ");
while (1) {
blinkLCD(250, 250, 2);
delay(1500);
}
}
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
if (! rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
//===== INIT SD =====
if (!SD.begin(10)) {
Serial.println("initialization SD CARD FAILED!");
lcd.setCursor(0, 1); lcd.print(" RTC ERROR! ");
while (1) {
blinkLCD(250, 250, 3);
delay(1500);
}
}
Serial.println("Initialization SD CARD OK");
//===== INIT CONDITION =====
int counter = 0;
if (digitalRead(pinReset) == LOW)lcd.clear();
while (digitalRead(pinReset) == LOW) {
lcd.setCursor(0, 0); lcd.print(" [ Reset? ] ");
lcd.setCursor(counter, 1); lcd.write(0xff);
counter++;
if (counter == 20) {
SD.remove("hm.txt");
savedFile = SD.open("hm.txt", FILE_WRITE);
if (savedFile) {
savedFile.println(0);
savedFile.close();
}
lcd.setCursor(0, 1); lcd.print(" RESET DATA ");
blinkLCD(100, 100, 10);
break;
}
delay(150);
}
savedFile = SD.open("hm.txt");
if (savedFile) {
Serial.println("Read Data");
if (savedFile.available()) {
String readFromSD = savedFile.readString();
Serial.print(readFromSD);
secondMeter = readFromSD.toInt();
}
savedFile.close();
}
else {
savedFile = SD.open("hm.txt", FILE_WRITE);
if (savedFile) {
savedFile.println(secondMeter);
savedFile.close();
}
}
}
void loop() {
DateTime now = rtc.now();
if (now.unixtime() > lt) {
lcd.setCursor(0, 1);
if (digitalRead(pinTrig) == 0) {
secondMeter++;
savedFile = SD.open("hm.txt", O_WRITE);
if (savedFile) {
savedFile.println(String(secondMeter));
savedFile.close();
}
lcd.print("STATUS : RUNNING ");
}
else {
lcd.print("STATUS : OFF ");
}
lcd.setCursor(0, 0); lcd.print("C/N UNIT: GS30107YM ");
hourMeter = secondMeter / 3600;
per10 = int((secondMeter % 3600) / 360);
sprintf(text, "HM : %08lu.%lu", hourMeter, per10);
lcd.setCursor(0, 2); lcd.print(text);
// sprintf(text, "WAKTU : %02d:%02d:%02d ", int(now.hour()), int(now.minute()), int(now.second()));
sprintf(text, "DETIK : %010lu", secondMeter);
lcd.setCursor(0, 3); lcd.print(text);
now = rtc.now();
lt = now.unixtime();
}
if (digitalRead(pinReset) == LOW && digitalRead(pinEdit) == LOW)
{
menuCount++;
if (menuCount > 40) {
settingTime();
}
}
else {
menuCount = 0;
}
delay(50);
}
void settingTime() {
int cursor = 0, dispCounter = 0;
menuCount = 0;
unsigned long secondMeterEdit = secondMeter;
lcd.setCursor(0, 3);
sprintf(text, "ADJUST : %010lu", secondMeterEdit);
lcd.print(text);
while (digitalRead(pinReset) == LOW || digitalRead(pinEdit) == LOW) {
blinkLCD(200, 200, 1);
}
while (1) {
if (dispCounter >= 15) {
lcd.setCursor(19 - cursor, 3); lcd.write(0xff);
dispCounter++;
}
else {
lcd.setCursor(0, 3);
sprintf(text, "ADJUST : %010lu", secondMeterEdit);
lcd.print(text);
}
dispCounter++;
if (dispCounter >= 30)dispCounter = 0;
int saveCount=0;
bool outResult = false;
while (digitalRead(pinReset) == LOW && digitalRead(pinEdit) == LOW){
saveCount++;
if (saveCount > 10) {
outResult = true;
break;
}
blinkLCD(100,100,1);
}
if(outResult==true)break;
if (digitalRead(pinEdit) == LOW) {
// while (digitalRead(pinEdit) == LOW);
cursor++;
if (cursor > 9)cursor = 0;
delay(250);
}
if (digitalRead(pinReset) == LOW) {
// while (digitalRead(pinReset) == LOW);
secondMeterEdit = secondMeterEdit + 1 * pow(10, cursor);
delay(250);
}
delay(10);
}
SD.remove("hm.txt");
savedFile = SD.open("hm.txt", FILE_WRITE);
if (savedFile) {
savedFile.println(secondMeterEdit);
savedFile.close();
}
lcd.setCursor(0, 1); lcd.print(" SAVE DATA ");
blinkLCD(100, 100, 10);
savedFile = SD.open("hm.txt");
if (savedFile) {
Serial.println("Read Data");
if (savedFile.available()) {
String readFromSD = savedFile.readString();
Serial.print(readFromSD);
secondMeter = readFromSD.toInt();
}
savedFile.close();
}
while (digitalRead(pinReset) == LOW || digitalRead(pinEdit) == LOW) {
blinkLCD(200, 200, 1);
}
menuCount = 0;
}
void blinkLCD(int timeOn, int timeOff, int perulangan) {
for (int i = 0; i < perulangan; i++) {
lcd.noBacklight(); delay(timeOn);
lcd.backlight(); delay(timeOff);
}
}