Rehberler · 12 dk okuma

ESP32 Deep Sleep: Pil Tasarrufu, Uyanma Yöntemleri ve µA Akım

ESP32 deep sleep ile pil tasarrufu: uyku modlarının µA akımları, zamanlayıcı, buton, PIR ve dokunmatik uyanma, RTC bellekte sayaç ve 18650 pil ömrü hesabı.

ESP32 deep sleep (derin uyku), ESP32'nin işlemcisini, Wi-Fi ve Bluetooth radyosunu ve ana belleğini kapatıp yalnızca küçük RTC bölümünü açık bıraktığı güç modudur. Bu modda yonganın tüketimi, Wi-Fi ile veri gönderirkenki 240 mA'den yaklaşık 10 µA'e, yani yirmi dört bin kat aşağıya iner. Kart belirlediğin sürenin sonunda, bir butona basıldığında, PIR sensörü hareket algıladığında ya da bir pine dokunulduğunda uyanır, işini birkaç saniyede bitirir ve yeniden uykuya döner. Pille çalışan hava istasyonları, bahçe sensörleri, kapı alarmları ve uzaktan ölçüm cihazları bu sayede bir 18650 pille günler yerine aylarca çalışabilir.

Bu rehberde ESP32'nin uyku modlarını ve gerçek akım değerlerini, zamanlayıcıyla, butonla, PIR sensörüyle (ext0 ve ext1) ve dokunarak uyandırmayı, uyku boyunca silinmeyen RTC belleğinde sayaç ve ölçüm saklamayı, geliştirme kartlarının neden uykuda bile miliamper harcadığını ve tek bir 18650 pille kaç ay çalışacağını adım adım hesaplamayı öğreneceksin. Arduino kodları ESP32 Arduino çekirdeğinin 3.1 ve sonraki sürümleri için yazıldı; sonunda aynı işi MicroPython ile nasıl yapacağını da göreceksin.

ESP32 geliştirme kartı (DevKit)
ESP32 geliştirme kartı: metal kapaklı modül derin uykuda yaklaşık 10 µA çeker; kartın üzerindeki regülatör, güç LED'i ve USB-seri yonga ise bu değeri miliamperlere çıkarır.

ESP32 deep sleep nedir, nasıl çalışır?

ESP32'nin içinde iki ayrı dünya vardır. Birincisi işlemcileri, 520 KB RAM'i, Wi-Fi ve Bluetooth radyosunu barındıran ana bölümdür. İkincisi ise kendi küçük zamanlayıcısı, 8 KB'lık RTC FAST ve 8 KB'lık RTC SLOW belleği, RTC GPIO pinleri ve ULP adlı ultra düşük güçlü yardımcı işlemcisi olan RTC bölümüdür. Derin uykuda ana bölümün gücü tamamen kesilir, yalnızca RTC bölümü çalışmaya devam eder. Uyanma anı geldiğinde yonga aslında yeniden başlar: önyükleyici çalışır, program flaştan yeniden yüklenir ve setup() en baştan işlenir. Bu yüzden derin uyku kullanan bir programda bütün iş setup() içinde yapılır, loop() hiç çalışmaz. Normal değişkenler her uyanışta sıfırlanır; yalnızca RTC belleğine koyduğun değişkenler korunur.

ESP32 uyku modları ve akım değerleri (µA)

ModNe çalışır?Akım (ESP32 yongası)
Aktif: Wi-Fi gönderim (802.11b, 19,5 dBm)İşlemci ve radyo240 mA
Aktif: Wi-Fi alım ve dinlemeİşlemci ve radyo95–100 mA
Modem uykusu, 240 MHzİşlemci çalışır, radyo kapalı30–68 mA
Modem uykusu, 80 MHzİşlemci yavaş çalışır, radyo kapalı20–31 mA
Hafif uyku (light sleep)İşlemci duraklatılır, RAM korunur0,8 mA
Derin uyku, ULP açıkRTC bölümü ve ULP yardımcı işlemcisi150 µA
Derin uyku (deep sleep)RTC zamanlayıcısı ve RTC belleği10 µA
HibernasyonYalnızca RTC zamanlayıcısı ve bazı RTC pinleri5 µA
Kapalı (EN pini LOW)Hiçbir şey1 µA

Değerler Espressif'in ESP32 veri sayfasından alınmıştır ve yalnızca yonganın kendi tüketimidir. Tabloda iki noktaya dikkat et. Birincisi, hafif uykuda (light sleep) program kaldığı satırdan devam eder ve RAM'deki her şey korunur, ama tüketim derin uykunun seksen katıdır; birkaç saniyelik beklemeler için uygundur. Derin uykuda ise program baştan başlar, buna karşılık tüketim mikroamperlere iner; dakikalar ya da saatler süren beklemeler için doğru seçim budur. İkincisi, iki uyku modunda da Wi-Fi ve Bluetooth bağlantısı korunmaz; her uyanışta yeniden bağlanman gerekir. Yeni nesil yongalarda değerler biraz farklıdır: ESP32-C3 derin uykuda yaklaşık 5 µA, ESP32-S3 ise yaklaşık 7–8 µA çeker.

Daha da düşük tüketim istersen RTC çevre birimlerini ve RTC belleğini de kapatabilirsin. esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF) satırını ve aynısını ESP_PD_DOMAIN_RTC_SLOW_MEM ile ESP_PD_DOMAIN_RTC_FAST_MEM için yazdığında yonga hibernasyon moduna yaklaşır ve yaklaşık 5 µA çeker. Bu durumda RTC belleğindeki değişkenler korunmaz ve kartı yalnızca zamanlayıcı ya da ext1 uyandırabilir. Çoğu projede 10 µA ile 5 µA arasındaki fark, kartın geri kalanının tüketimi yanında önemsiz kalır; önce aşağıdaki bölümdeki sorunları çöz.

Geliştirme kartları uykuda neden miliamper harcar?

