Rehberler · 11 dk okuma

ESP32 OTA Güncelleme: Kablosuz Kod Yükleme Rehberi (ArduinoOTA)

ESP32 OTA ile kodu USB kablosu olmadan Wi-Fi üzerinden yükle: ArduinoOTA ağ portu, ElegantOTA web sayfası, parola, bölüm tablosu ve kopan bağlantı.

ESP32 OTA (Over-The-Air, "havadan" güncelleme), kartına yeni kodu USB kablosu takmadan, Wi-Fi üzerinden yüklemektir. Tavana monte ettiğin bir sensör, bahçedeki sulama kontrolcüsü ya da elektrik panosunun içine yerleştirdiğin bir röle kartı düşün: her küçük düzeltme için merdiven kurup kartı söküp bilgisayara bağlamak yerine, Arduino IDE'den ya da tarayıcıdan birkaç saniyede yeni sürümü gönderirsin. Kart, yeni programı arka planda belleğine yazar, doğrular ve kendini yeniden başlatır.

Bu rehberde OTA'nın ESP32'nin içinde nasıl çalıştığını, üç farklı yöntemi (Arduino IDE için ArduinoOTA, tarayıcı için ElegantOTA, sunucudan çekmek için HTTPUpdate), doğru bölüm tablosunu (partition scheme) seçmeyi, parola korumasını, yükleme yarıda kesilirse ne olduğunu ve OTA özelliğini bir sonraki kodda kaybetmemenin yollarını adım adım öğreneceksin. Tüm kodlar ESP32 Arduino çekirdeğiyle derlenmiş ve denenmiştir.

ESP32 geliştirme kartı ile OTA kablosuz kod yükleme
ESP32 geliştirme kartı: ilk OTA kodunu bir kez USB ile yükledikten sonra sonraki tüm güncellemeleri Wi-Fi üzerinden gönderebilirsin.

ESP32 OTA nedir, nasıl çalışır?

ESP32'nin flash belleği tek parça değildir; bölüm tablosu adı verilen bir haritayla parçalara ayrılır. OTA destekleyen bir bölüm tablosunda program için iki eş alan bulunur: app0 (ota_0) ve app1 (ota_1). Kart bunlardan birinde çalışırken yeni program diğerine yazılır. Küçük bir otadata bölümü de bir sonraki açılışta hangi alanın çalıştırılacağını tutar. Bu sayede yükleme sırasında çalışan programa hiç dokunulmaz; yeni kod tamamen yazılıp doğrulanmadan kart eski programdan vazgeçmez.

  1. Yeni program (derlenmiş .bin dosyası) Wi-Fi üzerinden parça parça karta gelir.
  2. ESP32 her parçayı o an kullanılmayan program bölümüne yazar; çalışan kod bu sırada görevine devam eder.
  3. Dosyanın tamamı gelince görüntünün başlığı ve sağlama değeri kontrol edilir; bozuk ya da eksik bir dosya kabul edilmez.
  4. Doğrulama başarılıysa otadata güncellenir: bir sonraki açılışta yeni bölüm çalışacaktır.
  5. Kart kendini yeniden başlatır ve yeni programla açılır. Bir sonraki güncelleme bu kez diğer bölüme yazılır; iki alan sırayla kullanılır.
YöntemKodu nereden gönderirsin?En uygun olduğu durumEk kütüphane
ArduinoOTAArduino IDE'deki ağ portundanMasanda geliştirme yaparken, aynı ağdaykenYok (çekirdekle gelir)
ElegantOTATarayıcıdaki /update sayfasından .bin seçerekIDE'si olmayan birine güncelleme yaptırmak, telefondan yüklemeElegantOTA
HTTPUpdateKart, bir sunucudaki .bin dosyasını kendisi indirirÇok sayıda cihaz, uzaktaki cihazlar, otomatik güncellemeYok (çekirdekle gelir)

Bölüm tablosu (partition scheme) ve flash boyutu

OTA'nın en çok gözden kaçan şartı budur: yeni programı yazacak ikinci bir boş alan olmalıdır. Bu yüzden OTA ile yükleyebileceğin en büyük program, flash belleğin yarısından bile küçüktür. Bölüm tablosunu Arduino IDE'de Araçlar > Partition Scheme menüsünden seçersin. Yaygın 4 MB flash'lı ESP32 DevKit kartlarında (ESP32 Dev Module) seçenekler şunlardır:

