#include <stdio.h>
#include <stdlib.h>
#include "RTClib.h"
RTC_DS1307 rtc;
const int latchPin = 11; //Pin connected to ST_CP of 74HC595
const int clockPin = 13; //Pin connected to SH_CP of 74HC595
const int dataPin = 12; //Pin connected to DS of 74HC595
const int btnDay = A3;
const int btnMonth = A2;
const int btnYear = A1;
const int btnSet = A0;
const int num_0 = 0b00111111;
const int num_1 = 0b00000110;
const int num_2 = 0b01011011;
const int num_3 = 0b01001111;
const int num_4 = 0b01100110;
const int num_5 = 0b01101101;
const int num_6 = 0b01111101;
const int num_7 = 0b00000111;
const int num_8 = 0b01111111;
const int num_9 = 0b01101111;
const int off = 0b00000000;
const int digit[11] = {num_0, num_1, num_2, num_3, num_4, num_5, num_6, num_7, num_8, num_9, off};
DateTime goalDate = DateTime(2024, 11, 3, 18, 9, 0);
unsigned long previousMillis = 0;
const long updateInterval = 1000;
const unsigned long waitBtnTime = 10000;
void formatDataWithLeadingZero(int days, int hours, int minutes, int seconds, int digDays[], int digHours[], int digMinutes[], int digSeconds[]) {
for (int i = 3-1; i >= 0; i--) {
digDays[i] = days % 10;
days /= 10;
}
for (int i = 2-1; i >= 0; i--) {
digHours[i] = hours % 10;
hours /= 10;
digMinutes[i] = minutes % 10;
minutes /= 10;
digSeconds[i] = seconds % 10;
seconds /= 10;
}
}
DateTime setGoalDate(int digDays[], int digHours[], int digMinutes[], int digSeconds[]) {
int setDay = 0;
int setMonth = 0;
int setYear = 20;
formatDataWithLeadingZero(0, 0, 0, 0, digDays, digHours, digMinutes, digSeconds);
lightDigits(digDays, digHours, digMinutes, digSeconds);
unsigned long startTime = millis();
while (millis() - startTime <= waitBtnTime) {
// set day
if (digitalRead(btnDay) == LOW) {
delay(50);
if (digitalRead(btnDay) == LOW) {
setDay++;
if (setDay > 31) {
setDay = 0;
}
formatDataWithLeadingZero(0, setDay, 0, 0, digDays, digHours, digMinutes, digSeconds);
lightDigits(digDays, digHours, digMinutes, digSeconds);
startTime = millis();
}
}
// set month
if (digitalRead(btnMonth) == LOW) {
delay(50);
if (digitalRead(btnMonth) == LOW) {
setMonth++;
if (setMonth > 12) {
setMonth = 0;
}
formatDataWithLeadingZero(0, setDay, setMonth, 0, digDays, digHours, digMinutes, digSeconds);
lightDigits(digDays, digHours, digMinutes, digSeconds);
startTime = millis();
}
}
// set year
if (digitalRead(btnYear) == LOW) {
delay(50);
if (digitalRead(btnYear) == LOW) {
setYear++;
formatDataWithLeadingZero(0, setDay, setMonth, setYear, digDays, digHours, digMinutes, digSeconds);
lightDigits(digDays, digHours, digMinutes, digSeconds);
startTime = millis();
}
}
if (digitalRead(btnSet) == LOW) {
delay(50);
if (digitalRead(btnSet) == LOW) {
setDay = 0;
setMonth = 0;
setYear = 0;
formatDataWithLeadingZero(0, setDay, setMonth, setYear, digDays, digHours, digMinutes, digSeconds);
lightDigits(digDays, digHours, digMinutes, digSeconds);
startTime = millis();
}
}
}
if (setDay != 0 && setMonth != 0 && setYear != 20) {
return DateTime(2000+setYear, setMonth, setDay, 13, 0, 0);
}
}
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(btnDay, INPUT_PULLUP);
pinMode(btnMonth, INPUT_PULLUP);
pinMode(btnYear, INPUT_PULLUP);
pinMode(btnSet, INPUT_PULLUP);
rtc.begin();
}
void loop(){
unsigned long currentMillis = millis();
DateTime now = rtc.now();
int digDays[3];
int digHours[2];
int digMinutes[2];
int digSeconds[2];
if(digitalRead(btnSet) == LOW) {
delay(50);
if (digitalRead(btnSet) == LOW) {
goalDate = setGoalDate(digDays, digHours, digMinutes, digSeconds);
}
}
// Check if updateInterval has elapsed since previousMillis
if (currentMillis - previousMillis >= updateInterval) {
previousMillis = currentMillis;
TimeSpan remainingTime = goalDate - now;
int days;
int hours;
int minutes;
int seconds;
if (remainingTime.totalseconds() <= 0) {
// Goal time!
days = 0;
hours = 0;
minutes = 0;
seconds = 0;
} else {
days = remainingTime.days();
hours = remainingTime.hours();
minutes = remainingTime.minutes();
seconds = remainingTime.seconds();
}
formatDataWithLeadingZero(days, hours, minutes, seconds, digDays, digHours, digMinutes, digSeconds);
lightDigits(digDays, digHours, digMinutes, digSeconds);
}
}
void lightDigits(int days[3], int hours[2], int minutes[2], int seconds[2]) {
digitalWrite(latchPin, LOW);
// display days DDD
shiftOut(dataPin, clockPin, MSBFIRST, digit[days[0]]);
shiftOut(dataPin, clockPin, MSBFIRST, digit[days[1]]);
shiftOut(dataPin, clockPin, MSBFIRST, digit[days[2]]);
// display hours HH
shiftOut(dataPin, clockPin, MSBFIRST, digit[hours[0]]);
shiftOut(dataPin, clockPin, MSBFIRST, digit[hours[1]]);
// display minutes MM
shiftOut(dataPin, clockPin, MSBFIRST, digit[minutes[0]]);
shiftOut(dataPin, clockPin, MSBFIRST, digit[minutes[1]]);
// display seconds SS
shiftOut(dataPin, clockPin, MSBFIRST, digit[seconds[0]]);
shiftOut(dataPin, clockPin, MSBFIRST, digit[seconds[1]]);
digitalWrite(latchPin, HIGH);
}