Kodunu yükleyip multimetreyi bağladığında çoğu zaman 10 µA yerine 5–15 mA görürsün. Sorun yongada değil, kartın üzerindeki yardımcı parçalardadır. Ucuz DevKit ve NodeMCU-32S kartlarının çoğunda 5 V'u 3,3 V'a düşüren AMS1117 regülatörü bulunur ve bu regülatör hiçbir yük yokken bile kendi başına tipik olarak 5 mA harcar. Buna sürekli yanan güç LED'i ve bilgisayarla haberleşmeyi sağlayan USB-seri yonga (CP2102 ya da CH340) eklenir. Bu üçlünün toplamı tipik olarak 8 mA civarındadır ve ESP32 uyurken bile pilden günde yaklaşık 190 mAh eritir; 3000 mAh'lik bir 18650 böyle bir kartla iki haftayı zor görür. Akımı ölçmek için multimetreyi pil ile devre arasına seri bağla ve uyku sırasında µA kademesine geç; ayrıntılar multimetre nasıl kullanılır yazısında.

Tüketim kaynağıUykudaki akımÇözüm
ESP32 modülü (derin uyku)≈10 µAZaten düşük, ek bir şey gerekmez
AMS1117 regülatörTipik 5 mA (boşta)Boşta akımı 1,6 µA olan MCP1700 ya da 4 µA civarındaki HT7333 kullan
Güç LED'i1–3 mALED'i ya da önündeki direnci sök
USB-seri yonga (CP2102, CH340)Karta göre değişir, mA seviyesine çıkabilirUSB yongası olmayan bir kart ya da çıplak modül kullan
100 kΩ + 100 kΩ pil bölücü21 µA (4,2 V'ta)1 MΩ + 1 MΩ kullan ya da bölücüyü MOSFET'le yalnızca ölçümde aç
Sürekli beslenen sensörlerSensöre göre µA'den mA'eSensörü bir GPIO ya da MOSFET üzerinden yalnızca ölçüm anında besle
18650 gibi Li-ion pilleri asla doğrudan 3V3 pinine bağlama: dolu bir Li-ion hücre 4,2 V'tur, ESP32 ise en fazla 3,6 V kabul eder. Pili kartın VIN girişine bağlamak da iyi bir çözüm değildir, çünkü AMS1117'nin üzerinde yaklaşık 1 V düşer ve pil yarı boşaldığında çıkış 3 V'un altına iner. Doğru yol, düşük boşta akımlı ve düşük gerilim kayıplı bir 3,3 V LDO üzerinden 3V3 pinini beslemektir. MCP1700 ve HT7333 gibi küçük LDO'lar yalnızca 250 mA verebildiği için çıkışlarına Wi-Fi'nin akım tepelerini karşılayacak en az 470 µF'lık bir kondansatör ekle. Tam doluyken 3,6 V'u geçmeyen LiFePO4 hücreler ise regülatörsüz, doğrudan 3V3'e bağlanabilir.

İlk deep sleep kodu: zamanlayıcıyla uyanma

  1. Arduino IDE'de Kart Yöneticisi'nden esp32 by Espressif Systems paketini (3.1 ya da daha yeni bir sürüm) kur ve kart olarak ESP32 Dev Module seç.
  2. Aşağıdaki kodu yükle ve Seri Monitör'ü 115200 baud hızında aç.
  3. Kart her 10 saniyede bir uyanır; uyanış sayısının arttığını ve uyanma nedeninin Zamanlayici olarak yazıldığını gör.
  4. EN düğmesine bas: sayaç 1'e döner, çünkü bu bir derin uyku uyanışı değil, normal bir resettir.
  5. Gerçek projende TIME_TO_SLEEP değerini 600 (10 dakika) ya da 3600 (1 saat) yap.
C++ (Arduino IDE)
1// ESP32 deep sleep: zamanlayıcıyla uyanma ve RTC sayaç / timer wake-up and RTC counter
2#define uS_TO_S_FACTOR 1000000ULL   // 1 saniye = 1.000.000 µs / 1 second = 1,000,000 µs
3#define TIME_TO_SLEEP  10           // uyku süresi, saniye / sleep time in seconds
4
5RTC_DATA_ATTR int bootCount = 0;    // RTC belleğinde, derin uykuda silinmez / in RTC memory, kept in deep sleep
6
7void printWakeupReason() {
8  esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
9  switch (cause) {
10    case ESP_SLEEP_WAKEUP_TIMER:    Serial.println("Zamanlayici / Timer"); break;
11    case ESP_SLEEP_WAKEUP_EXT0:     Serial.println("ext0 (tek pin / single pin)"); break;
12    case ESP_SLEEP_WAKEUP_EXT1:     Serial.println("ext1 (coklu pin / multiple pins)"); break;
13    case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Dokunmatik / Touch"); break;
14    default: Serial.printf("Ilk acilis ya da reset / Power-on or reset (%d)\n", (int)cause); break;
15  }
16}
17
18void setup() {
19  Serial.begin(115200);
20  delay(500);                       // Seri Monitör'e zaman tanı / give the Serial Monitor time
21  bootCount++;
22  Serial.printf("Uyanis sayisi / Boot count: %d\n", bootCount);
23  printWakeupReason();
24
25  // Burada sensörü oku, veriyi gönder / read the sensor and send the data here
26
27  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);   // 10 s sonra uyan / wake after 10 s
28  Serial.println("Derin uyku basliyor / Entering deep sleep");
29  Serial.flush();                   // yazı bitmeden uyuma / finish printing before sleeping
30  esp_deep_sleep_start();           // buradan sonrası çalışmaz / nothing below runs
31}
32
33void loop() {
34  // Derin uykuda loop() hiç çalışmaz / loop() never runs with deep sleep
35}

Kodun kalbi iki satırdır: esp_sleep_enable_timer_wakeup() uyanma süresini mikrosaniye cinsinden ayarlar, esp_deep_sleep_start() ise yongayı hemen uykuya gönderir; bu satırdan sonra yazdığın hiçbir şey çalışmaz. Süreyi hesaplarken ULL (64 bit) ekini unutma: 3600 * 1000000 işlemi 32 bitlik int sınırını aşar, derleyici yalnızca bir uyarı verir ve kart ya yanlış sürede uyanır ya da hiç uyanmaz. Serial.flush() gönderim tamponundaki yazıların bitmesini bekler; onsuz son satırlar yarım kalır. esp_sleep_get_wakeup_cause() ise kartın neden uyandığını söyler; ilk açılışta ya da reset sonrasında hiçbir uyku kaynağı döndürmez. Uyku süresini sayan RTC zamanlayıcısı varsayılan olarak yaklaşık 150 kHz'lik dahili bir RC osilatörüyle çalışır. Bu osilatör kristal kadar kararlı değildir ve sıcaklıkla birkaç yüzde kayabilir; saatin önemli olduğu projelerde uyanışlarda saati NTP ile eşitlemek iyi bir çözümdür.