Partition SchemeProgram alanıOTADosya sistemi (SPIFFS/LittleFS)
Default 4MB with spiffs2 × 1,25 MB (1.310.720 bayt)Var1,375 MB
Minimal SPIFFS (1.9MB APP with OTA)2 × 1,875 MB (1.966.080 bayt)Var128 KB
No OTA (2MB APP/2MB SPIFFS)1 × 2 MBYok1,875 MB
Huge APP (3MB No OTA/1MB SPIFFS)1 × 3 MBYok896 KB
Minimal (1.3MB APP/700KB SPIFFS)1 × 1,25 MB (2 MB flash'lı kartlar için)Yok640 KB
Bluetooth ve Wi-Fi'ı birlikte kullanan büyük bir program "Sketch too big" hatası verdiğinde çoğu kişi Huge APP seçer. Bu seçimde ikinci program alanı yoktur; kod USB ile sorunsuz yüklenir ama OTA "Not Enough Space" ya da "Begin Failed" hatasıyla başlamaz. OTA istiyorsan Minimal SPIFFS (1.9MB APP with OTA) seç.

Programının ne kadar yer kapladığını derleme çıktısında görürsün: Wi-Fi ve ArduinoOTA içeren ilk örnek kodumuz "Sketch uses 758685 bytes (57%) ... Maximum is 1310720 bytes" satırını yazdırır. Buradaki üst sınır, seçtiğin tablodaki tek bir program alanının boyutudur. Kullanım %90'ı geçiyorsa, yakında Minimal SPIFFS'e geçmen gerekeceğini bil. Bir kez önemli bir kural daha: bölüm tablosu OTA ile değiştirilemez. Tabloyu değiştirdiysen o yüklemeyi USB ile yapmalısın; sonraki OTA'lar yeni tabloyla çalışır. 8 MB ve 16 MB flash'lı kartlarda (birçok ESP32-S3 modeli gibi) Flash Size menüsünden doğru boyutu seçersen çok daha geniş OTA alanları kullanabilirsin.

Kartının gerçekte hangi bölümden çalıştığını ve OTA için ne kadar yer kaldığını görmek istersen aşağıdaki küçük kodu yükle. Bu kod herhangi bir kütüphane gerektirmez ve ESP-IDF'in OTA fonksiyonlarını doğrudan kullanır:

C++ (Arduino IDE)
1#include <esp_ota_ops.h>
2
3void setup() {
4  Serial.begin(115200);
5  delay(1000);
6  const esp_partition_t* running = esp_ota_get_running_partition();
7  const esp_partition_t* next = esp_ota_get_next_update_partition(NULL);
8
9  Serial.printf("Flash boyutu / Flash size: %u KB\n", ESP.getFlashChipSize() / 1024);
10  Serial.printf("Program boyutu / Sketch size: %u KB\n", ESP.getSketchSize() / 1024);
11  Serial.printf("OTA icin bos alan / Free space for OTA: %u KB\n", ESP.getFreeSketchSpace() / 1024);
12  Serial.printf("Calisan bolum / Running partition: %s (0x%06x)\n", running->label, running->address);
13  if (next != NULL) {
14    Serial.printf("Siradaki OTA bolumu / Next OTA partition: %s (0x%06x)\n", next->label, next->address);
15  } else {
16    Serial.println("OTA bolumu yok: bolum tablosunu degistir / No OTA partition: change the partition scheme");
17  }
18}
19
20void loop() {
21}

Varsayılan tabloda ilk USB yüklemesinden sonra çıktı "Running partition: app0 (0x010000)" ve "Next OTA partition: app1 (0x150000)" olur. Bir OTA güncellemesinden sonra kodu tekrar çalıştırırsan bu kez app1'de çalıştığını görürsün. ESP.getFreeSketchSpace() değeri, OTA ile yükleyebileceğin en büyük programın boyutunu verir; yeni .bin dosyan bundan büyükse güncelleme başlamaz.

Yöntem 1: ArduinoOTA ile Arduino IDE'den kablosuz yükleme

ArduinoOTA kütüphanesi ESP32 çekirdeğiyle birlikte gelir, ayrıca kurman gerekmez. Kart ağa bağlandıktan sonra kendini mDNS ile duyurur; Arduino IDE bunu görür ve Port menüsüne bir ağ portu ekler. Yükle tuşuna bastığında IDE, programı USB yerine bu ağ portundan gönderir. ESP32'de OTA hizmeti varsayılan olarak 3232 numaralı portu dinler. Aşağıdaki kod Wi-Fi'a bağlanır, OTA'yı parolayla başlatır ve kanıt olarak dahili LED'i yakıp söndürür:

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <ArduinoOTA.h>
3
4const char* WIFI_SSID = "AgAdi";          // Wi-Fi adın / your Wi-Fi name
5const char* WIFI_PASS = "AgSifresi";      // Wi-Fi şifren / your Wi-Fi password
6const int LED_PIN = 2;                    // çoğu DevKit'te dahili LED / onboard LED on most DevKits
7
8unsigned long lastBlink = 0;
9
10void setup() {
11  Serial.begin(115200);
12  pinMode(LED_PIN, OUTPUT);
13
14  WiFi.mode(WIFI_STA);
15  WiFi.begin(WIFI_SSID, WIFI_PASS);
16  while (WiFi.status() != WL_CONNECTED) {   // bağlanana kadar bekle / wait until connected
17    delay(500);
18    Serial.print(".");
19  }
20  Serial.println();
21  Serial.print("IP: ");
22  Serial.println(WiFi.localIP());
23
24  ArduinoOTA.setHostname("bluegrays-esp32");  // IDE'de görünen ad / name shown in the IDE
25  ArduinoOTA.setPassword("ota1234");          // yükleme parolası / upload password
26
27  ArduinoOTA.onStart([]() {
28    // Güncelleme başlıyor: motorları, röleleri güvenli konuma al / update starting: put motors and relays in a safe state
29    String type = (ArduinoOTA.getCommand() == U_FLASH) ? "program" : "dosya sistemi / filesystem";
30    Serial.println("OTA basladi / started: " + type);
31  });
32  ArduinoOTA.onEnd([]() {
33    Serial.println("\nOTA bitti, yeniden baslatiliyor / done, rebooting");
34  });
35  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
36    Serial.printf("Ilerleme / Progress: %u%%\r", progress * 100 / total);
37  });
38  ArduinoOTA.onError([](ota_error_t error) {
39    Serial.printf("Hata / Error[%u]: ", error);
40    if (error == OTA_AUTH_ERROR) Serial.println("parola / auth failed");
41    else if (error == OTA_BEGIN_ERROR) Serial.println("baslatilamadi, yer yok / begin failed, no space");
42    else if (error == OTA_CONNECT_ERROR) Serial.println("baglanti / connect failed");
43    else if (error == OTA_RECEIVE_ERROR) Serial.println("veri alinamadi / receive failed");
44    else if (error == OTA_END_ERROR) Serial.println("bitirilemedi / end failed");
45  });
46
47  ArduinoOTA.begin();                         // OTA hizmetini başlat / start the OTA service
48}
49
50void loop() {
51  ArduinoOTA.handle();                        // her turda çağır, unutma / call on every pass, never forget
52
53  // delay() yerine millis(): OTA isteklerini kaçırmamak için / millis() instead of delay() so OTA requests aren't missed
54  if (millis() - lastBlink >= 500) {
55    lastBlink = millis();
56    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
57  }
58}
SatırNe işe yarar?
ArduinoOTA.setHostname("bluegrays-esp32")IDE'nin Port listesinde ve ağda görünen ad. Birden çok kartın varsa her birine farklı ad ver.
ArduinoOTA.setPassword("ota1234")Parola koymazsan ağdaki herkes kartına kod yükleyebilir. IDE yüklemeden önce bu parolayı sorar.
onStart / onEndGüncelleme başlarken ve biterken çalışır. Motorları durdurmak, röleleri kapatmak, ekrana "Güncelleniyor" yazmak için ideal yer.
onProgressYüzdeyi verir; bir LCD ya da OLED'de ilerleme çubuğu çizebilirsin.
onErrorHatanın türünü söyler: parola, yer yok, bağlantı, veri alma ya da bitirme hatası.
ArduinoOTA.handle()Gelen OTA isteklerini kontrol eder. loop() içinde sık sık çağrılmazsa kart IDE'ye cevap veremez.

