Macademia'nın robotik ve mühendislik programı · ücretsiz seviye tespiti ve kişisel öğrenme yolu

8. ünite / 10

Güç, derin uyku ve kablosuz güncelleme (OTA)

Pil ömrünü ortalama akımla hesapla, derin uyku ve RTC belleğiyle aylarca çalış; A/B bölümlü OTA ile sahadaki cihazı güvenle güncelle.

Bu ünitenin sonunda

  • ESP32 güç kiplerinin akımlarını karşılaştırıp ortalama akım ve pil ömrünü hesaplamak
  • Derin uykuda RTC belleğini ve zamanlayıcı/ext0 uyanma kaynaklarını kullanmak
  • DevKit kartının uyku akımını neden bozduğunu açıklamak
  • A/B bölümlü OTA'nın indirme, doğrulama, öz sınama ve geri dönüş adımlarını sıralamak

Ders notları

Prize bağlı bir cihazda güç sorun değildir; pille çalışan bir sera sensöründe ise tasarımın merkezindedir. ESP32 Wi-Fi ile yayın yaparken 100–160 mA çeker, derin uykuda yalın modül yaklaşık 10 µA. Aradaki fark dört kattan fazla değil, on bin kattır.

Güç kipleri

  • Sürekli açık: Wi-Fi bağlı, yaklaşık 95 mA ortalama. 2000 mAh pil bir günden az dayanır.
  • Modem uykusu: CPU çalışır, radyo DTIM aralıklarında uyur; 20 mA civarı.
  • Hafif uyku: CPU durur, RAM korunur, uyanış hızlıdır; yüzlerce µA.
  • Derin uyku: yalnız RTC çalışır; uyanış bir yeniden başlamadır. RTC_DATA_ATTR ile işaretli değişkenler korunur.
I_ort = (I_uyanık · t_uyanık + I_uyku · (T − t_uyanık)) / T    ömür = kapasite · 0,8 / I_ort

Örnek: 1,2 s boyunca 120 mA, 60 s aralık, 10 µA uyku: ortalama yaklaşık 2,4 mA; 2500 mAh 18650 ile yaklaşık 35 gün. Aralığı 5 dakikaya çıkarmak ömrü beş kat artırır. Ama dikkat: DevKit kartındaki AMS1117 regülatörü ve USB-seri çipi uykuda bile birkaç mA çeker; aynı hesap birkaç güne iner. Pil projesinde yalın modül ya da düşük sükunet akımlı regülatör seçilir.

Pil tarafı

18650 Li-ion ya da LiPo hücre TP4056 korumalı şarj modülüyle doldurulur; koruma devresi aşırı deşarjı keser. Gerilimden kalan yüzdeyi tahmin etmek kabadır; MAX17048 yakıt göstergesi I²C ile yüzdeyi verir. Pil azalınca daha seyrek uyanmak basit ve etkili bir stratejidir.

OTA: kablosuz güncelleme

Sahadaki yüz cihaza USB ile gidilmez. ESP32 flaşında iki uygulama bölümü vardır (ota_0, ota_1). Yeni yazılım çalışmayan bölüme indirilir, özeti ve imzası doğrulanır, önyükleme bölümü değiştirilir, cihaz yeniden başlar. Yeni sürüm "beklemede" açılır: kendi sınamasını geçerse esp_ota_mark_app_valid_cancel_rollback() ile geçerli işaretlenir; geçemezse ya da çökerse bir sonraki açılışta eski bölüme dönülür. ArduinoOTA yerel ağda geliştirme için, HTTPUpdate ise sunucudan toplu güncelleme için kullanılır.

Simülasyonlar

Güç bütçesi: derin uyku ve pil ömrü

Sürekli açık, modem uykusu, hafif uyku ve derin uyku kiplerini karşılaştır. Uyanma aralığı, uyanık kalma süresi, pil kapasitesi ve kartın uyku akımıyla ortalama akımı ve pil ömrünü hesapla.

Kip başına pil ömrü (gün, aynı aralık ve pil)açıkmodemhafifderinDevKit176.90
Derin uyku (yalın modül) Ortalama akım 0,490 mA → pil ömrü ≈ 177 gün (%80 kullanılabilir kapasite)
I = (Iawake · tawake + Isleep · tsleep) / T
Uyanık 120 mA, uyku 10 µA

OTA güncelleme: A/B bölümleri ve geri dönüş

Yeni yazılımı çalışmayan bölüme indir, doğrula, yeniden başlat. Kendi sınamasını geçemeyen sürümün eski bölüme geri döndüğünü ve geçersiz olayların durumu değiştirmediğini adım adım izle.

ota_0 (A)
v1.4.0
çalışıyorönyükleme
ota_1 (B)
v1.3.2
Aşama: boşta · gelen v1.5.0
  1. –"Güncellemeyi başlat"a bas.

Kod

Arduino C++: derin uyku, RTC belleği ve uyanma kaynağı
#include <WiFi.h>
#include "esp_sleep.h"

RTC_DATA_ATTR uint32_t bootCount = 0;   // derin uykuda korunur (RTC yavaş bellek)
RTC_DATA_ATTR float lastTemp = NAN;     // değişince bildir için son değer
const uint64_t SLEEP_US = 5ULL * 60 * 1000000;  // 5 dakika