RTC belleğinde sayaç ve ölçüm saklamak

Uyanışlar arasında bir şeyi hatırlaman gerekiyorsa değişkenin önüne RTC_DATA_ATTR yazarsın: derleyici onu ana RAM yerine derin uykuda da açık kalan 8 KB'lık RTC SLOW belleğine koyar. Sayaçlar, son ölçümler, Wi-Fi kanal bilgisi ya da son gönderilen sıcaklık gibi küçük veriler için idealdir. Ancak bu bellek kalıcı değildir: Espressif'in belgelerine göre RTC belleğindeki veriler, derin uykudan uyanma dışındaki her yeniden başlamada başlangıç değerine döner. Pil değişince, EN düğmesine basınca, yeni kod yükleyince ya da ESP.restart() çağırınca sayaç sıfırlanır. Elektrik kesintisinden sonra da korunması gereken ayarları Preferences kütüphanesiyle flaş belleğe yaz; ama bunu her uyanışta yapma, çünkü flaşın yazma ömrü sınırlıdır.

OlayNormal değişkenRTC_DATA_ATTRPreferences (flaş)
Derin uykudan uyanmaSıfırlanırKorunurKorunur
EN düğmesi ya da ESP.restart()SıfırlanırBaşlangıç değerine dönerKorunur
Pilin çıkarılması, güç kesintisiSıfırlanırSilinirKorunur
Yeni kod yüklemeSıfırlanırSilinirKorunur (flaş silinmezse)

Bu belleği akıllıca kullanarak pil ömrünü katlayabilirsin. Wi-Fi'ye bağlanmak her uyanışın en pahalı kısmıdır. Bu yüzden aşağıdaki kod her 10 dakikada bir pil gerilimini ölçer ama Wi-Fi'yi yalnızca saatte bir açar: altı ölçüm RTC belleğindeki bir dizide birikir, altıncısında hepsi birden gönderilir. Ayrıca bağlandığı modemin kanalını ve MAC adresini (BSSID) RTC belleğine kaydeder; sonraki bağlantılarda ESP32 bütün kanalları taramadan doğrudan o modeme bağlanır ve bağlantı süresi belirgin şekilde kısalır.

C++ (Arduino IDE)
1// RTC belleğinde ölçüm biriktirip saatte bir gönderme / buffer readings in RTC memory, send hourly
2#include <WiFi.h>
3
4const char* SSID = "AgAdi";                       // Wi-Fi adı / Wi-Fi name
5const char* PASS = "Sifre123";                    // Wi-Fi şifresi / Wi-Fi password
6const int BAT_PIN = 35;                           // 1M + 1M bölücünün orta noktası / divider midpoint
7const uint64_t SLEEP_US = 600ULL * 1000000ULL;    // 10 dakika / 10 minutes
8const int BATCH = 6;                              // 6 ölçümde bir gönder / send every 6 readings
9
10RTC_DATA_ATTR float readings[BATCH];              // uykuda korunan ölçümler / readings kept in sleep
11RTC_DATA_ATTR int count = 0;                      // biriken ölçüm sayısı / number of stored readings
12RTC_DATA_ATTR int32_t savedChannel = 0;           // son Wi-Fi kanalı / last Wi-Fi channel
13RTC_DATA_ATTR uint8_t savedBssid[6];              // modemin MAC adresi / access point MAC address
14
15bool connectFast() {
16  WiFi.mode(WIFI_STA);
17  if (savedChannel > 0) {
18    WiFi.begin(SSID, PASS, savedChannel, savedBssid);   // taramadan bağlan / connect without scanning
19  } else {
20    WiFi.begin(SSID, PASS);                             // ilk sefer: normal bağlantı / first time: normal connect
21  }
22  unsigned long start = millis();
23  while (WiFi.status() != WL_CONNECTED) {
24    if (millis() - start > 10000) {                     // 10 s içinde bağlanamazsa vazgeç / give up after 10 s
25      savedChannel = 0;                                 // bir dahaki sefere tara / scan next time
26      return false;
27    }
28    delay(50);
29  }
30  savedChannel = WiFi.channel();
31  memcpy(savedBssid, WiFi.BSSID(), 6);
32  return true;
33}
34
35void setup() {
36  Serial.begin(115200);
37  // Pili Wi-Fi açılmadan önce ölç / measure the battery before Wi-Fi starts
38  float v = analogReadMilliVolts(BAT_PIN) * 2 / 1000.0;   // bölücü gerilimi yarıya indirir / divider halves it
39  readings[count++] = v;
40  Serial.printf("Olcum / Reading %d: %.2f V\n", count, v);
41
42  if (count >= BATCH) {
43    if (connectFast()) {
44      for (int i = 0; i < BATCH; i++) {
45        Serial.printf("Gonder / Send: %.2f V\n", readings[i]);   // burada HTTP ya da MQTT / HTTP or MQTT here
46      }
47      count = 0;
48    } else {
49      for (int i = 1; i < BATCH; i++) readings[i - 1] = readings[i];   // en eskiyi at / drop the oldest
50      count = BATCH - 1;
51    }
52    WiFi.disconnect(true);
53    WiFi.mode(WIFI_OFF);                                // radyoyu kapat / turn the radio off
54  }
55
56  Serial.flush();
57  esp_sleep_enable_timer_wakeup(SLEEP_US);
58  esp_deep_sleep_start();
59}
60
61void loop() {
62}

Pil gerilimi, 1 MΩ + 1 MΩ'luk bir gerilim bölücüyle yarıya indirilip ADC1 kanalındaki GPIO 35'ten okunur. Bölücünün orta noktasıyla GND arasına 100 nF'lık bir kondansatör koyarsan bu kadar yüksek dirençli bir bölücüde bile ölçüm kararlı olur. Ölçümü Wi-Fi'yi açmadan önce yapmak da önemlidir, çünkü radyo çalışırken çekilen akım pil gerilimini anlık olarak düşürür. Wi-Fi bağlanamazsa en eski ölçüm atılır, diğerleri bir sonraki denemeye saklanır. Uyumadan önce WiFi.disconnect(true) ve WiFi.mode(WIFI_OFF) ile radyoyu düzgünce kapatmak Espressif'in de önerdiği yoldur. Bağlantıyı daha da hızlandırmak için WiFi.config() ile sabit IP verip DHCP beklemesini atlayabilirsin. Bölücünün hesabını gerilim bölücü, şarj devresini TP4056 şarj modülü yazısında bulabilirsin.

