#include <Wire.h>
#include <RTClib.h>
#include <DHT.h>
#include <TM1637Display.h>
// تعریف پینها
#define CLK 9
#define DIO 8
#define DHTPIN 5
#define DHTTYPE DHT22
#define MODE_BUTTON 2
#define UP_BUTTON 3
#define DOWN_BUTTON 4
// تعریف شیءها
RTC_DS1307 rtc;
DHT dht(DHTPIN, DHTTYPE);
TM1637Display display(CLK, DIO);
// متغیرهای زمان و دما
int hours = 0, minutes = 0, seconds = 0;
float temperature = 0;
// متغیرهای حالت
bool showTemp = false;
bool settingMode = false;
bool fixedTimeDisplay = false;
int settingStep = 0;
unsigned long lastUpdate = 0;
unsigned long lastButtonPress = 0;
unsigned long modePressStart = 0;
DateTime now;
void setup() {
Serial.begin(9600);
Wire.begin();
rtc.begin();
dht.begin();
display.setBrightness(0x0a);
pinMode(MODE_BUTTON, INPUT_PULLUP);
pinMode(UP_BUTTON, INPUT_PULLUP);
pinMode(DOWN_BUTTON, INPUT_PULLUP);
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
unsigned long currentMillis = millis();
now = rtc.now();
hours = now.hour();
minutes = now.minute();
seconds = now.second();
// تبدیل ساعت به ۱۲ ساعته
if (hours >= 12) {
if (hours > 12) hours -= 12;
}
if (hours == 0) hours = 12;
// خواندن دما هر ۵ ثانیه
if (currentMillis - lastUpdate >= 5000) {
temperature = dht.readTemperature();
lastUpdate = currentMillis;
showTemp = !showTemp;
}
// نمایش ساعت یا دما
if (fixedTimeDisplay) {
display.showNumberDecEx(hours * 100 + minutes, 0b01000000, true);
} else {
if (!settingMode) {
if (showTemp) {
int tempDisplay = (int)(temperature * 10);
display.showNumberDecEx(tempDisplay, 0b00100000, true);
} else {
display.showNumberDecEx(hours * 100 + minutes, 0b01000000, true);
}
} else {
handleSetting();
}
}
checkButtons();
// خروج خودکار از تنظیمات بعد از ۵ ثانیه
if (settingMode && (currentMillis - lastButtonPress >= 5000)) {
settingMode = false;
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hours, minutes, 0));
settingStep = 0;
}
}
void checkButtons() {
static int lastModeButtonState = HIGH;
static int lastUpButtonState = HIGH;
static int lastDownButtonState = HIGH;
int modeButtonState = digitalRead(MODE_BUTTON);
int upButtonState = digitalRead(UP_BUTTON);
int downButtonState = digitalRead(DOWN_BUTTON);
unsigned long currentMillis = millis();
// بررسی نگه داشتن دکمه MODE برای ۳ ثانیه
if (modeButtonState == LOW) {
if (modePressStart == 0) {
modePressStart = currentMillis;
} else if (currentMillis - modePressStart >= 3000) {
settingMode = true;
settingStep = 0;
lastButtonPress = currentMillis;
modePressStart = 0;
}
} else {
modePressStart = 0;
}
// بررسی فشار دکمه MODE برای تغییر بین تنظیمات
if (modeButtonState == HIGH && lastModeButtonState == LOW && settingMode) {
settingStep = (settingStep + 1) % 2;
lastButtonPress = currentMillis;
}
lastModeButtonState = modeButtonState;
// بررسی دکمه UP
if (upButtonState == LOW && lastUpButtonState == HIGH) {
if (settingMode) {
if (settingStep == 0) {
hours = (hours % 12) + 1;
if (hours == 0) hours = 12;
} else if (settingStep == 1) {
minutes = (minutes + 1) % 60;
}
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hours, minutes, seconds));
} else {
fixedTimeDisplay = !fixedTimeDisplay;
}
lastButtonPress = currentMillis;
}
lastUpButtonState = upButtonState;
// بررسی دکمه DOWN
if (downButtonState == LOW && lastDownButtonState == HIGH) {
if (settingMode) {
if (settingStep == 0) {
hours = (hours == 1) ? 12 : hours - 1;
} else if (settingStep == 1) {
minutes = (minutes == 0) ? 59 : minutes - 1;
}
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hours, minutes, seconds));
}
lastButtonPress = currentMillis;
}
lastDownButtonState = downButtonState;
}
void handleSetting() {
if (settingStep == 0) {
display.showNumberDecEx(hours, 0b01000000, false);
} else if (settingStep == 1) {
display.showNumberDecEx(minutes, 0b01000000, false);
}
}