#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <RTClib.h>
// LCD ekran ayarları
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD adresi genellikle 0x27 veya 0x3F olabilir
// DHT11 sensör ayarları
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// RTC modülü ayarları
RTC_DS1307 rtc;
// Röle pinleri
#define RELAY1 3
#define RELAY2 4
#define RELAY3 5
// Potansiyometre pinleri
#define TEMP_POT_PIN A0
#define HUM_POT_PIN A1
// Buzzer pini
#define BUZZER_PIN 6
// Limit toleransları
const float TEMP_TOLERANCE = 0.5;
const float HUM_TOLERANCE = 2;
const float ALARM_THRESHOLD = 2.0; // Alarm eşiği (toleranslar + eşiğe göre)
// Röle 3'ün çalışma süresi ve döngü süresi
const int WORK_DURATION = 1; // dakika
const int CYCLE_DURATION = 99; // 2 saat (dakika cinsinden)
// Zamanlayıcılar için değişkenler
DateTime previousRelayOnTime;
DateTime previousDayTime;
bool relay3State = false;
unsigned long relay3Interval = WORK_DURATION * 60000; // Rölenin çalışma süresi (milisaniye)
unsigned long relay3CycleInterval = CYCLE_DURATION * 60000; // 2 saatlik döngü süresi (milisaniye)
int dayCounter = 0; // Gün sayacı
bool firstRun = true; // İlk açılış kontrol bayrağı
void setup() {
// Seri haberleşme başlat
Serial.begin(9600);
// LCD ekranı başlat
lcd.init();
lcd.backlight();
// DHT11 sensörünü başlat
dht.begin();
// RTC modülünü başlat
if (!rtc.begin()) {
lcd.print("RTC Bağlanamadı");
while (1);
}
// RTC'yi doğru ayarla (bu kod, RTC modülünün doğru bir şekilde çalıştığını varsayar)
if (!rtc.isrunning()) {
lcd.print("RTC Çalışmıyor");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Röle pinlerini çıkış olarak ayarla
pinMode(RELAY1, OUTPUT);
pinMode(RELAY2, OUTPUT);
pinMode(RELAY3, OUTPUT);
// Buzzer pinini çıkış olarak ayarla
pinMode(BUZZER_PIN, OUTPUT);
// Röleleri kapalı konumda başlat
digitalWrite(RELAY1, LOW);
digitalWrite(RELAY2, LOW);
digitalWrite(RELAY3, LOW);
// İlk başlatmada Röle 3'ün kapanma zamanını ve gün sayacını ayarla
previousRelayOnTime = rtc.now();
previousDayTime = rtc.now();
// İlk açılış mesajını göster
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("->SADI YILDIZ<-");
lcd.setCursor(0, 1);
lcd.print("<-05438155503->");
delay(2000); // Mesajı 2 saniye boyunca göster
firstRun = false;
}
void loop() {
// Nem ve sıcaklık değerlerini al
float h = dht.readHumidity();
float t = dht.readTemperature();
// Potansiyometrelerden sıcaklık ve nem limitlerini al
int tempPotValue = analogRead(TEMP_POT_PIN);
int humPotValue = analogRead(HUM_POT_PIN);
// Sıcaklık ve nem limitlerini potansiyometre değerlerine göre ayarla
float tempLimit = map(tempPotValue, 0, 1023, 15, 40); // 15°C - 40°C arası
float humLimit = map(humPotValue, 0, 1023, 30, 70); // %30 - %70 arası
// Röle 3'ü kontrol et
DateTime now = rtc.now();
unsigned long elapsedTime = now.unixtime() - previousRelayOnTime.unixtime();
unsigned long cycleTime = relay3CycleInterval / 1000; // Döngü süresi saniye cinsinden
unsigned long workTime = relay3Interval / 1000; // Çalışma süresi saniye cinsinden
unsigned long remainingCycleTime = cycleTime - (elapsedTime % cycleTime);
unsigned long remainingWorkTime = relay3State ? (workTime - (elapsedTime % cycleTime)) : remainingCycleTime;
// Gün sayacını güncelle
if (now.day() != previousDayTime.day()) {
dayCounter++;
previousDayTime = now;
}
// LCD ekranı güncelle
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(t, 1); // 1 ondalıklı gösterim
lcd.print("\337 ->");
lcd.print(tempLimit, 1); // 1 ondalıklı gösterim
lcd.print("\337 ");
lcd.setCursor(0, 1);
lcd.print(h, 1); // 1 ondalıklı gösterim
lcd.print("% ->");
lcd.print(humLimit, 1); // 1 ondalıklı gösterim
lcd.print("%");
// Kalan süreyi dakika cinsinden hesapla
unsigned long remainingMinutes = remainingWorkTime / 60; // Dakika cinsinden kalan süre
// Kalan süreyi ve gün sayacını LCD ekranının 1. satırının 14. sütununa yazdır
lcd.setCursor(14, 0);
lcd.print(remainingMinutes);
lcd.setCursor(14, 1);
lcd.print(dayCounter);
// Röleleri kontrol et
if (t > (tempLimit + TEMP_TOLERANCE)) {
digitalWrite(RELAY1, LOW); // Sıcaklık limitinin üstünde
} else if (t < (tempLimit - TEMP_TOLERANCE)) {
digitalWrite(RELAY1, HIGH); // Sıcaklık limitinin altında
} else {
digitalWrite(RELAY1, HIGH); // Sıcaklık tolerans aralığında
}
if (h > (humLimit + HUM_TOLERANCE)) {
digitalWrite(RELAY2, LOW); // Nem limitinin üstünde
} else if (h < (humLimit - HUM_TOLERANCE)) {
digitalWrite(RELAY2, HIGH); // Nem limitinin altında
} else {
digitalWrite(RELAY2, HIGH); // Nem tolerans aralığında
}
// Limit toleranslarının üzerinde bir fark olduğunda alarmı çal
if ((t > (tempLimit + TEMP_TOLERANCE + ALARM_THRESHOLD)) || (h > (humLimit + HUM_TOLERANCE + ALARM_THRESHOLD))) {
tone(BUZZER_PIN, 1000); // Buzzer'ı 1kHz frekansta çaldır
} else if ((t < (tempLimit - TEMP_TOLERANCE - ALARM_THRESHOLD)) || (h < (humLimit - HUM_TOLERANCE - ALARM_THRESHOLD))) {
tone(BUZZER_PIN, 1000); // Buzzer'ı 1kHz frekansta çaldır
} else {
noTone(BUZZER_PIN); // Buzzer'ı kapat
}
// Röle 3'ü kontrol et
if (now.unixtime() - previousRelayOnTime.unixtime() >= relay3CycleInterval / 1000) {
previousRelayOnTime = now;
relay3State = !relay3State;
digitalWrite(RELAY3, relay3State ? HIGH : LOW);
// Röleyi 2 dakika çalıştır
if (relay3State) {
delay(relay3Interval);
digitalWrite(RELAY3, LOW);
}
}
// Gecikme
delay(1000); // LCD'yi daha sık güncellemek için gecikmeyi 1000 ms olarak ayarladık
}