Adım adım: ilk OTA yüklemesi

  1. Koddaki WIFI_SSID ve WIFI_PASS değerlerini kendi ağına göre düzenle. ESP32 yalnızca 2,4 GHz ağlara bağlanır.
  2. Araçlar menüsünde kartını (ör. ESP32 Dev Module) ve OTA içeren bir Partition Scheme seç (Default ya da Minimal SPIFFS).
  3. İlk yüklemeyi USB kablosuyla yap. Kartta henüz OTA kodu olmadığı için bu adım zorunludur.
  4. Seri Monitörü 115200 baud'da aç ve kartın yazdığı IP adresini not al.
  5. USB kablosunu çıkar, kartı istersen başka bir güç kaynağına bağla. 10–20 saniye içinde Araçlar > Port menüsünde ağ portları başlığı altında "bluegrays-esp32 at 192.168.1.x" satırı görünür; onu seç.
  6. Koddaki LED hızını 500'den 100'e çevir ve Yükle'ye bas. IDE parolayı sorduğunda "ota1234" yaz.
  7. Çıktı penceresinde yüzde ilerlemesini ve sonunda "Done" ya da "Result: OK" benzeri bir satırı göreceksin. Kart yeniden başlar ve LED artık hızlı yanıp söner.
Ağ portu görünmüyorsa önce bilgisayarın ve ESP32'nin aynı ağda olduğundan emin ol; misafir ağları ve bazı mesh sistemleri cihazların birbirini görmesini engeller. IDE'yi kapatıp açmak, kartı yeniden başlatmak ya da birkaç saniye beklemek çoğu zaman yeter. Mac ve Linux'ta IDE yükleme için espota.py betiğini kullandığından bilgisayarında Python 3 kurulu olmalıdır.

Bilmen gereken bir kısıtlama var: ağ portu yalnızca yükleme içindir, Seri Monitör kablosuz çalışmaz. Kartın mesajlarını görmek için ya USB'yi geri takarsın ya da durumu bir web sayfasında, ekranda veya MQTT mesajlarıyla gösterirsin. Masa başında geliştirirken kartı USB'ye takılı bırakıp yüklemeyi yine ağdan yapmak da mümkündür; böylece hem hızlı yükleme hem Seri Monitör elinde olur.

Parola koruması ve güvenlik

OTA hizmeti açık bir kart, ağındaki herkesin kod yükleyebileceği bir kapı demektir. ArduinoOTA'da setPassword() parolayı düz metin olarak kodun içinde tutar; kodu paylaşacaksan parolanın MD5 özetini setPasswordHash() ile verebilirsin, böylece parolanın kendisi kaynak kodda görünmez. ElegantOTA ise /update sayfasını kullanıcı adı ve parolayla (HTTP Basic Auth) korur.

  • Her cihaza farklı ve tahmin edilmesi zor bir parola ver: "1234" ya da "admin" gibi değerler ilk denenenlerdir.
  • Kartı internete açma: Modemde port yönlendirme yaparak OTA ya da /update sayfasını dışarıya açmak ciddi bir risktir; bu yöntemler şifresiz HTTP üzerinden çalışır.
  • Uzaktaki cihazlar için HTTPUpdate kullan: Kart güncellemeyi kendisi istediği için içeriden dışarıya bağlantı yeterlidir; internet üzerinden çekiyorsan HTTPS ve WiFiClientSecure tercih et.
  • Güncelleme sırasında güvenli duruma geç: onStart içinde motorları durdur, ısıtıcı ve pompa rölelerini kapat. Yeniden başlatma birkaç saniye sürer ve bu sırada pinler tanımsız kalabilir.

Yöntem 2: ElegantOTA ile tarayıcıdan .bin yükleme

ElegantOTA, ESP32'nin içinde çalışan web sunucusuna şık bir /update sayfası ekler. Telefonundan ya da Arduino IDE'si olmayan herhangi bir bilgisayardan bu sayfayı açar, derlenmiş .bin dosyasını seçer ve yüklersin; ilerleme çubuğu tarayıcıda görünür. Cihazı başkasına teslim ettiğinde ya da sahada güncelleme yapacağında en pratik yöntem budur.

  1. Arduino IDE'de Kütüphane Yöneticisi'ni aç, ElegantOTA (Ayush Sharma) kütüphanesini ara ve kur.
  2. Aşağıdaki kodu düzenle ve ilk kez USB ile yükle.
  3. Seri Monitörde yazan adresi (ör. http://192.168.1.42/update) tarayıcında aç, kullanıcı adı "admin" ve parola "ota1234" ile giriş yap.
  4. Mod olarak Firmware seçili olsun, .bin dosyasını sürükle bırak; yükleme bitince kart kendini yeniden başlatır.
C++ (Arduino IDE)
1#include <WiFi.h>
2#include <WebServer.h>
3#include <ElegantOTA.h>
4
5const char* WIFI_SSID = "AgAdi";          // Wi-Fi adın / your Wi-Fi name
6const char* WIFI_PASS = "AgSifresi";      // Wi-Fi şifren / your Wi-Fi password
7
8WebServer server(80);
9unsigned long otaProgressMillis = 0;
10
11void onOTAStart() {
12  Serial.println("OTA basladi / OTA started");     // röleleri kapat / switch relays off
13}
14
15void onOTAProgress(size_t current, size_t final) {
16  if (millis() - otaProgressMillis > 1000) {        // saniyede bir yaz / print once per second
17    otaProgressMillis = millis();
18    Serial.printf("%u / %u bayt / bytes\n", current, final);
19  }
20}
21
22void onOTAEnd(bool success) {
23  Serial.println(success ? "OTA basarili / OTA successful" : "OTA hatasi / OTA failed");
24}
25
26void setup() {
27  Serial.begin(115200);
28  WiFi.mode(WIFI_STA);
29  WiFi.begin(WIFI_SSID, WIFI_PASS);
30  while (WiFi.status() != WL_CONNECTED) {
31    delay(500);
32    Serial.print(".");
33  }
34  Serial.println();
35  Serial.print("Adres / Address: http://");
36  Serial.print(WiFi.localIP());
37  Serial.println("/update");
38
39  server.on("/", []() {
40    server.send(200, "text/plain", "BlueGrays ESP32 - surum / version 1.0");
41  });
42
43  ElegantOTA.begin(&server, "admin", "ota1234");   // /update sayfası + kullanıcı/parola / /update page + user/password
44  ElegantOTA.onStart(onOTAStart);
45  ElegantOTA.onProgress(onOTAProgress);
46  ElegantOTA.onEnd(onOTAEnd);
47
48  server.begin();
49}
50
51void loop() {
52  server.handleClient();     // web isteklerini işle / handle web requests
53  ElegantOTA.loop();         // başarılı yüklemeden sonra yeniden başlatır / reboots after a successful upload
54}

ElegantOTA varsayılan olarak çekirdekle gelen eş zamanlı WebServer sınıfıyla çalışır; bu yüzden loop() içinde server.handleClient() ve ElegantOTA.loop() çağrıları şarttır. Projen zaten ESPAsyncWebServer kullanıyorsa kütüphanenin ELEGANTOTA_USE_ASYNC_WEBSERVER ayarını 1 yaparak asenkron sunucuyla da kullanabilirsin; asenkron sunucu kurulumunu ESP32 Async Web Server ve WebSocket yazısında anlattık. Sayfadaki Filesystem modu ise program yerine LittleFS ya da SPIFFS görüntüsünü (web sayfası dosyaları, ayar dosyaları) günceller.

.bin dosyasını almak: derlenmiş dosyayı dışa aktarma

ElegantOTA ve HTTPUpdate için derlenmiş program dosyasına ihtiyacın var. Arduino IDE'de Sketch > Export Compiled Binary (Türkçe arayüzde Taslak menüsünde, derlenmiş binary'yi dışa aktarma seçeneği) komutunu çalıştır. IDE programı derler ve sketch klasörünün içinde build klasörü altına birkaç dosya bırakır. Bunların yalnızca biri OTA'ya uygundur:

