#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#define BUTTON1 7
#define BUTTON2 6
#define BUTTON3 5
#define BUTTON4 4
#define BUZZER 3
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS3231 rtc;
DateTime now;
int HMS[3] = {3600, 60, 1};
int flag[4] = {0}, change = 0, OnOff = 0, hms = 0, h, m, s;
int BUTTON[4] = {BUTTON1, BUTTON2, BUTTON3, BUTTON4};
long time = 0;
unsigned long previousMillis = 0; // 最後のタイマー更新時間
const long interval = 1000; // 1秒間隔
// タイマー関数
void Timer() {
if (OnOff == 1) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (time > 0) {
time--;
} else {
tone(BUZZER, 1760, 500);
OnOff = 0;
}
}
}
}
// スイッチ処理関数
void Button() {
for (int i = 0; i < 4; i++) {
if (digitalRead(BUTTON[i]) == LOW && flag[i] == 0) {
switch (i) {
case 0:
change = (change + 1) % 2;
break;
case 1:
time += HMS[hms];
break;
case 2:
hms = (hms + 1) % 3;
break;
case 3:
OnOff = !OnOff;
if (!OnOff) time = 0; // タイマーOFFでリセット
break;
}
flag[i] = 1; // 押下済フラグ
}
if (digitalRead(BUTTON[i]) == HIGH && flag[i] == 1) {
flag[i] = 0; // ボタンリリース
}
}
}
// 時刻表示
void displayTime() {
char buffer[16];
sprintf(buffer, "Time:%02d:%02d:%02d", now.hour(), now.minute(), now.second());
lcd.setCursor(0, 0);
lcd.print(buffer);
lcd.print(" ");
}
// 日付表示
void displayDate() {
char buffer[16];
sprintf(buffer, "Date:%d/%02d/%02d", now.year(), now.month(), now.day());
lcd.setCursor(0, 1);
lcd.print(buffer);
}
// タイマー表示
void displayTimer() {
char buffer[16];
h = (time / 3600) % 24;
m = (time / 60) % 60;
s = time % 60;
sprintf(buffer, "Timer:%02d:%02d:%02d", h, m, s);
lcd.setCursor(0, 0);
lcd.print(buffer);
lcd.setCursor(0, 1);
lcd.print(" "); // 行のクリア
}
void setup() {
lcd.init();
lcd.backlight();
rtc.begin();
pinMode(BUTTON1, INPUT_PULLUP);
pinMode(BUTTON2, INPUT_PULLUP);
pinMode(BUTTON3, INPUT_PULLUP);
pinMode(BUTTON4, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
// メインループ
void loop() {
Button();
now = rtc.now();
Timer(); // タイマー関数を呼び出し
if (change == 0) {
displayTime();
displayDate();
} else {
displayTimer();
}
}