// ESP32 Sicaklik Loglayici — TEST MODU (10 sn interval)
// DHT22 + DS1307 RTC + microSD + SSD1306 OLED
// OLED yerlesimi: her satir merkezlenmis, status alt bantta
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
#include <DHT.h>
#include <SPI.h>
#include <SD.h>
#define DHT_PIN 4
#define DHT_TYPE DHT22
#define SD_CS 5
#define LED_STATUS 15
#define OLED_W 128
#define OLED_H 64
#define OLED_ADDR 0x3C
#define LOG_INTERVAL_MS 10000UL // TEST: 10 sn (prod: 60000)
DHT dht(DHT_PIN, DHT_TYPE);
RTC_DS1307 rtc;
Adafruit_SSD1306 oled(OLED_W, OLED_H, &Wire, -1);
uint32_t logCount = 0;
uint32_t lastLogMs = 0;
bool sdOk = false;
bool rtcOk = false;
float lastTemp = 0.0;
float lastHum = 0.0;
String lastStamp = "Bekleniyor...";
// ============ HELPERS ============
void lcdAt(int x, int y, uint8_t size, const String &t) {
oled.setTextSize(size);
oled.setCursor(x, y);
oled.print(t);
}
// Metni belirtilen y'de x-ekseninde ortalar
void centered(uint8_t y, uint8_t size, const String &t) {
int w = t.length() * 6 * size;
int x = (128 - w) / 2;
if (x < 0) x = 0;
lcdAt(x, y, size, t);
}
String twoDig(int n) { return (n < 10) ? "0" + String(n) : String(n); }
String euDate(DateTime d) { return twoDig(d.day()) + "." + twoDig(d.month()) + "." + String(d.year()); }
String hhmmss(DateTime d) { return twoDig(d.hour()) + ":" + twoDig(d.minute()) + ":" + twoDig(d.second()); }
String isoDate(DateTime d) { return String(d.year()) + "-" + twoDig(d.month()) + "-" + twoDig(d.day()); }
// ============ EKRANLAR ============
void drawSplash() {
oled.clearDisplay();
oled.setTextColor(SSD1306_WHITE);
oled.drawRoundRect(2, 2, 124, 60, 6, SSD1306_WHITE);
centered(14, 2, "BlueGrays");
centered(36, 1, "Sicaklik Logger");
centered(50, 1, "v1.0 DHT22 + RTC");
oled.display();
}
void drawStatus() {
oled.clearDisplay();
oled.setTextColor(SSD1306_WHITE);
// Baslik
centered(0, 1, "Sicaklik Logger");
oled.drawLine(0, 10, 127, 10, SSD1306_WHITE);
// Buyuk sicaklik degeri
String tempStr = String(lastTemp, 1) + " C";
centered(15, 2, tempStr);
// Nem (sol) + kayit sayaci (sag)
String humStr = "Nem: %" + String(lastHum, 1);
lcdAt(0, 36, 1, humStr);
String cnt = "#" + String(logCount);
int cntW = cnt.length() * 6;
lcdAt(128 - cntW, 36, 1, cnt);
oled.drawLine(0, 45, 127, 45, SSD1306_WHITE);
// Zaman damgasi (orta)
centered(47, 1, lastStamp);
// Alt bant: SD + RTC durum (orta)
String stat = String(sdOk ? "SD:OK" : "SD:X ") + " " + String(rtcOk ? "RTC:OK" : "RTC:X");
centered(57, 1, stat);
oled.display();
}
// ============ SETUP ============
void setup() {
Serial.begin(115200);
delay(500);
pinMode(LED_STATUS, OUTPUT);
digitalWrite(LED_STATUS, LOW);
Wire.begin();
if (!oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("[X] OLED bulunamadi");
while (1) delay(100);
}
drawSplash();
delay(2500);
dht.begin();
Serial.println("[OK] DHT22 baslatildi");
if (!rtc.begin()) {
Serial.println("[X] DS1307 bulunamadi");
rtcOk = false;
} else {
rtcOk = true;
if (!rtc.isrunning()) {
Serial.println("[!] RTC calismiyordu, derleme zamanina ayarlandi");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Serial.println("[OK] RTC hazir: " + isoDate(rtc.now()) + " " + hhmmss(rtc.now()));
}
if (!SD.begin(SD_CS)) {
Serial.println("[X] SD kart baslatilamadi (CS=GPIO 5)");
sdOk = false;
} else {
sdOk = true;
Serial.println("[OK] SD kart hazir");
if (!SD.exists("/temp_log.csv")) {
File f = SD.open("/temp_log.csv", FILE_WRITE);
if (f) {
f.println("tarih,saat,sicaklik_C,nem_yuzde,log_no");
f.close();
Serial.println("[OK] /temp_log.csv header yazildi");
}
}
}
drawStatus();
Serial.println("== Kayit baslatildi (test modu 10 sn) ==");
}
// ============ LOG ============
void logNow() {
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(t) || isnan(h)) {
Serial.println("[!] DHT okuma HATASI");
return;
}
lastTemp = t;
lastHum = h;
DateTime now = rtcOk ? rtc.now() : DateTime((uint32_t)(millis() / 1000));
lastStamp = euDate(now) + " " + hhmmss(now);
logCount++;
Serial.printf("[%s] T=%.1fC H=%.1f%% #%lu\n",
lastStamp.c_str(), t, h, (unsigned long)logCount);
if (sdOk) {
File f = SD.open("/temp_log.csv", FILE_APPEND);
if (f) {
f.printf("%s,%s,%.1f,%.1f,%lu\n",
isoDate(now).c_str(), hhmmss(now).c_str(), t, h, (unsigned long)logCount);
f.close();
} else {
Serial.println("[X] SD yazma HATASI");
}
}
digitalWrite(LED_STATUS, HIGH);
delay(80);
digitalWrite(LED_STATUS, LOW);
drawStatus();
}
// ============ LOOP ============
void loop() {
uint32_t now = millis();
if (now - lastLogMs >= LOG_INTERVAL_MS || lastLogMs == 0) {
lastLogMs = now;
logNow();
}
delay(200);
}