Buton ve PIR ile uyanma: ext0 ve ext1

Zamanlayıcının dışında ESP32'yi dış dünyadan gelen bir sinyal de uyandırabilir. Bunun iki yolu vardır ve ikisi de yalnızca RTC GPIO pinlerinde çalışır: 0, 2, 4, 12–15, 25–27 ve 32–39. ext0 tek bir pini izler ve o pin seçtiğin seviyeye (HIGH ya da LOW) geldiğinde kartı uyandırır; RTC çevre birimlerini açık tuttuğu için dahili pull-up ve pull-down dirençleri uykuda da kullanılabilir. ext1 ise bir bit maskesiyle birden fazla pini aynı anda izler. Klasik ESP32'de ext1'in iki modu vardır: ESP_EXT1_WAKEUP_ANY_HIGH seçili pinlerden herhangi biri HIGH olunca, ESP_EXT1_WAKEUP_ALL_LOW ise hepsi birden LOW olunca uyandırır. Herhangi biri LOW olunca uyandıran ANY_LOW modu yalnızca ESP32-S2, S3, C6 ve H2'de vardır. Bu yüzden klasik ESP32'de birden fazla butonla uyandırmak istiyorsan butonları 3V3'e bağlayıp her pine 10 kΩ'luk bir pull-down direnci koymalısın. Birden fazla kaynağı aynı anda da açabilirsin; örneğin hem PIR hem de saatte bir zamanlayıcı açıksa kart hangisi önce gelirse onunla uyanır.

Uyanma kaynağıFonksiyonPinlerNot
Zamanlayıcıesp_sleep_enable_timer_wakeup()Pin gerekmezSüre mikrosaniye cinsinden, 64 bit
ext0esp_sleep_enable_ext0_wakeup()Tek bir RTC GPIOHIGH ya da LOW seviyede uyanır; dokunmatik ve ULP ile birlikte kullanılamaz
ext1esp_sleep_enable_ext1_wakeup_io()Birden çok RTC GPIOANY_HIGH ya da ALL_LOW; harici direnç önerilir
DokunmatiktouchSleepWakeUpEnable()T0–T9 (10 pin)Değer eşiğin altına inince uyanır; ext0 ile birlikte kullanılamaz
ULP yardımcı işlemcisiesp_sleep_enable_ulp_wakeup()Programa göreUykuda sensör okuyabilir; ileri seviye

Örnek devrenin bağlantıları

ParçaParça piniESP32 piniNot
PIR sensörü (HC-SR501 ya da AM312)OUTGPIO 33ext0 ile uyandırır
PIR sensörüVCC / GND5V (HC-SR501) ya da 3V3 (AM312) / GNDHC-SR501 en az 4,5 V ister
Buton ABir bacak / diğer bacak3V3 / GPIO 25GPIO 25 ile GND arasına 10 kΩ pull-down
Buton BBir bacak / diğer bacak3V3 / GPIO 26GPIO 26 ile GND arasına 10 kΩ pull-down
Dokunmatik ped ya da tel–GPIO 27 (T7)Kısa tutulursa daha kararlı çalışır
LED + 220 ΩAnotGPIO 2Çoğu DevKit'te dahili mavi LED de bu pindedir
Pil bölücü (1 MΩ + 1 MΩ)Orta noktaGPIO 35Orta nokta ile GND arasına 100 nF
18650 + TP4056 + 3,3 V LDOLDO çıkışı / GND3V3 / GNDLDO çıkışına 470 µF kondansatör
Uyandırma girişi olarak GPIO 0, 2, 12 ve 15 pinlerinden kaçın. Bunlar açılış (strapping) pinleridir; reset anında bir buton ya da sensör yüzünden yanlış seviyede kalırlarsa kart programlama moduna girer ya da hiç açılmaz. Örneğin GPIO 12 açılışta HIGH kalırsa flaş gerilimi 1,8 V'a ayarlanır ve kart açılamaz. GPIO 34–39 yalnızca giriştir ve dahili pull-up ya da pull-down direnci yoktur; bu pinlerle uyandıracaksan direnci dışarıdan ekle. Kartının tam pin haritasına Pinout aracından bakabilirsin.

PIR sensörüyle uyanma kodu (ext0)

C++ (Arduino IDE)
1// PIR ile uyanma (ext0) / wake on PIR motion (ext0)
2#include "driver/rtc_io.h"
3
4const gpio_num_t PIR_PIN = GPIO_NUM_33;   // RTC GPIO olmalı / must be an RTC GPIO
5const int LED_PIN = 2;                    // uyarı LED'i / alert LED
6
7RTC_DATA_ATTR int motionCount = 0;        // toplam hareket sayısı / total motion count
8
9void setup() {
10  Serial.begin(115200);
11  rtc_gpio_deinit(PIR_PIN);               // pini yeniden normal GPIO yap / turn the pad back into a normal GPIO
12  pinMode(PIR_PIN, INPUT);
13  pinMode(LED_PIN, OUTPUT);
14
15  if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT0) {
16    motionCount++;
17    Serial.printf("Hareket! / Motion! Toplam / Total: %d\n", motionCount);
18    digitalWrite(LED_PIN, HIGH);          // burada bildirim gönderebilirsin / send a notification here
19    delay(1000);
20    digitalWrite(LED_PIN, LOW);
21  }
22
23  // PIR çıkışı LOW olana kadar bekle, yoksa hemen yeniden uyanır / wait for LOW or it wakes again at once
24  while (digitalRead(PIR_PIN) == HIGH) {
25    delay(100);
26  }
27
28  esp_sleep_enable_ext0_wakeup(PIR_PIN, 1);   // pin HIGH olunca uyan / wake when the pin goes HIGH
29  rtc_gpio_pullup_dis(PIR_PIN);
30  rtc_gpio_pulldown_en(PIR_PIN);              // boştayken LOW tut / keep it LOW while idle
31  Serial.println("Uyku / Sleep");
32  Serial.flush();
33  esp_deep_sleep_start();
34}
35
36void loop() {
37}