void setup() {
  bootCount++;
  esp_sleep_wakeup_cause_t why = esp_sleep_get_wakeup_cause();
  if (why == ESP_SLEEP_WAKEUP_EXT0) Serial.println("button");  // düğmeyle uyandı
  float t = 23.4;                        // sensörü oku (kısa tut)
  if (isnan(lastTemp) || fabs(t - lastTemp) >= 0.3 || bootCount % 12 == 0) {
    WiFi.begin();                        // yalnız gerekince Wi-Fi aç: en pahalı adım
    // ... bağlan, yayımla, bağlantıyı düzgün kapat
    lastTemp = t;
  }
  esp_sleep_enable_timer_wakeup(SLEEP_US);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0);   // GPIO33 LOW olunca uyan
  esp_deep_sleep_start();                // buradan sonrası çalışmaz: uyanış = yeniden başlama
}

void loop() {}
Arduino C++: HTTPUpdate ile OTA ve geri dönüş onayı
#include <WiFi.h>
#include <HTTPUpdate.h>
#include "esp_ota_ops.h"

bool selfTest() {
  // Sensör cevap veriyor mu, broker'a bağlanabiliyor mu?
  return WiFi.status() == WL_CONNECTED;
}

void setup() {
  WiFi.begin();
  while (WiFi.status() != WL_CONNECTED) delay(200);
  if (selfTest()) esp_ota_mark_app_valid_cancel_rollback();  // yeni sürüm geçerli
  else esp_ota_mark_app_invalid_rollback_and_reboot();        // eski bölüme dön
}

void checkUpdate() {
  WiFiClientSecure tls;
  tls.setCACert(OTA_CA_PEM);             // sunucuyu doğrula: sahte güncelleme yok
  t_httpUpdate_return r = httpUpdate.update(tls, "https://ota.example.com/sera/firmware.bin");
  if (r == HTTP_UPDATE_FAILED) Serial.println(httpUpdate.getLastErrorString());
  // Başarılıysa kütüphane yeniden başlatır; yeni sürüm "beklemede" açılır
}

void loop() {}
MicroPython: MAX17048 ile pil yüzdesi ve derin uyku
from machine import I2C, Pin, deepsleep
import network, time

i2c = I2C(0, scl=Pin(22), sda=Pin(21))
raw = i2c.readfrom_mem(0x36, 0x04, 2)       # SOC yazmacı: yüksek bayt yüzde
soc = raw[0] + raw[1] / 256
print("pil %", round(soc, 1))
if soc < 15:
    sure_ms = 30 * 60 * 1000                # pil azsa daha seyrek uyan
else:
    sure_ms = 5 * 60 * 1000
wlan = network.WLAN(network.STA_IF)
wlan.active(False)                          # uyumadan önce radyoyu kapat
deepsleep(sure_ms)

Kendin dene

Güç simülasyonunda aynı 60 s aralıkta dört kipi karşılaştır ve pil ömürlerini not et. Derin uykuda kart seçimini "DevKit" yap: ömür kaç kat düştü? Aralığı 5 dakikaya çıkar ve uyanık süreyi 3 s'ye uzat (yavaş Wi-Fi). OTA simülasyonunda başarılı bir güncellemeyi sonuna kadar götür; sonra yeni sürümde öz sınamayı başarısız yap ve geri dönüşü izle. Gerçek kartta derin uyku kodunu yükle ve multimetreyle uyku akımını ölç.

Sık yapılan hatalar

  • Pil ömrünü yalın modülün 10 µA'sıyla hesaplayıp DevKit kartı kullanmak: regülatör ve USB çipi mA düzeyinde çeker.
  • Derin uyku sonrası loop()'un devam edeceğini sanmak: uyanış yeniden başlamadır, setup() baştan çalışır.
  • Uyanınca her seferinde Wi-Fi'ye bağlanmak: değişim yoksa yayını atlamak en büyük tasarruftur.
  • OTA'da sunucu sertifikasını doğrulamamak: araya giren biri kötü amaçlı yazılım yükleyebilir.
  • Yeni sürümü öz sınama yapmadan geçerli işaretlemek: hatalı sürümde geri dönüş şansı kaybolur.

Yazılım mühendisliği bağlantısı

OTA bir sürüm yönetimi sorunudur: hangi cihazda hangi sürüm var, güncelleme nasıl kademeli açılır?

  • Önce cihazların küçük bir kısmına (kanarya) dağıt, hata oranını izle, sonra herkese aç.
  • Yazılım sürümünü telemetriye ekle ("fw":"1.5.0"); bir hata bildiriminde ilk soru "hangi sürüm?" olur.

Kendini sına

  1. ESP32 derin uykudan uyanınca ne olur?

  2. Uyanık 1,2 s × 120 mA, uyku 10 µA, aralık 60 s. Ortalama akım yaklaşık ne kadardır?

  3. Derin uykuda olması gereken 10 µA yerine kart 6 mA çekiyor. En olası neden?

  4. A/B OTA'da yeni sürüm açıldı ama öz sınamayı geçemedi. Doğru sonuç hangisi?

Parçalar ve ilgili sayfalar

Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç