// 수정된 시뮬레이션 https://wokwi.com/projects/421571444490103809
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#define BUZZER_PIN 9 // 피에조 부저 핀
#define BUTTON_PIN 10 // 알람 중지 버튼 핀
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS3231 rtc; // DS3231 RTC 모듈 사용
// 알람 관련 변수
bool alarmActive = false;
int alarmHour = 11;
int alarmMin = 43;
int alarmSec = 10;
const long ALARM_DURATION = 10000;
unsigned long t1;
const char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
int dd;
int old_dd;
void setup()
{
Serial.begin(9600);
Wire.begin();
// RTC 초기화
if (!rtc.begin())
{
Serial.println("RTC를 찾을 수 없습니다");
while (1);
}
// RTC 시간이 유효하지 않은 경우에만 시간 설정
if (rtc.lostPower())
{
// 2025년 1월 30일 8:18:10 설정
rtc.adjust(DateTime(2025, 1, 30, 8, 18, 10));
}
lcd.init();
lcd.backlight();
lcd.clear();
pinMode(BUZZER_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop()
{
DateTime now = rtc.now(); // 현재 시간 읽기
// 첫째줄 년,월,일 표시. 일자가 바뀌면 첫줄 변경
dd=now.day();
if(old_dd!=dd){
old_dd=dd;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(now.year(), DEC);
lcd.print("/");
lcd.print(now.month(), DEC);
lcd.print("/");
lcd.print(dd, DEC);
lcd.setCursor(13, 0);
lcd.print(days[now.dayOfTheWeek()]);
}
//둘째줄 시간표시
lcd.setCursor(0, 1);
if (now.hour() < 10)
lcd.print("0");
lcd.print(now.hour(), DEC);
lcd.print(":");
if (now.minute() < 10)
lcd.print("0");
lcd.print(now.minute(), DEC);
lcd.print(":");
if (now.second() < 10)
lcd.print("0");
lcd.print(now.second(), DEC);
// 알람 켜기 (시간일치시)
if (now.hour() == alarmHour && now.minute() == alarmMin && now.second() == alarmSec && alarmActive == false)
{
t1=millis();
alarmActive = true;
tone(BUZZER_PIN, 1000);
lcd.setCursor(10, 1);
lcd.print("ALARM!");
}
// 알람끄기 (버튼 또는 10초후자동)
if ((digitalRead(10)==0 || millis()-t1>=ALARM_DURATION) && (alarmActive == true) )
{
noTone(BUZZER_PIN);
alarmActive = false;
lcd.setCursor(10, 1);
lcd.print(" ");
delay(500);
}
}