Kod, uyandığında önce rtc_gpio_deinit() ile pini normal GPIO'ya döndürür. ext0 ile uyandıktan sonra pin RTC modunda kalır ve bu satır olmadan digitalRead() doğru çalışmayabilir. Hareketi sayıp LED'i yaktıktan sonra PIR çıkışının LOW'a dönmesini bekler. Bu bekleme çok önemlidir: çıkış hâlâ HIGH iken uykuya geçersen kart hemen yeniden uyanır ve saniyede birkaç kez açılıp kapanan bir döngüye girer. HC-SR501'in çıkışı ayarlanan süre boyunca HIGH kalır; beklemeyi kısaltmak için modülün üzerindeki zaman potansiyometresini en aza çevir. HC-SR501 en az 4,5 V ile çalıştığından tek 18650 ile beslenen projelerde 3,3 V ile çalışabilen küçük AM312 PIR modülünü tercih et. Sensörün ayarları için PIR hareket sensörü yazısına bakabilirsin.

İki butonla uyanma kodu (ext1)

C++ (Arduino IDE)
1// İki butonla uyanma (ext1) / wake with two buttons (ext1)
2#include "driver/rtc_io.h"
3
4const gpio_num_t BTN_A = GPIO_NUM_25;     // buton A: 3V3'e, 10k pull-down / button A: to 3V3, 10k pull-down
5const gpio_num_t BTN_B = GPIO_NUM_26;     // buton B: 3V3'e, 10k pull-down / button B: to 3V3, 10k pull-down
6const uint64_t WAKE_MASK = (1ULL << BTN_A) | (1ULL << BTN_B);
7
8void setup() {
9  Serial.begin(115200);
10  rtc_gpio_deinit(BTN_A);                 // pinleri normal GPIO'ya döndür / back to normal GPIO
11  rtc_gpio_deinit(BTN_B);
12  pinMode(BTN_A, INPUT);
13  pinMode(BTN_B, INPUT);
14
15  if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT1) {
16    uint64_t pins = esp_sleep_get_ext1_wakeup_status();   // hangi pin uyandırdı? / which pin woke us?
17    if (pins & (1ULL << BTN_A)) Serial.println("Buton A: isigi ac / Button A: lights on");
18    if (pins & (1ULL << BTN_B)) Serial.println("Buton B: isigi kapat / Button B: lights off");
19  } else {
20    Serial.println("Ilk acilis / First boot");
21  }
22
23  while (digitalRead(BTN_A) == HIGH || digitalRead(BTN_B) == HIGH) {
24    delay(10);                            // butonlar bırakılana kadar bekle / wait until released
25  }
26
27  esp_sleep_enable_ext1_wakeup_io(WAKE_MASK, ESP_EXT1_WAKEUP_ANY_HIGH);  // biri HIGH olunca / any goes HIGH
28  Serial.flush();
29  esp_deep_sleep_start();
30}
31
32void loop() {
33}

ext1 uyanışında esp_sleep_get_ext1_wakeup_status() hangi pinin uyandırdığını bir bit maskesi olarak döndürür. Böylece iki butona farklı görevler verebilirsin: biri ışığı açsın, diğeri kapatsın ya da biri ölçüm göndersin, diğeri menüyü açsın. Butonlar 3V3'e bağlı ve pinler 10 kΩ ile GND'ye çekili olduğundan basılmadığında LOW, basıldığında HIGH okunur; ANY_HIGH modu da tam olarak bunu bekler. Kod uyumadan önce butonların bırakılmasını bekler, yoksa basılı duran buton kartı hemen yeniden uyandırır. ESP32 Arduino çekirdeğinin 2.x ya da 3.0.x sürümünü kullanıyorsan (bu sürümlerde _io fonksiyonu yoktur) esp_sleep_enable_ext1_wakeup_io yerine aynı parametrelerle esp_sleep_enable_ext1_wakeup yaz. Pull-down direncinin neden gerektiğini Arduino'ya buton nasıl bağlanır yazısında ayrıntılı bulabilirsin.

Dokunarak uyandırma (touch wake-up)

ESP32'nin on pini (T0–T9) kapasitif dokunmatik sensör olarak çalışır ve derin uykudayken bile parmağını algılayabilir. Pine bağlı bir tel, bakır bant ya da bir PCB pedi düğme gibi davranır; ince bir plastik ya da ahşap kapağın arkasına bile yerleştirilebilir. Klasik ESP32'de touchRead() değeri dokununca düşer: kısa bir kabloyla dokunulmamışken çoğu zaman 60–80 arası, dokununca 10–20 arası okunur. Uyanma eşiğini bu iki değerin arasına koyarsın; örnek koddaki 40 iyi bir başlangıçtır. Klasik ESP32'de birden fazla dokunmatik pini aynı anda uyandırma kaynağı yapabilirsin. ESP32-S2 ve S3'te ise yalnızca tek bir pin uyandırabilir, okunan değer dokununca yükselir ve eşik bambaşka bir ölçekte (Espressif'in örnek kodunda 5000) seçilir. Dokunmatikle uyanma ext0 ile birlikte kullanılamaz; butona da ihtiyacın varsa ext1'i seç. Pin listesi ve kalibrasyon için ESP32 dokunmatik pinler yazısına göz at.

C++ (Arduino IDE)
1// Dokunarak uyandırma: T7 = GPIO 27 / touch wake-up: T7 = GPIO 27
2#define THRESHOLD 40                      // değer bunun altına inince uyanır / wakes when the value drops below this
3
4RTC_DATA_ATTR int touchWakes = 0;
5
6void setup() {
7  Serial.begin(115200);
8  delay(500);
9  if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TOUCHPAD) {
10    touchWakes++;
11    Serial.printf("Dokunusla uyanma / Touch wake #%d\n", touchWakes);
12  }
13  // Eşiği ayarlamak için dokunmadan ve dokunarak değeri izle / watch the value untouched and touched
14  Serial.printf("T7 degeri / value: %d\n", (int)touchRead(T7));
15
16  touchSleepWakeUpEnable(T7, THRESHOLD);  // dokunmatikle uyanmayı aç / enable touch wake-up
17  Serial.flush();
18  esp_deep_sleep_start();
19}
20
21void loop() {
22}

MicroPython ile ESP32 deep sleep

