#include <Wire.h>
#include <RTClib.h>
#include <TM1637Display.h>
#define CLK_PIN 9
#define DIO_PIN 8
TM1637Display display(CLK_PIN, DIO_PIN);
RTC_DS1307 rtc;
bool showTime = true;
#define UP_BUTTON_PIN 2
#define DOWN_BUTTON_PIN 3
#define MODE_BUTTON_PIN 4
unsigned long previousMillis = 0;
const long interval = 1000;
int mode = 0; // 0: ساعت, 1: تاریخ, 2: تنظیمات
unsigned long modePressTime = 0;
bool isModePressed = false;
int adjustMode = 0; // 0: ساعت, 1: دقیقه, 2: روز, 3: ماه
bool isAdjusting = false; // برای بررسی اینکه آیا در حالت تنظیمات هستیم یا نه
unsigned long lastModePressTime = 0;
const unsigned long debounceDelay = 50; // تاخیر برای جلوگیری از نوسانات
unsigned long lastModeChange = 0; // زمان آخرین تغییر به حالت تاریخ
void setup() {
Wire.begin();
rtc.begin();
display.setBrightness(7);
pinMode(UP_BUTTON_PIN, INPUT_PULLUP);
pinMode(DOWN_BUTTON_PIN, INPUT_PULLUP);
pinMode(MODE_BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
DateTime now = rtc.now();
int hour = now.hour();
int minute = now.minute();
int day = now.day();
int month = now.month();
// ساعت ۱۲ ساعته
if (hour > 12) {
hour -= 12;
}
// حالتهای مختلف
if (mode == 0) {
display.showNumberDecEx(hour * 100 + minute, 0b01000000, true); // فقط نقطه وسط چشمک میزند
} else if (mode == 1) {
display.showNumberDecEx(month * 100 + day, 0b00001110, showTime); // نمایش تاریخ
} else if (mode == 2) {
adjustTime(now); // تنظیم ساعت و تاریخ
}
// بررسی وضعیت دکمهها
handleButtons(now);
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
showTime = !showTime;
}
// برگشت به ساعت بعد از 5 ثانیه اگر دکمه فشرده نشده باشد
if (mode == 1 && currentMillis - lastModeChange >= 5000) {
mode = 0;
}
}
void handleButtons(DateTime now) {
int modeState = digitalRead(MODE_BUTTON_PIN);
int upState = digitalRead(UP_BUTTON_PIN);
int downState = digitalRead(DOWN_BUTTON_PIN);
// چک کردن کلید Mode برای تغییر حالت (ساعت -> تاریخ -> تنظیمات)
if (modeState == LOW && millis() - lastModePressTime > debounceDelay) {
if (!isModePressed) {
isModePressed = true;
modePressTime = millis();
}
lastModePressTime = millis();
}
if (modeState == HIGH && isModePressed) {
unsigned long pressDuration = millis() - modePressTime;
if (pressDuration < 3000) {
// تغییر حالت (فشار کوتاه)
if (mode == 0) {
mode = 1;
lastModeChange = millis();
} else if (mode == 1) {
mode = 0;
}
} else {
// ورود به تنظیمات (نگه داشتن ۳ ثانیه)
mode = 2;
adjustMode = 0; // شروع از ساعت
isAdjusting = true; // وارد حالت تنظیمات شدیم
}
isModePressed = false;
}
// تنظیم ساعت و تاریخ
if (mode == 2) {
if (upState == LOW) {
delay(200);
if (adjustMode == 0) { // تغییر ساعت
DateTime newTime = DateTime(now.year(), now.month(), now.day(), now.hour() + 1, now.minute(), now.second());
rtc.adjust(newTime);
} else if (adjustMode == 1) { // تغییر دقیقه
DateTime newTime = DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute() + 1, now.second());
rtc.adjust(newTime);
} else if (adjustMode == 2) { // تغییر روز
DateTime newTime = DateTime(now.year(), now.month(), now.day() + 1, now.hour(), now.minute(), now.second());
rtc.adjust(newTime);
} else if (adjustMode == 3) { // تغییر ماه
DateTime newTime = DateTime(now.year(), now.month() + 1, now.day(), now.hour(), now.minute(), now.second());
rtc.adjust(newTime);
}
}
if (downState == LOW) {
delay(200);
if (adjustMode == 0) { // تغییر ساعت
DateTime newTime = DateTime(now.year(), now.month(), now.day(), now.hour() - 1, now.minute(), now.second());
rtc.adjust(newTime);
} else if (adjustMode == 1) { // تغییر دقیقه
DateTime newTime = DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute() - 1, now.second());
rtc.adjust(newTime);
} else if (adjustMode == 2) { // تغییر روز
DateTime newTime = DateTime(now.year(), now.month(), now.day() - 1, now.hour(), now.minute(), now.second());
rtc.adjust(newTime);
} else if (adjustMode == 3) { // تغییر ماه
DateTime newTime = DateTime(now.year(), now.month() - 1, now.day(), now.hour(), now.minute(), now.second());
rtc.adjust(newTime);
}
}
}
}
void adjustTime(DateTime now) {
// نمایش ساعت و بخشهای مختلف
if (isAdjusting) {
// وقتی در حالت تنظیمات هستیم، نمایش اعداد به گونهای باشد که چشمک بزند
if (adjustMode == 0) {
display.showNumberDecEx(now.hour(), 0b01000000, true); // نمایش ساعت و چشمک زدن
} else if (adjustMode == 1) {
display.showNumberDecEx(now.minute(), 0b01000000, true); // نمایش دقیقه و چشمک زدن
} else if (adjustMode == 2) {
display.showNumberDecEx(now.day(), 0b01000000, true); // نمایش روز و چشمک زدن
} else if (adjustMode == 3) {
display.showNumberDecEx(now.month(), 0b01000000, true); // نمایش ماه و چشمک زدن
}
} else {
// در حالت نمایش زمان، نمایش عادی ساعت و تاریخ
display.showNumberDecEx(now.hour(), 0b01000000, showTime);
display.showNumberDecEx(now.minute(), 0b00000000, showTime);
}
// با فشردن دکمه Mode در حالت تنظیمات، به بخش بعدی برویم (ساعت -> دقیقه -> روز -> ماه)
if (mode == 2 && digitalRead(MODE_BUTTON_PIN) == LOW) {
delay(200);
adjustMode++;
if (adjustMode > 3) {
adjustMode = 0; // برگرداندن به ساعت بعد از ماه
isAdjusting = false; // خروج از حالت تنظیمات
mode = 0; // بازگشت به حالت نمایش ساعت
}
}
}