#include <Wire.h>
#include <RTClib.h> // کتابخانه DS1307
#include <TM1637Display.h> // کتابخانه TM1637
#include <DHT.h> // کتابخانه DHT
// تنظیمات DS1307
RTC_DS1307 rtc;
// تنظیمات TM1637
#define CLK 9
#define DIO 8
TM1637Display display(CLK, DIO);
// تنظیمات DHT22
#define DHTPIN 5
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// پینهای کلیدها
#define BUTTON_SET 2
#define BUTTON_UP 3
#define BUTTON_DOWN 4
// متغیرهای عمومی
bool isSetting = false; // حالت تنظیم ساعت
bool isMinuteSetting = false; // انتخاب بین ساعت و دقیقه
bool displayTemperature = false; // نمایش دما
int setHour = 0, setMinute = 0;
unsigned long buttonPressTime = 0; // زمان نگه داشتن دکمه SET
unsigned long lastActionTime = 0; // زمان آخرین فشردن دکمه
unsigned long tempDisplayStart = 0; // زمان شروع نمایش دما
bool tempDisplayActive = false; // وضعیت نمایش دما
void setup() {
// پیکربندی پینها
pinMode(BUTTON_SET, INPUT_PULLUP);
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_DOWN, INPUT_PULLUP);
// آغاز ارتباط سریال
Serial.begin(9600);
// آغاز ماژول RTC
if (!rtc.begin()) {
Serial.println("RTC not found!");
while (1);
}
if (!rtc.isrunning()) {
Serial.println("RTC is NOT running!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // تنظیم اولیه ساعت
}
// آغاز DHT و TM1637
dht.begin();
display.setBrightness(0x0f); // روشنایی کامل
// تست هفتسگمنت
testSegment();
Serial.println("Setup done!");
}
void loop() {
unsigned long currentTime = millis();
// بررسی نگهداشتن دکمه SET برای ۳ ثانیه
if (digitalRead(BUTTON_SET) == LOW) {
if (buttonPressTime == 0) {
buttonPressTime = currentTime;
}
if (currentTime - buttonPressTime > 3000 && !isSetting) { // ورود به حالت تنظیمات
isSetting = true;
isMinuteSetting = false;
DateTime now = rtc.now();
setHour = now.hour();
setMinute = now.minute();
lastActionTime = currentTime;
delay(200);
}
} else {
if (buttonPressTime > 0 && (currentTime - buttonPressTime < 3000)) { // فشردن کوتاه
tempDisplayActive = true;
tempDisplayStart = currentTime;
delay(200);
}
buttonPressTime = 0;
}
if (isSetting) {
handleSettingMode(); // مدیریت تنظیمات
} else if (tempDisplayActive) {
showTemp(); // نمایش دما
if (currentTime - tempDisplayStart > 5000) { // بازگشت به ساعت پس از ۵ ثانیه
tempDisplayActive = false;
}
} else {
displayCurrentTime(); // نمایش ساعت
}
}
// مدیریت حالت تنظیم ساعت
void handleSettingMode() {
unsigned long currentTime = millis();
if (digitalRead(BUTTON_SET) == LOW) { // جابهجایی بین ساعت و دقیقه
delay(200);
isMinuteSetting = !isMinuteSetting;
lastActionTime = currentTime;
}
if (digitalRead(BUTTON_UP) == LOW) { // افزایش مقدار
if (isMinuteSetting) {
setMinute = (setMinute + 1) % 60;
} else {
setHour = (setHour + 1) % 24;
}
lastActionTime = currentTime;
delay(200);
}
if (digitalRead(BUTTON_DOWN) == LOW) { // کاهش مقدار
if (isMinuteSetting) {
setMinute = (setMinute - 1 + 60) % 60;
} else {
setHour = (setHour - 1 + 24) % 24;
}
lastActionTime = currentTime;
delay(200);
}
// چشمک زدن مقدار انتخابشده
if ((currentTime / 500) % 2 == 0) { // هر ۵۰۰ میلیثانیه
if (isMinuteSetting) {
display12HourFormat(setHour, -1); // مخفی کردن دقیقه
} else {
display12HourFormat(-1, setMinute); // مخفی کردن ساعت
}
} else {
display12HourFormat(setHour, setMinute);
}
// خروج از حالت تنظیم پس از ۱۰ ثانیه عدم فعالیت
if (currentTime - lastActionTime > 10000) {
rtc.adjust(DateTime(2023, 1, 1, setHour, setMinute, 0));
isSetting = false;
}
}
// نمایش ساعت بهصورت ۱۲ ساعته
void display12HourFormat(int hour, int minute) {
bool isPM = false;
if (hour != -1 && hour >= 12) {
isPM = true;
if (hour > 12) hour -= 12;
}
if (hour == 0) hour = 12;
int displayTime = 0;
if (hour == -1) { // مخفی کردن ساعت
displayTime = minute;
} else if (minute == -1) { // مخفی کردن دقیقه
displayTime = hour * 100;
} else {
displayTime = hour * 100 + minute;
}
display.showNumberDecEx(displayTime, 0b01000000, true); // ":" روشن
}
// نمایش ساعت فعلی
void displayCurrentTime() {
DateTime now = rtc.now();
display12HourFormat(now.hour(), now.minute());
}
// نمایش دما با "C"
void showTemp() {
float temp = dht.readTemperature();
if (isnan(temp)) {
display.showNumberDec(8888); // خطا
return;
}
int displayTemp = (int)temp;
display.showNumberDecEx(displayTemp, 0b00100000, false); // نمایش دما با "C"
}
// تست هفتسگمنت
void testSegment() {
for (int i = 0; i <= 9999; i += 1111) {
display.showNumberDec(i);
delay(500);
}
}