DosyaİçerikOTA'da kullanılır mı?
projem.ino.binYalnızca uygulama (senin programın)Evet, yüklemen gereken dosya bu
projem.ino.bootloader.binÖnyükleyiciHayır
projem.ino.partitions.binBölüm tablosuHayır
projem.ino.merged.bin (çekirdek 3.x)Önyükleyici, tablo ve programın birleşimiHayır, yalnızca USB ile 0x0 adresine yazılır
Programı, karttaki çip için derlediğinden emin ol. ESP32 için derlenmiş bir .bin dosyasını ESP32-S3 ya da ESP32-C3'e yüklemeye çalışırsan son doğrulamada reddedilir ve kart eski programla devam eder. Yanlışlıkla merged.bin ya da bootloader.bin seçersen güncelleme "Wrong Magic Byte", yer yetersizliği ya da etkinleştirme hatasıyla durur.

Yöntem 3: HTTPUpdate ile sunucudan otomatik güncelleme

Evin farklı köşelerinde beş tane sensör kartın olduğunu düşün. Her birine tek tek IDE'den yüklemek yerine yeni .bin dosyasını bir sunucuya koyarsın, kartlar da dosyayı kendileri indirir. ESP32 çekirdeğiyle gelen HTTPUpdate kütüphanesi bu işi tek satırla yapar. Aşağıdaki örnekte karttaki BOOT butonuna (GPIO 0) bastığında güncelleme başlar:

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <HTTPUpdate.h>
3
4const char* WIFI_SSID = "AgAdi";
5const char* WIFI_PASS = "AgSifresi";
6// Bilgisayarındaki ya da sunucundaki .bin dosyası / the .bin file on your computer or server
7const char* FIRMWARE_URL = "http://192.168.1.50:8000/firmware.bin";
8const int BUTTON_PIN = 0;               // karttaki BOOT butonu / the BOOT button on the board
9
10void setup() {
11  Serial.begin(115200);
12  pinMode(BUTTON_PIN, INPUT_PULLUP);
13  WiFi.begin(WIFI_SSID, WIFI_PASS);
14  while (WiFi.status() != WL_CONNECTED) delay(500);
15  Serial.println("Hazir: guncellemek icin BOOT'a bas / Ready: press BOOT to update");
16}
17
18void loop() {
19  if (digitalRead(BUTTON_PIN) == LOW) {      // butona basıldı / button pressed
20    WiFiClient client;
21    httpUpdate.rebootOnUpdate(true);          // başarılıysa yeniden başlat / reboot on success
22    t_httpUpdate_return ret = httpUpdate.update(client, FIRMWARE_URL);
23
24    switch (ret) {
25      case HTTP_UPDATE_FAILED:
26        Serial.printf("Hata / Error (%d): %s\n", httpUpdate.getLastError(),
27                      httpUpdate.getLastErrorString().c_str());
28        break;
29      case HTTP_UPDATE_NO_UPDATES:
30        Serial.println("Guncelleme yok / No update");
31        break;
32      case HTTP_UPDATE_OK:
33        Serial.println("Tamam / OK");        // buraya genelde gelinmez, kart yeniden başlar / usually not reached, the board reboots
34        break;
35    }
36    delay(1000);
37  }
38}

Denemek için .bin dosyasını bilgisayarında bir klasöre firmware.bin adıyla koy ve o klasörde python3 -m http.server 8000 komutunu çalıştır; koddaki IP adresini bilgisayarının yerel IP'siyle değiştir. Gerçek kullanımda butonu bir zamanlayıcıyla değiştirirsin: kart örneğin saatte bir küçük bir "version.txt" dosyasını okur, sunucudaki sürüm numarası kendisininkinden büyükse güncellemeyi başlatır. Böylece aynı dosyayı tekrar tekrar indirip yeniden başlama döngüsüne de girmez.

OTA sırasında bağlantı koparsa ne olur?

Kısa cevap: kartın bozulmaz. Yeni program kullanılmayan bölüme yazıldığı ve önyükleme bölümü ancak dosyanın tamamı doğrulandıktan sonra değiştirildiği için yükleme yarıda kesilirse kart eski programıyla çalışmaya devam eder. IDE'de "Error Uploading", ArduinoOTA'da OTA_RECEIVE_ERROR ya da ElegantOTA'da başarısız sonucu görürsün; sorunu giderip yüklemeyi tekrarlarsın. Kesilme sırasında elektrik giderse de durum aynıdır, kart eski programla açılır. Tek gerçek risk, yeni programın kendisinin hatalı olmasıdır: Wi-Fi'a bağlanmayan ya da OTA kodunu içermeyen bir program yüklersen bir sonraki güncelleme için kabloya dönmen gerekir.

  • Zayıf Wi-Fi sinyali: Yükleme %30–60 civarında takılıyorsa kartı modeme yaklaştır ya da harici antenli bir modül kullan. Seri Monitörde WiFi.RSSI() değeri -75 dBm'den kötüyse kopmalar beklenir; ayrıntılar için ESP32 Wi-Fi'a bağlanmıyor yazısına bak.
  • Yetersiz güç: Flash'a yazma ile Wi-Fi yayını aynı anda akım çeker. Zayıf bir USB portu ya da ince kablo, yükleme sırasında kartı resetleyebilir; bu durum brownout hatası olarak görünür. En az 500 mA verebilen sağlam bir 5 V kaynak kullan.
  • loop() içinde uzun bekleme: delay(5000) gibi beklemeler handle() çağrısını geciktirir ve IDE "No response from the ESP" hatası verir. Zamanlamayı millis() ile yap.
  • Güvenlik duvarı: ArduinoOTA'da yükleme başladığında ESP32 bilgisayarına geri bağlanır. Windows Güvenlik Duvarı ya da bir antivirüs bu gelen bağlantıyı engellerse yükleme ilk anda başarısız olur; ilk denemede çıkan izin penceresinde özel ağlara izin ver.

