#include <Wire.h>
#include <RTClib.h>
#include <TM1637Display.h>
#include <DHT.h>
#define CLK_PIN 9
#define DIO_PIN 8
#define DHTPIN 5
#define DHTTYPE DHT11
TM1637Display display(CLK_PIN, DIO_PIN);
RTC_DS1307 rtc;
DHT dht(DHTPIN, DHTTYPE);
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 = 500;
int mode = 0; // 0: ساعت, 1: تاریخ, 2: دما, 3: تنظیمات
unsigned long modePressTime = 0;
bool isModePressed = false;
int adjustMode = 0; // 0: ساعت, 1: دقیقه, 2: روز, 3: ماه
bool isAdjusting = false;
unsigned long lastModeChange = 0;
// کد سگمنتهای حروف برای نمایشگر TM1637
const uint8_t SEGMENT_H = 0b01110110; // 'H'
const uint8_t SEGMENT_E = 0b01111001; // 'E'
const uint8_t SEGMENT_D = 0b01011110; // 'D'
const uint8_t SEGMENT_F = 0b01110001; // 'F'
const uint8_t SEGMENT_MINUS = 0b01000000; // '-'
void setup() {
Wire.begin();
rtc.begin();
dht.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) {
showTemperature(); // نمایش دما
} else if (mode == 3) {
adjustTime(now); // حالت تنظیمات
}
handleButtons(now);
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
showTime = !showTime;
}
if (mode == 1 || mode == 2) {
if (millis() - 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);
if (modeState == LOW) {
if (!isModePressed) {
isModePressed = true;
modePressTime = millis();
}
} else if (modeState == HIGH && isModePressed) {
unsigned long pressDuration = millis() - modePressTime;
if (pressDuration < 3000) {
mode = (mode + 1) % 3; // تغییر بین ساعت، تاریخ و دما
lastModeChange = millis();
} else {
mode = 3; // ورود به تنظیمات
adjustMode = 0;
isAdjusting = true;
}
isModePressed = false;
}
if (mode == 3) {
if (upState == LOW) {
delay(200);
adjustDateTime(now, true);
}
if (downState == LOW) {
delay(200);
adjustDateTime(now, false);
}
}
}
void adjustTime(DateTime now) {
int hour = now.hour();
int minute = now.minute();
int day = now.day();
int month = now.month();
if (hour > 12) {
hour -= 12;
}
uint8_t leadingSegments[2] = {SEGMENT_MINUS, 0}; // بخش چپ ثابت
int valueToDisplay = 0;
switch (adjustMode) {
case 0: // تنظیم ساعت
leadingSegments[1] = SEGMENT_H;
valueToDisplay = hour;
break;
case 1: // تنظیم دقیقه
leadingSegments[1] = SEGMENT_E;
valueToDisplay = minute;
break;
case 2: // تنظیم روز
leadingSegments[1] = SEGMENT_D;
valueToDisplay = day;
break;
case 3: // تنظیم ماه
leadingSegments[1] = SEGMENT_F;
valueToDisplay = month;
break;
}
// نمایش بخش چپ ثابت و مقدار چشمکزن
display.setSegments(leadingSegments, 2, 0); // نمایش حروف ثابت
if (showTime || !isAdjusting) {
display.showNumberDecEx(valueToDisplay, 0b01000000, true, 2, 2);
}
// تغییر حالت با فشار کلید Mode
if (digitalRead(MODE_BUTTON_PIN) == LOW) {
delay(200);
adjustMode = (adjustMode + 1) % 4;
if (adjustMode == 0) {
mode = 0; // بازگشت به نمایش ساعت
}
}
}
void adjustDateTime(DateTime now, bool increment) {
int hour = now.hour();
int minute = now.minute();
int day = now.day();
int month = now.month();
int year = now.year();
if (adjustMode == 0) {
hour = increment ? hour + 1 : hour - 1;
if (hour > 12) hour = 1;
if (hour < 1) hour = 12;
} else if (adjustMode == 1) {
minute = increment ? minute + 1 : minute - 1;
if (minute > 59) minute = 0;
if (minute < 0) minute = 59;
} else if (adjustMode == 2) {
day = increment ? day + 1 : day - 1;
if (day > 31) day = 1;
if (day < 1) day = 31;
} else if (adjustMode == 3) {
month = increment ? month + 1 : month - 1;
if (month > 12) month = 1;
if (month < 1) month = 12;
}
rtc.adjust(DateTime(year, month, day, hour, minute, now.second()));
}
void showTemperature() {
float temperature = dht.readTemperature();
if (isnan(temperature)) {
display.showNumberDecEx(8888, 0b00000000, true); // ارور در خواندن دما
} else {
int temp = static_cast<int>(temperature);
display.showNumberDecEx(temp * 100 + 12, 0b00000010, true); // نمایش دما و علامت "C"
}
}