ESP32'yi MicroPython ile programlıyorsan aynı işi daha kısa bir kodla yaparsın. machine.deepsleep(ms) kartı verilen milisaniye kadar uyutur, esp32.wake_on_ext0() bir pini uyandırma kaynağı yapar, machine.RTC().memory() ise uyku boyunca korunan bir bayt dizisi sunar; ESP32'de bu alan varsayılan olarak 2048 bayttır. Uyanınca main.py baştan çalışır; machine.reset_cause() ile derin uykudan uyanıp uyanmadığını, machine.wake_reason() ile neyin uyandırdığını anlarsın. Pull-up ya da pull-down ayarlanmış RTC pinleri bu ayarı uykuda da korur. MicroPython'a yeniysen MicroPython temelleri yazısından başlayabilirsin.

MicroPython
1import machine, esp32, time
2from machine import Pin
3
4rtc = machine.RTC()
5led = Pin(2, Pin.OUT)
6
7mem = rtc.memory()                            # RTC belleğini oku / read RTC memory
8count = int.from_bytes(mem, "little") if mem else 0
9
10if machine.reset_cause() == machine.DEEPSLEEP_RESET:
11    count += 1
12    if machine.wake_reason() == machine.EXT0_WAKE:
13        print("Butonla uyandi / Woken by button")
14    else:
15        print("Zamanlayiciyla uyandi / Woken by timer")
16else:
17    count = 0
18    print("Ilk acilis / First boot")
19
20rtc.memory(count.to_bytes(4, "little"))       # sayacı sakla / store the counter
21print("Uyanis / Wake:", count)
22
23led.on()                                      # kısa iş: ölç ve gönder / short task: measure and send
24time.sleep_ms(200)
25led.off()
26
27button = Pin(33, Pin.IN, Pin.PULL_DOWN)       # buton GPIO 33 ile 3V3 arasında / button between GPIO 33 and 3V3
28esp32.wake_on_ext0(button, esp32.WAKEUP_ANY_HIGH)   # basınca uyan / wake on press
29machine.deepsleep(60000)                      # 60 s uyu / sleep for 60 s

Raspberry Pi Pico'da ise ESP32'deki gibi mikroamperlik bir derin uyku yoktur. MicroPython'daki machine.lightsleep(ms) saatlerin çoğunu durdurup işlemciyi bekletir ve RAM'i korur; machine.deepsleep(ms) ise aynı uykunun ardından kartı resetler. Kartın tüketimi bu modlarda bile miliamper mertebesinde kalır. Bu yüzden Pico ile aylarca pille çalışacak bir cihaz yapmak istiyorsan TPL5110 gibi bir güç zamanlayıcısıyla kartın beslemesini ölçümler arasında tamamen kesmek daha iyi sonuç verir. Pico'nun temelleri için Raspberry Pi Pico nedir? yazısına bakabilirsin.

18650 ile aylarca çalışan sensör: pil ömrü hesabı

Uyuyup uyanan bir cihazın pil ömrünü bulmak için önce ortalama akımı hesaplarsın: Ortalama akım = (Uyanık akım × Uyanık süre + Uyku akımı × Uyku süresi) / Toplam süre. Sonra pilin kullanılabilir kapasitesini bu ortalamaya bölersin. Etiketinde 3000 mAh yazan bir 18650'nin tamamı kullanılamaz; düşük gerilim kesmesi, regülatör kaybı ve yaşlanma için yaklaşık %85'ini, yani 2550 mAh'i hesaba katmak gerçekçidir. Aşağıdaki tablo, 10 dakikada bir uyanıp Wi-Fi üzerinden veri gönderen ve bağlantı sırasında ortalama 120 mA çeken bir sensör için hesaplandı.

SenaryoUyku akımıUyanık kalmaOrtalama akımTahmini süre
DevKit kartı8 mA3 s, 120 mA8,56 mA≈12 gün
DevKit kartı, hızlı bağlantı8 mA1 s, 120 mA8,19 mA≈13 gün
Çıplak modül + MCP1700 + 1 MΩ bölücü15 µA3 s, 120 mA0,61 mA≈173 gün (5,7 ay)
Çıplak modül, hızlı bağlantı15 µA1 s, 120 mA0,215 mA≈494 gün (16 ay)
Çıplak modül, saatte bir toplu gönderim15 µASaatte 1 s Wi-Fi (120 mA) + 5 × 0,3 s ölçüm (40 mA)0,065 mATeoride ≈4,5 yıl

Tablodan çıkan sonuç açık: geliştirme kartında uyanık süreyi kısaltmak neredeyse hiçbir şey değiştirmez, çünkü pili asıl bitiren uykudaki 8 mA'dir. Uyku akımı mikroamperlere indiğinde ise denge tersine döner ve uyanık geçen her saniye belirleyici olur: Wi-Fi bağlantısını 3 saniyeden 1 saniyeye indirmek pil ömrünü neredeyse üç katına çıkarır. Ortalama akım 0,1 mA'in altına indiğinde artık pilin kendi kendine boşalması devreye girer. Bir Li-ion hücre ayda yaklaşık %2–3 kapasite kaybettiği için 4,5 yıllık teorik değer pratikte 2 yıl civarına iner. Kendi değerlerinle hesap yapmak için pil ömrü hesaplayıcısını kullanabilir, mAh ve Wh kavramlarını mAh ne demek yazısında okuyabilirsin.

  • Doğru kartı seç: USB yongası ve güç LED'i olmayan kartlar ya da çıplak ESP32 modülü uykuda mikroamper çeker.
  • Regülatörü değiştir: AMS1117 yerine boşta akımı birkaç mikroamper olan bir LDO kullan.
  • Sensörü yalnızca ölçümde besle: Birkaç mA çeken sensörleri doğrudan bir GPIO'dan, daha büyük yükleri P kanallı bir MOSFET'ten besle; MOSFET'in kapısına bir pull-up direnci koy ki uykuda kapalı kalsın. Ayrıntılar Arduino MOSFET kullanımı yazısında.
  • Wi-Fi'yi seyrek aç: Ölçümleri RTC belleğinde biriktir ve toplu gönder; yakındaki başka bir ESP32'ye veri yollayacaksan ESP-NOW modeme bağlanmadan çok daha kısa sürede gönderir.
  • Bağlantıyı hızlandır: Sabit IP, kayıtlı kanal ve BSSID ile Wi-Fi bağlantısı çoğu zaman 1 saniyenin altına iner.
  • Gereksiz beklemeleri kaldır: Bitmiş projede Seri Monitör çıktısını ve uzun delay() satırlarını sil; uyanık geçen her milisaniye pilden gider.
  • Bölücüyü ve LED'leri unutma: Sürekli bağlı bir 100 kΩ + 100 kΩ bölücü, uyuyan ESP32'nin iki katı akım çeker.