Her yeni kodda OTA'yı korumak

OTA'yla ilgili en sık yaşanan hayal kırıklığı şudur: karta OTA'yla tamamen farklı bir proje yüklersin, o projede ArduinoOTA kodu yoktur ve kart artık ağ portunda görünmez. Yeni yüklenen program eskisinin tamamen yerine geçer; OTA özelliği "kartta kalan" bir şey değildir, her programın kendisi taşımalıdır. Tavandaki cihaza tekrar merdivenle çıkmamak için şu kuralları alışkanlık haline getir:

  • Bir şablon kullan: Wi-Fi bağlantısı ve ArduinoOTA ayarlarını ayrı bir fonksiyona (ör. setupOTA()) koy ve her yeni projeye bu dosyayla başla.
  • handle() çağrısını loop()'un en başına yaz ve loop() içinde hiçbir zaman uzun süre bloklayan bir döngü bırakma.
  • Wi-Fi koparsa yeniden bağlan: WiFi.setAutoReconnect(true) kullan ya da bağlantıyı düzenli olarak kontrol et; bağlantısı olmayan kart güncelleme alamaz.
  • Deep sleep kullanan projelere bakım penceresi ekle: Uyuyan kart OTA isteğini duymaz. Açılışta bir buton basılıysa ya da bir MQTT bayrağı geldiyse uyumadan önce 60 saniye OTA bekleyen bir mod yaz. Uyku modları için ESP32 Deep Sleep yazısına bakabilirsin.
  • Önce masadaki ikinci kartta dene: Sahadaki cihaza göndermeden önce aynı kodu yanındaki bir kartta çalıştır; Wi-Fi'a bağlanıyor ve ağ portunda görünüyorsa göndermek güvenlidir.
  • Sürüm numarası yazdır: Kodun başında bir FW_VERSION sabiti tut ve web sayfasında ya da ekranda göster; hangi kartta hangi sürümün çalıştığını hep bilirsin.

ESP8266 ve Raspberry Pi Pico W'de OTA

Bu rehberdeki ArduinoOTA ve ElegantOTA kodları küçük değişikliklerle ESP8266 (NodeMCU, Wemos D1 Mini) kartlarında da çalışır: WiFi.h yerine ESP8266WiFi.h, WebServer yerine ESP8266WebServer kullanılır ve OTA portu 8266'dır. ESP8266'nın 4 MB flash'ı olan kartlarında Flash Size menüsünde OTA için yeterli program alanı bırakan bir seçenek seçmelisin. Raspberry Pi Pico W'de ise arduino-pico çekirdeği ArduinoOTA desteği sunar; burada yeni program önce LittleFS dosya sistemine indirilir ve açılışta yerine kopyalanır. Bu yüzden Pico W'de Flash Size menüsünde dosya sistemi için programdan büyük bir alan ayırman gerekir. MicroPython'da hazır bir OTA aracı yoktur; .py dosyalarını ağdan indirip değiştiren küçük betikler yazılabilir ama bu, ESP32'deki gibi doğrulamalı iki bölümlü bir güncelleme değildir.

OTA ile proje fikirleri

  • Tavan ya da duvar sensörü: Sıcaklık, nem ve hareket ölçen bir kartın eşik değerlerini kabloya dokunmadan değiştir.
  • Akıllı ev rölesi: Elektrik kutusundaki röle kartının zamanlama kurallarını OTA ile güncelle; onStart içinde röleleri güvenli konuma al.
  • Home Assistant cihazları: MQTT ile Home Assistant'a bağlı sensörlere yeni özellikleri ağdan ekle.
  • Bahçe sulama kontrolcüsü: Su geçirmez kutudaki kartı açmadan sulama saatlerini ve toprak nem eşiğini değiştir.
  • LCD'de ilerleme çubuğu: onProgress değerini 16x2 LCD'de yüzde ve çubuk olarak göster; BlueGrays'teki ESP32 OTA projesi tam olarak bunu yapar.
  • Filo güncellemesi: Birden çok kartın HTTPUpdate ile her gece aynı sunucudan sürüm kontrolü yapmasını sağla.

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

