#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 = true; // ابتدا دقیقه برای تنظیم انتخاب شود
int setHour = 0, setMinute = 0;
unsigned long buttonPressTime = 0; // زمان نگه داشتن دکمه SET
unsigned long lastActionTime = 0; // زمان آخرین فشردن دکمه
unsigned long displayChangeTime = 0; // زمان تغییر نمایش
const unsigned long settingTimeout = 5000; // زمان خروج خودکار از تنظیمات (۵ ثانیه)
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 = true; // ابتدا دقیقه برای تنظیم انتخاب شود
DateTime now = rtc.now();
setHour = now.hour();
setMinute = now.minute();
lastActionTime = currentTime;
}
} else {
buttonPressTime = 0;
}
// مدیریت حالت تنظیم
if (isSetting) {
handleSettingMode(currentTime);
} else {
displayCurrentTime(); // نمایش ساعت عادی
}
}
// مدیریت حالت تنظیم
void handleSettingMode(unsigned long currentTime) {
// جابهجایی بین تنظیم ساعت و دقیقه با فشردن کلید SET
if (digitalRead(BUTTON_SET) == LOW && currentTime - lastActionTime > 200) {
isMinuteSetting = !isMinuteSetting; // تغییر بین ساعت و دقیقه
lastActionTime = currentTime;
}
// افزایش مقدار با کلید UP
if (digitalRead(BUTTON_UP) == LOW && currentTime - lastActionTime > 200) {
if (isMinuteSetting) {
setMinute = (setMinute + 1) % 60; // افزایش دقیقه
} else {
setHour = (setHour + 1) % 24; // افزایش ساعت
}
lastActionTime = currentTime;
}
// کاهش مقدار با کلید DOWN
if (digitalRead(BUTTON_DOWN) == LOW && currentTime - lastActionTime > 200) {
if (isMinuteSetting) {
setMinute = (setMinute - 1 + 60) % 60; // کاهش دقیقه
} else {
setHour = (setHour - 1 + 24) % 24; // کاهش ساعت
}
lastActionTime = currentTime;
}
// نمایش تنظیمات
if (isMinuteSetting) {
displaySetting(setMinute, 'd'); // نمایش دقیقه و حرف 'd'
} else {
displaySetting(setHour, 'P'); // نمایش ساعت و حرف 'P'
}
// خروج خودکار از حالت تنظیم پس از ۵ ثانیه عدم فعالیت
if (currentTime - lastActionTime > settingTimeout) {
rtc.adjust(DateTime(2023, 1, 1, setHour, setMinute, 0)); // ذخیره تنظیمات
isSetting = false; // خروج از حالت تنظیم
}
}
// نمایش تنظیمات با حرف مشخص
void displaySetting(int value, char prefix) {
uint8_t digits[4];
digits[0] = display.encodeDigit(prefix); // نمایش حرف (d یا P)
digits[1] = display.encodeDigit(value / 10); // رقم دهگان
digits[2] = display.encodeDigit(value % 10); // رقم یکان
digits[3] = 0; // خالی
display.setSegments(digits, 4, 0); // نمایش روی نمایشگر
}
// نمایش ساعت بهصورت ۱۲ ساعته
void displayCurrentTime() {
DateTime now = rtc.now();
int hour = now.hour();
int minute = now.minute();
// تبدیل ساعت به فرمت ۱۲ ساعته
bool isPM = false;
if (hour >= 12) {
isPM = true;
if (hour > 12) hour -= 12;
}
if (hour == 0) hour = 12;
// نمایش ساعت و دقیقه
int displayTime = hour * 100 + minute;
display.showNumberDecEx(displayTime, 0b01000000, true); // ":" روشن
}
// نمایش دما با "C" و دو رقم
void showTemp() {
float temp = dht.readTemperature();
if (isnan(temp)) {
display.showNumberDec(8888); // خطا
return;
}
int displayTemp = (int)temp;
if (displayTemp < 0 || displayTemp > 99) {
displayTemp = 0; // محدودیت دما به ۰ تا ۹۹ درجه
}
// نمایش "C" و دما
uint8_t cSymbol = SEG_A | SEG_D | SEG_E | SEG_F; // کد کاراکتر "C"
uint8_t digits[4];
digits[0] = display.encodeDigit(displayTemp / 10); // رقم دهگان
digits[1] = display.encodeDigit(displayTemp % 10); // رقم یکان
digits[2] = cSymbol; // کاراکتر "C"
digits[3] = 0; // خالی
display.setSegments(digits, 4, 0); // نمایش دما و "C"
}
// تست هفتسگمنت
void testSegment() {
for (int i = 0; i <= 9999; i += 1111) {
display.showNumberDec(i);
delay(500);
}
}