ESP32 deep sleep ile proje fikirleri

  • Pilli hava istasyonu: BME280 ile sıcaklık, nem ve basıncı 10 dakikada bir ölç, saatte bir MQTT ile Home Assistant'a gönder.
  • Bahçe nem sensörü: Saatte bir uyanıp toprak nemini ölç, toprak kuruduğunda telefonuna haber ver.
  • Kapı ve pencere alarmı: Kapı açılınca bir reed röle ESP32'yi ext0 ile uyandırsın, bir Telegram botu sana mesaj göndersin.
  • Pille çalışan güvenlik sensörü: PIR sensörü hareket algıladığında uyanıp bildirim gönderen, geri kalan zamanda aylarca uyuyan bir cihaz yap.
  • Dokunmatik kapı zili: Ahşap bir panelin arkasına bakır bant yapıştır; dokununca ESP32 uyanıp ESP-NOW ile içerideki zile sinyal göndersin.
  • Pilli sıcaklık kaydedici: Su geçirmez bir DS18B20 ile buzdolabının ya da akvaryumun sıcaklığını ölç, değerleri RTC belleğinde biriktirip günde birkaç kez gönder.

Sık yapılan hatalar ve çözümleri

BelirtiNedenÇözüm
Kart uyur uyumaz yeniden uyanıyorUyandırma pini hâlâ aktif (PIR HIGH, buton basılı) ya da pin boştaUyumadan önce pinin pasif seviyeye dönmesini bekle, pull-down ya da pull-up direnci ekle
Kart beklenen sürede uyanmıyorSüre hesabında 32 bit taşma (3600 * 1000000)Sabitlere ULL ekle: 3600ULL * 1000000ULL
Sayaç her seferinde 1'den başlıyorDeğişken RTC_DATA_ATTR değil ya da kart resetlendiRTC_DATA_ATTR ekle; kalıcı veri için Preferences kullan
Uykuda 5–15 mA ölçülüyorRegülatör, güç LED'i, USB yongası, bölücü ya da sensörlerDüşük tüketimli kart ya da çıplak modül, düşük boşta akımlı LDO
Seri Monitör'de son satırlar yarımYazı tamponu boşalmadan uykuya geçildiesp_deep_sleep_start() öncesinde Serial.flush() çağır
Uyandıktan sonra digitalRead() yanlış okuyorUyandıran pin RTC modunda kaldıPini kullanmadan önce rtc_gpio_deinit() çağır
GPIO 34–39 ile buton uyandırmıyorBu pinlerde dahili pull direnci yok, pin boştaDışarıdan 10 kΩ direnç ekle
Uykudayken kod yüklenemiyorKartta otomatik reset devresi yok; S3 ve C3'te yerleşik USB portu uykuda kayboluyorBOOT'u basılı tutup EN (RESET) düğmesine bas-bırak, sonra yüklemeyi başlat
Uykuya geçince röle ya da LED kendiliğinden değişiyorDerin uykuda dijital pinler boşta (yüksek empedans) kalırPull direnci kullan ya da rtc_gpio_hold_en() ile pinin seviyesini koru
Geliştirme sırasında setup()'ın başına geçici olarak 5 saniyelik bir bekleme ya da bir butona basılıysa uyumama koşulu koy. Böylece kart sürekli uyurken bile Seri Monitör'ü açmaya ve yeni kod yüklemeye zaman bulursun; proje bitince bu satırı silmeyi unutma. Pille çalışırken kart arada bir kendiliğinden resetleniyorsa sorun büyük ihtimalle Wi-Fi'nin akım tepelerindedir; çözümler ESP32 brownout hatası yazısında.

ESP32 deep sleep, aynı kodu pille günlerce değil aylarca çalıştırmanın anahtarıdır: işi kısa tut, uyandırma kaynağını doğru seç, uyanışlar arasında gereken küçük verileri RTC belleğinde sakla ve kartın kendi tüketimini unutma. ESP32'nin temellerine dönmek istersen ESP32 nedir? yazısı iyi bir başlangıçtır. BlueGrays uygulamasındaki ESP32 Deep Sleep — Pil Tasarrufu (OLED + RTC RAM Sayaç) projesinde bu yazıdaki zamanlayıcı ve RTC sayaç mantığını OLED ekranlı bir devrede, adım adım devre şeması ve hazır koduyla deneyebilirsin.

Sıkça sorulan sorular

ESP32 deep sleep modunda ne kadar akım çeker?

Espressif'in veri sayfasına göre ESP32 yongası derin uykuda, RTC zamanlayıcısı ve RTC belleği açıkken yaklaşık 10 µA çeker; hibernasyon modunda bu değer 5 µA'e iner. Ancak DevKit gibi geliştirme kartlarında regülatör, güç LED'i ve USB-seri yonga yüzünden uyku akımı çoğu zaman 5–15 mA olur.

ESP32 derin uykudan nasıl uyandırılır?

Beş yolu vardır: RTC zamanlayıcısı, tek bir RTC pini (ext0), birden çok RTC pini (ext1), dokunmatik pinler ve ULP yardımcı işlemcisi. Uyandırma kaynağını esp_deep_sleep_start() çağrısından önce ayarlarsın ve birden fazlasını aynı anda açabilirsin; yalnızca ext0 ile dokunmatik uyanma birlikte kullanılamaz.

ESP32 deep sleep'te değişkenler silinir mi?

Evet, normal değişkenler silinir, çünkü derin uykudan uyanmak bir yeniden başlatmadır ve setup() baştan çalışır. Önüne RTC_DATA_ATTR yazdığın değişkenler RTC belleğinde tutulur ve uyanışlar arasında korunur; ama güç kesilince, EN düğmesine basınca ya da yeni kod yükleyince başlangıç değerine döner.

ESP32 bir 18650 pille ne kadar çalışır?