BelirtiOlası sebepÇözüm
Port menüsünde ağ portu yokKart farklı ağda, mDNS engelleniyor, kod ArduinoOTA.begin() çağırmıyorAynı 2,4 GHz ağı kullan, IDE'yi yeniden başlat, Seri Monitörde IP'nin yazdığını kontrol et
"No response from the ESP"loop() içinde uzun delay(), kart meşgul ya da güvenlik duvarıdelay() yerine millis() kullan, güvenlik duvarında IDE'ye izin ver
"Authentication Failed"Yanlış OTA parolasıKoddaki setPassword değerini gir; parolayı unuttuysan bir kez USB ile yükle
"Not Enough Space" / Begin FailedHuge APP ya da No OTA tablosu, program ikinci alana sığmıyorMinimal SPIFFS seç ve bir kez USB ile yükle; programı küçült
Yükleme yarıda kesiliyorZayıf sinyal, güç düşmesi, kopan bağlantıKartı modeme yaklaştır, sağlam 5 V kaynak kullan, tekrar dene; eski program çalışmaya devam eder
Yükleme sonrası kart ağa çıkmıyorYeni kod Wi-Fi ya da OTA içermiyor, yanlış SSIDUSB ile düzelt; bundan sonra her projeye OTA şablonuyla başla
ElegantOTA'da "Wrong Magic Byte" ya da etkinleştirme hatasımerged.bin, bootloader.bin ya da başka çip için derlenmiş dosya seçilmişYalnızca projem.ino.bin dosyasını yükle
OTA'yı ilk kez kurarken kartı USB'ye takılı bırak ve Seri Monitörü açık tut; onError çıktısı sana sorunun parola mı, yer mi, yoksa bağlantı mı olduğunu tek satırda söyler. Her şey çalıştıktan sonra kabloyu çıkarabilirsin.

