/* Hello Wokwi! */
#include <LiquidCrystal_I2C.h>
#define alarm A0 //闹钟
#define add A1 //加
#define minus A2 //减
#define choose A3//选择端口
const int buzzerPin=10;//蜂鸣器
LiquidCrystal_I2C lcd(0x27, 20, 4);
unsigned long seconds;
int isecond = 0, iminute = 0, ihour = 0, iday = 0, imonth = 0, iyear = 0; //初始时间
int psecond = 0, pminute = 0, phour = 0, pday = 0, pmonth = 0, pyear = 0; //当前时间
int s = 0, m = 0, h = 0, d = 0, mon = 0, y = 0; //时间进位
int count=0,ButtonDelay=10,alarm_count = 0 ,frequence = 2093;
int alarm_hour = 10, alarm_minute = 1, alarm_second = 0; //闹钟时间
void setup()
{
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(6, 1); lcd.print(":");
lcd.setCursor(9, 1); lcd.print(":");
lcd.setCursor(7, 0); lcd.print('/');
lcd.setCursor(10, 0); lcd.print('/');
digitalWrite(add,HIGH);
digitalWrite(minus,HIGH);
digitalWrite(choose, HIGH);
digitalWrite(alarm, HIGH);
pinMode(buzzerPin, OUTPUT);
setTime(2022,8,28,10,00,00); //设置初始时间
}
void setTime(int y, int mon, int d, int h, int m, int s)
{
iyear = y;
imonth = mon;
iday = d;
ihour = h;
iminute = m;
isecond = s;
}
void Format(int col, int row,int num)
{
lcd.setCursor(col, row);
if(num <=9) lcd.print("0");
lcd.print(num);
}
void Time()
{
psecond = ( isecond + seconds ) % 60;
m = ( isecond + seconds ) / 60;
Format(10,1,psecond);
pminute = ( iminute + m ) % 60;
h = ( iminute + m ) / 60;
Format(7,1,pminute);
phour = (ihour + h ) % 24;
d = ( ihour + h ) / 24;
Format(4,1,phour);
}
int YearMonth_Days(int year, int month)
{
int days = 0;
if (month != 2)
{
switch (month)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; break;
case 4: case 6: case 9: case 11: days = 30; break;
}
}
else
{
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) days = 29;
else days = 28;
}
return days;
}
void Day()
{
int days = YearMonth_Days(pyear,pmonth);
int days_up;
if( pmonth == 1 )
days_up = YearMonth_Days( pyear - 1, 12 );
else
days_up = YearMonth_Days( pyear, pmonth - 1 );
pday = ( iday + d ) % days;
if( pday == 0 )
pday = days;
if( ( iday + d ) == days + 1 )
{
iday -= days;
mon++;
}
if(( iday + d ) == 0)
{
iday += days_up;
mon--;
}
Format(11,0,pday);
}
void Month()
{
pmonth = ( imonth + mon ) % 12;
if( pmonth == 0 ) pmonth = 12;
y = ( imonth + mon - 1) / 12;
Format(8,0,pmonth);
}
void Year()
{
pyear = ( iyear + y ) % 9999;
if( pyear == 0 ) pyear = 9999;
lcd.setCursor(3, 0);
lcd.print(pyear);
}
void show()
{
Time();
Day();
Month();
Year();
lcd.setCursor(6, 1); lcd.print(":");
lcd.setCursor(9, 1); lcd.print(":");
lcd.setCursor(7, 0); lcd.print('-');
lcd.setCursor(10, 0); lcd.print('-');
}
void Cursor(int col,int row)
{
lcd.setCursor(col,row);
lcd.cursor();
delay(100);
lcd.noCursor();
delay(100);
}
void set_time(int col, int row, int &Time){
Cursor(col, row);
if(digitalRead(add) == LOW){
delay(ButtonDelay);
if(digitalRead(add) == LOW){
Time ++;
}
show();
}
if(digitalRead(minus) == LOW){
delay(ButtonDelay);
if(digitalRead(minus) == LOW){
Time --;
}
show();
}
}
void set_clock(){
if(digitalRead(choose)==LOW){
lcd.setCursor(13, 1); lcd.print("set");
while(1){
if(digitalRead(choose)==LOW){
delay(ButtonDelay);
if(digitalRead(choose)==LOW){
count++;
}
}
seconds = millis()/1000;
show();
if(count == 1){
set_time(5, 1, ihour); //SetHour
}else if(count == 2){
set_time(8, 1, iminute); //SetMinute
}else if(count == 3){
set_time(11, 1, isecond); //SetSecond
}else if(count == 4){
set_time(12, 0, iday); //SetDay
}else if(count == 5){
set_time(9, 0, imonth); // SetMonth
}else if(count == 6){
set_time(6, 0, iyear); //SetYear
}else if(count >= 7){
count = 0;
lcd.clear();
break;
}
}
}
}
void set_alarm_hour(){
Cursor(5, 1);
if(digitalRead(add) == LOW){
delay(ButtonDelay);
if(digitalRead(add) == LOW){
alarm_hour ++;
if(alarm_hour == 24){
alarm_hour = 0;
}
Format(4,1,alarm_hour);
}
}
if(digitalRead(minus) == LOW){
delay(ButtonDelay);
if(digitalRead(minus) == LOW){
alarm_hour --;
if(alarm_hour == -1){
alarm_hour = 23;
}
Format(4,1,alarm_hour);
}
}
}
void set_alarm_minute(){
Cursor(8, 1);
if(digitalRead(add) == LOW) {
delay(ButtonDelay);
if(digitalRead(add) == LOW){
alarm_minute ++;
if(alarm_minute == 60){
alarm_minute = 0;
}
Format(7,1,alarm_minute);
}
}
if(digitalRead(minus) == LOW){
delay(ButtonDelay);
if(digitalRead(minus) == LOW){
alarm_minute --;
if(alarm_minute == -1){
alarm_minute = 59;
}
Format(7,1,alarm_minute);
}
}
}
void set_alarm(){
if(digitalRead(alarm) == LOW){
//lcd.clear();
alarm_hour = phour;
alarm_minute = pminute;
lcd.setCursor(0, 0);
lcd.print(" set alarm ");
lcd.setCursor(10, 1);
lcd.print("00"); //闹钟秒数
while(1){
if(digitalRead(choose) == LOW){
delay(ButtonDelay);
if(digitalRead(choose) == LOW){
alarm_count++;
}
}
if(alarm_count == 1){
set_alarm_hour();
}else if(alarm_count == 2){
set_alarm_minute();
}else if(alarm_count >= 3){
alarm_count = 0;
break;
}
}
}
}
void Clock_Alarm(){
if(phour == alarm_hour && pminute == alarm_minute && psecond == alarm_second){
tone(buzzerPin,frequence);
delay(5000);
noTone(buzzerPin);
}
}
void loop()
{
seconds = millis()/1000;
show();
set_clock();
set_alarm();
Clock_Alarm();
Clock_Alarm();
}