Kart ve kullanım şekline göre bir günden bir yılın üzerine kadar değişir. Sürekli Wi-Fi'ye bağlı bir DevKit 3000 mAh'lik bir 18650 ile yalnızca 1–2 gün, 10 dakikada bir uyanan bir DevKit yaklaşık 12 gün dayanır. Aynı işi yapan, uykuda 15 µA çeken düşük tüketimli bir devre ise bağlantı süresine göre 5 ila 16 ay çalışır.

ESP32 light sleep ile deep sleep arasındaki fark nedir?

Hafif uykuda (light sleep) işlemci duraklatılır ama RAM korunur; kart uyanınca program kaldığı satırdan devam eder ve yonga yaklaşık 0,8 mA çeker. Derin uykuda RAM'in gücü de kesilir, tüketim 10 µA'e iner ama uyanışta program baştan başlar. Saniyeler süren beklemeler için hafif uyku, dakikalar ya da saatler süren beklemeler için derin uyku daha uygundur.

Derin uykudaki ESP32'ye kod nasıl yüklenir?

Otomatik reset devresi olan kartlarda yükleme genellikle sorunsuz başlar, çünkü yükleyici EN pinini kullanarak yongayı resetler. Başlamazsa kartın üzerindeki BOOT düğmesini basılı tutup EN (RESET) düğmesine bas ve bırak, ardından yüklemeyi başlat. ESP32-S3 ve C3 gibi yerleşik USB'li kartlarda port uykuda kaybolduğu için bu yöntem çoğu zaman şarttır.

Tüm projeleri gör
ESP32 ile LED Yakma
#103Başlangıç

ESP32 ile LED Yakma

ESP32 ile temel GPIO çıkışı kullanımını öğretir. Bir LED'i dijital pinden açıp kapatarak yanıp sönme efekti elde ederiz. Arduino UNO'daki klasik blink projesinin ESP32 versiyonu; Arduino ortamındaki temel blink komutları aynıdır, ancak ESP32'nin pin yerleşimi ve 3,3 V GPIO seviyeleri Arduino UNO'dan farklıdır.

4.7(37)
99
ESP32 Buton ile LED Kontrol (Push)
#104Başlangıç

ESP32 Buton ile LED Kontrol (Push)

Butona basılı tutulduğunda LED yanar, bırakıldığında söner. ESP32'nin dijital input pin'i ve dahili pull-up direncinin nasıl kullanıldığını gösterir. INPUT_PULLUP modu sayesinde harici direnç gerekmez.

4.6(36)
55
ESP32 Deep Sleep — Pil Tasarrufu (OLED + RTC RAM Sayaç)
#135İleri
Premium

ESP32 Deep Sleep — Pil Tasarrufu (OLED + RTC RAM Sayaç)

ESP32'nin Deep Sleep modu, CPU ve çoğu çevre birimini kapatarak akım tüketimini ~10µA seviyesine düşürür ve pille çalışan IoT cihazları için kritik öneme sahiptir. Bu projede üç farklı uyandırma kaynağını kullanıyoruz: zamanlayıcı (timer, 15sn), harici pin (EXT0 — buton GPIO 33) ve touch (T0/GPIO 4). RTC_DATA_ATTR ile işaretlenen değişkenler deep sleep boyunca korunur — boot sayacı, timer wake sayacı ve buton wake sayacı kalıcı olarak izlenir. SSD1306 OLED ekranda her uyanışta wake reason, say

4.3(10)
16
ESP32 Hareket Alarm Sistemi (PIR + Buzzer + LED + Telegram)
#145İleri
Premium

ESP32 Hareket Alarm Sistemi (PIR + Buzzer + LED + Telegram)

PIR sensörü hareket algıladığında buzzer ve LED'i aktif eden, aynı anda Telegram üzerinden sahibine anlık bildirim gönderen akıllı bir güvenlik alarm sistemidir. Tekrarlayan alarmların sıklığını sınırlamak için 30 saniyelik cooldown (bekleme süresi) mekanizması vardır; bu mekanizma PIR sensörünün yanlış algılamalarını doğrulamaz veya ortadan kaldırmaz. Ev güvenliği, garaj izleme, depo veya çalışma odası gibi alanlarda kullanılabilir. Telegram entegrasyonu sayesinde nerede olursanız olun anında h

0.0(0)
9
ESP32 PIR Hareket Sensörü ile Otomatik Aydınlatma
#121Orta
Premium

ESP32 PIR Hareket Sensörü ile Otomatik Aydınlatma

Bu projede HC-SR501 PIR hareket sensörü ile odaya giren kişiyi algılayıp LED'i otomatik olarak yakacağız. LED'in açık kalma süresini millis() ile izleyeceğiz; sensör HIGH okundukça son hareket zamanı yenilenecek ve son HIGH okumasından en az 10 saniye sonra LED sönecek. Mevcut kod ayrıca her döngüde delay(50) ile 50 ms beklediğinden uygulama döngüsü tamamen bloklamayan bir yapıda değildir. Gerçek hayatta merdiven, koridor, banyo veya dolap içi aydınlatmalarda kullanılabilir.

4.4(24)
38
ESP32 DHT22 Sıcaklık ve Nem (LCD Ekranlı)
#117Orta

ESP32 DHT22 Sıcaklık ve Nem (LCD Ekranlı)

DHT22 sensörü ile ortam sıcaklığını ve nem oranını ölçüp 16x2 I2C LCD ekranda gerçek zamanlı olarak gösteren bir projedir. Adafruit DHT kütüphanesi kullanılarak tek kablo (one-wire) protokolü ile sensörden veri okunur. Bu proje, IoT hava istasyonu, akıllı ev otomasyonu veya seralarda ortam takip sistemlerinin temelini oluşturur. ESP32'nin GPIO 4 pini üzerinden DHT22 ile haberleşme sağlanır.

4.8(38)
56
ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)
#144İleri
Premium

ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)

ESP32 ile zamanlı sıcaklık ve nem kayıt sistemi kur! Bu projede DHT22 sensörü ile dakikada bir sıcaklık/nem okuyup DS1307 RTC modülünden aldığın gerçek zaman etiketiyle microSD karta CSV formatında kaydediyoruz. OLED ekranda büyük font ile son sıcaklık değeri, nem yüzdesi, timestamp ve toplam kayıt sayısı canlı gösterilir. SD kart üzerindeki /temp_log.csv dosyası Excel/Google Sheets/Python pandas ile açılıp analiz edilebilir — sera monitörü, ev/oda sıcaklık takibi, laboratuvar veri toplama,

4.7(7)
12