OTA, ESP32 projelerini masadan alıp gerçek bir yere monte etmenin anahtarıdır: bir kez doğru kurduğunda düzeltmeler, yeni özellikler ve eşik değişiklikleri kablosuz olarak saniyeler içinde gelir. BlueGrays uygulamasında ESP32 OTA Update projesini (LCD'de IP ve ilerleme göstergeli), Wi-Fi bağlantısı, Async Web Server, mDNS ve NTP projeleriyle birlikte devre şeması ve kodlarıyla adım adım bulabilirsin.

Sıkça sorulan sorular

ESP32 OTA nedir?

OTA (Over-The-Air), ESP32'ye yeni programı USB kablosu yerine Wi-Fi üzerinden yüklemektir. Kart yeni kodu kullanılmayan bir program bölümüne yazar, doğrular ve yeniden başlayarak yeni sürümle açılır. İlk OTA destekli kodu bir kez USB ile yüklemen gerekir.

ESP32 ağ portu Arduino IDE'de neden görünmüyor?

En sık sebepler bilgisayar ile kartın farklı ağlarda olması, misafir ağının cihazları birbirinden ayırması ve koddaki ArduinoOTA.begin() çağrısının çalışmamasıdır. Seri Monitörde kartın IP aldığını kontrol et, IDE'yi yeniden başlat ve birkaç saniye bekle.

ESP32 OTA için hangi partition scheme seçilmeli?

4 MB flash'lı kartlarda Default (2 × 1,25 MB program alanı) ya da program büyükse Minimal SPIFFS (2 × 1,875 MB) seçilmelidir. Huge APP ve No OTA seçeneklerinde ikinci program alanı olmadığı için OTA çalışmaz. Tabloyu değiştirdikten sonraki ilk yükleme USB ile yapılmalıdır.

OTA yüklemesi yarıda kesilirse ESP32 bozulur mu?

Hayır. Yeni program boş bölüme yazılır ve önyükleme bölümü yalnızca dosyanın tamamı doğrulandıktan sonra değiştirilir. Bağlantı ya da elektrik kesilirse kart eski programla açılır ve yüklemeyi tekrar deneyebilirsin.

OTA ile yüklerken Seri Monitör kullanılabilir mi?

Ağ portu yalnızca kod yüklemek içindir; Seri Monitör kablosuz çalışmaz. Mesajları görmek için kartı USB'ye takılı bırakabilir ya da bilgileri bir web sayfasında, ekranda veya MQTT ile gösterebilirsin.

ESP32 OTA parolası nasıl ayarlanır?

ArduinoOTA'da begin() çağrısından önce ArduinoOTA.setPassword("parola") yazarsın; IDE yüklemeden önce bu parolayı sorar. Parolayı kodda açık tutmak istemiyorsan MD5 özetini setPasswordHash() ile verebilirsin. ElegantOTA'da ise begin(&server, "kullanici", "parola") ile sayfayı korursun.

Tüm projeleri gör
ESP32 OTA Update — Kablosuz Firmware Yükleme (LCD Ekranlı)
#132İleri
Premium

ESP32 OTA Update — Kablosuz Firmware Yükleme (LCD Ekranlı)

Bu projede ESP32'ye USB kablosu olmadan, Wi-Fi üzerinden yeni firmware yüklemeyi öğreneceksin. ArduinoOTA kütüphanesi ile ESP32 ağda görünür hale gelir ve Arduino IDE'nin "Network port" sekmesinde bluegrays-ota olarak otomatik listelenir. İlk yükleme USB ile yapılır, sonrasında tüm güncellemeler kablosuz olur — saha cihazları için çok kritik bir özelliktir. I2C LCD ekranda WiFi durumu, IP, hostname, OTA yükleme yüzdesi ve hata mesajları hem Türkçe hem İngilizce gösterilir. Parola koruması, h

4.6(14)
22
ESP32 Wi-Fi STA Bağlantısı (LCD Ekranlı)
#127İleri

ESP32 Wi-Fi STA Bağlantısı (LCD Ekranlı)

Bu projede ESP32'yi Station (STA) modunda evdeki Wi-Fi ağına güvenli ve hata toleranslı şekilde bağlıyoruz. SSID/şifreyi secrets.h dosyasına ayırarak Git'e sızmasını önlüyor, otomatik yeniden bağlanma mekanizması kuruyor, RSSI sinyal seviyesini ve IP adresini I2C LCD ekranda gösteriyoruz. Dahili LED durum göstergesi olarak çalışır. Üretim seviyesi bir bağlantı yöneticisidir.

4.4(21)
34
ESP32 Async Web Server (LCD'de IP Göstergeli)
#129İleri

ESP32 Async Web Server (LCD'de IP Göstergeli)

Bu projede ESP32'yi aynı Wi-Fi ağındaki telefonunuzdan veya bilgisayarınızdan kontrol edebileceğiniz asenkron bir web sunucusuna dönüştürüyoruz. ESPAsyncWebServer kütüphanesi sayesinde sunucu birden fazla isteği aynı anda işleyebiliyor (klasik WebServer.h gibi tek istekte bloklamıyor). Tarayıcıdan ESP32'nin IP adresine bağlanıp ON/OFF butonlarına basarak (/on ve /off adresleri) GPIO 5'e bağlı LED'i açıp kapatabileceksiniz.

4.8(16)
26
ESP32 mDNS: bluegrays-esp.local ile Cihaza Erişim (LCD Ekranlı)
#131İleri
Premium

ESP32 mDNS: bluegrays-esp.local ile Cihaza Erişim (LCD Ekranlı)

Bu projede ESP32'ye mDNS (Multicast DNS) servisi ekleyerek IP adresi yerine bluegrays-esp.local gibi okunabilir bir host adıyla erişim sağlıyoruz. DHCP'nin verdiği IP değişse bile cihaza her zaman aynı isimle ulaşabilirsiniz. Üzerinde küçük bir web server da çalıştırarak tarayıcıdan http://bluegrays-esp.local/ adresiyle LED kontrolü gönderiyoruz. I2C LCD ekranda hostname, IP ve LED durumu hem Türkçe hem İngilizce gösterilir. iOS, macOS ve Linux mDNS'i doğal olarak destekler; Windows'ta Bonjo

4.8(14)
23
ESP32 WebSocket Sayaç (2 Buton + LCD + Web Realtime)
#130İleri
Premium

ESP32 WebSocket Sayaç (2 Buton + LCD + Web Realtime)

Bu projede ESP32'ye bağlı iki butonla (GPIO 5 artırır, GPIO 4 azaltır) bir sayaç değiştirilir. Değer hem 16x2 I2C LCD'de hem de ESPAsyncWebServer'ın WebSocket desteğiyle bağlı tüm tarayıcılarda anında güncellenir; sayfayı yenilemek gerekmez. HTTP polling yerine tek bir kalıcı bağlantı kullanılır ve ESP32 yeni değeri ws.textAll() ile herkese gönderir.

4.5(14)
23
ESP32 NTP ile İnternetten Gerçek Zaman
#128İleri
Premium

ESP32 NTP ile İnternetten Gerçek Zaman

ESP32, Wi-Fi'a bağlanıp NTP (Network Time Protocol) sunucularından milisaniye hassasiyetiyle gerçek zamanı çeker. configTzTime() fonksiyonu sayesinde Türkiye saat dilimi (TRT, UTC+3) otomatik uygulanır ve yaz/kış saati uygulayan ülkelerde DST geçişi POSIX TZ string'i ile otomatik yönetilir. Saat hem Serial Monitor'e hem de opsiyonel I2C LCD'ye yazdırılır. configTzTime() SNTP hizmetini başlatır; ağ erişimi varken periyodik yeniden senkronizasyon yapılır ve iki senkronizasyon arasında sistem s

4.5(13)
21
ESP32 HTTPClient + Hava Durumu API (LCD Ekranlı)
#133İleri
Premium

ESP32 HTTPClient + Hava Durumu API (LCD Ekranlı)

Bu projede ESP32 ile internet üzerinden hava durumu API'sine (wttr.in) HTTPClient.h kullanarak REST API çağrısı yapıyoruz. ArduinoJson v7 ile dönen JSON cevabını parse edip şehir, sıcaklık, nem, hava durumu ve rüzgar bilgilerini I2C LCD ekranda hem Türkçe hem İngilizce gösteriyoruz. wttr.in ücretsizdir, API key gerektirmez — herhangi bir şehir ismini yazarak o şehrin anlık hava durumunu çekebilirsiniz. 30 dakikada bir otomatik güncelleme, LED ile her ekran için farklı görsel feedback ve eksiks

4.7(13)
20
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