#include <SevSeg.h>
#include <RTClib.h>
#include <Wire.h>
RTC_DS1307 rtc; // Create an instance of the RTC_DS1307 class
//Pin definitions
const int digitPins[] = {2, 3, 4, 5};
const int segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
int hours = 9;
int minutes = 53;
int seconds = 0;
unsigned long timer = 0;
bool stop_flag = false;
int increase_count = 14;
int last_increase_count_state = LOW;
int cur_increase_count_state = LOW;
int decrease_count = 15;
int last_decrease_count_state = LOW;
int cur_decrease_count_state = LOW;
int toggle_minute_hour = 16;
int last_toggled_minute_hour_state = LOW;
int cur_toggled_minute_hour_state = LOW;
int toggle_timer_clock = 17;
int last_toggled_timer_clock_state = LOW;
int cur_toggled_timer_clock_state = LOW;
bool toggle_minute_hour_flag = false;
bool toggle_timer_clock_flag = false;
bool is_button_pressed = false;
const long interval = 500; // Blinking interval in milliseconds
bool blink_state = false;
unsigned long previous_millis = 0;
const byte digitPatterns[] = {
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01101111// 9
};
void setup () {
pinMode(increase_count, INPUT);
digitalWrite(increase_count, HIGH);
pinMode(decrease_count, INPUT);
digitalWrite(decrease_count, HIGH);
pinMode(toggle_minute_hour, INPUT);
digitalWrite(toggle_minute_hour, HIGH);
pinMode(toggle_timer_clock, INPUT);
digitalWrite(toggle_timer_clock, HIGH);
for (int i = 0; i < 4; i++) {
pinMode(digitPins[i], OUTPUT);
digitalWrite(digitPins[i], HIGH); //turn off all digits intially
}
// set the segment pins as outputs
for (int i = 0; i < 8; i++) {
pinMode(segmentPins[i], OUTPUT);
}
Serial.begin(9600);
}
int debounce(int last, int button_port)
{
int current = digitalRead(button_port);
if (last != current)
{
delay(10);
current = digitalRead(button_port);
}
return current;
}
void loop() {
//blue button
cur_toggled_timer_clock_state = debounce(last_toggled_timer_clock_state, toggle_timer_clock);
if (last_toggled_timer_clock_state == HIGH && cur_toggled_timer_clock_state == LOW)
{
if(!is_button_pressed) {
toggle_timer_clock_flag = !toggle_timer_clock_flag;
}
else {
toggle_timer_clock_flag = true;
}
//when the button is not pressed the operation is a clock
stop_flag = false;
if(toggle_timer_clock_flag && !is_button_pressed) {
seconds = 59;
minutes = 59;
hours = 23;
}
//when the button is pressed the operation is a timer
else if (toggle_timer_clock_flag && is_button_pressed) {
is_button_pressed = false;
seconds = 59;
}
else {
seconds = 0;
minutes = 0;
hours = 0;
}
}
last_toggled_timer_clock_state = cur_toggled_timer_clock_state;
//yellow button
cur_toggled_minute_hour_state = debounce(last_toggled_minute_hour_state, toggle_minute_hour);
if (last_toggled_minute_hour_state == HIGH && cur_toggled_minute_hour_state == LOW)
{
if(!stop_flag){
toggle_minute_hour_flag = false;
stop_flag = true;
}
else {
toggle_minute_hour_flag = !toggle_minute_hour_flag;
}
is_button_pressed = true;
}
last_toggled_minute_hour_state = cur_toggled_minute_hour_state;
cur_increase_count_state = debounce(last_increase_count_state, increase_count);
if (last_increase_count_state == HIGH && cur_increase_count_state == LOW)
{
//when buttton is pressed, minutes is in operation
if(!toggle_minute_hour_flag) {
if (minutes < 59) {
timer = timer + 1000;
if ( millis() - timer >= 1000)
{
timer = timer - 1000;
minutes = minutes + 1;
}
}
else {
minutes = 0;
}
}
//if not, then hours
else {
if (hours < 23) {
timer = timer + 1000;
if ( millis() - timer >= 1000)
{
timer = timer - 1000;
hours = hours + 1;
}
}
else {
hours = 0;
}
}
stop_flag = true;
is_button_pressed = true;
}
last_increase_count_state = cur_increase_count_state;
cur_decrease_count_state = debounce(last_decrease_count_state, decrease_count);
//red button
if (last_decrease_count_state == HIGH && cur_decrease_count_state == LOW)
{
if(!toggle_minute_hour_flag) {
if (minutes > 0) {
timer = timer + 1000;
if ( millis() - timer >= 1000)
{
timer = timer - 1000;
minutes = minutes - 1;
}
}
else {
minutes = 59;
}
}
else {
if (hours > 0) {
timer = timer + 1000;
if ( millis() - timer >= 1000)
{
timer = timer - 1000;
hours = hours - 1;
}
}
else {
hours = 23;
}
}
stop_flag = true;
is_button_pressed = true;
}
last_decrease_count_state = cur_decrease_count_state;
//read current time
//extract hours, minutes, seconds
if(!stop_flag && !toggle_timer_clock_flag) {
if ( seconds < 60) {
if ( millis() - timer >= 1000)
{
timer = timer + 1000;
seconds = seconds + 1;
Serial.println(seconds);
delay(10);
}
}
if ( seconds >= 60) {
if ( millis() - timer >= 1000)
{
timer = timer + 1000;
seconds = 0;
minutes = minutes + 1;
}
}
if ( minutes >= 60) {
timer = timer + 1000;
if ( millis() - timer >= 1000)
{
timer = timer - 1000;
seconds = 0;
minutes = 0;
hours = hours + 1;
}
}
if (hours >= 24) {
timer = timer + 1000;
if ( millis() - timer >= 1000)
{
timer = millis();
seconds = 0;
minutes = 0;
hours = 0;
stop_flag = true;
}
}
}
else if(!stop_flag && toggle_timer_clock_flag) {
is_button_pressed = false;
if ( seconds > 0) {
if ( millis() - timer >= 1000)
{
timer = timer + 1000;
seconds = seconds - 1;
Serial.println(seconds);
delay(10);
}
}
if ( seconds <= 0) {
if ( millis() - timer >= 1000)
{
timer = timer + 1000;
seconds = 59;
minutes = minutes-1;
}
}
if (minutes <= 0 && seconds <= 0) {
timer = timer + 1000;
if ( millis() - timer >= 1000)
{
timer = timer - 1000;
seconds = 59;
minutes = 59;
hours = hours-1;
}
}
if (hours <= 0 && minutes <= 0 && seconds <= 0) {
timer = timer + 1000;
if ( millis() - timer >= 1000)
{
timer = millis();
seconds = 0;
minutes = 0;
hours = 0;
stop_flag = true;
}
}
}
else{
timer = millis();
}
unsigned long current_millis = millis();
// Check if it's time to toggle the blink state
if (current_millis - previous_millis >= interval) {
previous_millis = current_millis;
blink_state = !blink_state;
}
//display hours and minutes
for(int i =0; i < 4; i++) {
if(toggle_minute_hour_flag && stop_flag && blink_state && (i == 0 || i == 1)) {
displayNumber(-1, i);
}
else if (!toggle_minute_hour_flag && stop_flag && blink_state && (i == 2 || i == 3)) {
displayNumber(-1, i);
}
else {
if (i < 2) {
// Display hours
int digitValue = (i == 0) ? hours / 10 : hours % 10;
displayNumber(digitValue, i);
} else {
// Display minutes
int digitValue = (i == 2) ? minutes / 10 : minutes % 10;
displayNumber(digitValue, i);
}
}
delay(5);
}
}
void displayNumber(int number, int digit) {
//activate the appropriate digit
digitalWrite(digitPins[digit], LOW);
//display the correspinding digit pattern
for (int i = 0; i < 8; i++) {
digitalWrite(segmentPins[i], bitRead(digitPatterns[number], i));
}
if (digit == 1) {
digitalWrite(segmentPins[7], HIGH);
}
delay(5);
for (int i = 0; i < 8; i++) {
digitalWrite(segmentPins[i], LOW);
}
digitalWrite(digitPins[digit], HIGH);
}