Panduan · 12 mnt baca

Pembaruan OTA ESP32: Upload Kode Tanpa Kabel dengan ArduinoOTA

OTA ESP32 memungkinkanmu meng-upload kode lewat Wi-Fi tanpa kabel USB: port jaringan ArduinoOTA, halaman web ElegantOTA, kata sandi, partition scheme, dan upload yang terputus.

OTA ESP32 (Over-The-Air update, pembaruan lewat udara) berarti meng-upload kode baru ke board-mu lewat Wi-Fi alih-alih mencolokkan kabel USB. Bayangkan sensor yang terpasang di plafon, pengendali penyiraman di kebun, atau board relay yang terselip di dalam panel listrik: daripada mengambil tangga, melepas board, dan menyambungkannya ke komputer untuk setiap perbaikan kecil, kamu mengirim versi baru dari Arduino IDE atau browser dalam beberapa detik. Board menulis program baru ke memorinya di latar belakang, memverifikasinya, lalu me-restart dirinya sendiri.

Di panduan ini kamu akan belajar langkah demi langkah cara kerja OTA di dalam ESP32, tiga metode yang berbeda (ArduinoOTA untuk Arduino IDE, ElegantOTA untuk browser, dan HTTPUpdate untuk mengambil dari server), cara memilih partition scheme yang tepat, cara melindungi upload dengan kata sandi, apa yang terjadi kalau upload terputus, dan cara agar OTA tidak hilang di sketch berikutnya. Semua kode sudah dikompilasi dan diuji dengan core Arduino ESP32.

Board pengembangan ESP32 dengan upload kode nirkabel lewat OTA
Board pengembangan ESP32: setelah sketch OTA pertama di-upload sekali lewat USB, setiap pembaruan berikutnya bisa kamu kirim lewat Wi-Fi.

Apa itu OTA ESP32 dan bagaimana cara kerjanya?

Memori flash ESP32 bukan satu blok tunggal; memori ini dibagi menjadi beberapa bagian oleh sebuah peta yang disebut tabel partisi (partition table). Tabel partisi yang mendukung OTA punya dua area identik untuk program: app0 (ota_0) dan app1 (ota_1). Selama board berjalan dari salah satunya, program baru ditulis ke area yang lain. Partisi kecil otadata menyimpan area mana yang akan dijalankan pada boot berikutnya. Dengan cara ini, program yang sedang berjalan tidak pernah disentuh selama upload, dan board tidak melepaskan program lama sampai kode baru selesai ditulis dan diverifikasi sepenuhnya.

  1. Program baru (file .bin hasil kompilasi) tiba di board lewat Wi-Fi, sepotong demi sepotong.
  2. ESP32 menulis setiap potongan ke partisi program yang sedang tidak dipakai; sementara itu, kode yang berjalan tetap mengerjakan tugasnya.
  3. Begitu seluruh file tiba, header image dan checksum diperiksa; file yang rusak atau tidak lengkap ditolak.
  4. Kalau verifikasi berhasil, otadata diperbarui: partisi baru akan dijalankan pada boot berikutnya.
  5. Board me-restart dan menyala dengan program baru. Pembaruan berikutnya masuk ke partisi yang lain; kedua area dipakai secara bergantian.
MetodeDari mana kodenya dikirim?Paling cocok untukLibrary tambahan
ArduinoOTADari port jaringan di Arduino IDEMengembangkan di meja kerja, di jaringan yang samaTidak ada (sudah termasuk di core)
ElegantOTADengan memilih file .bin di halaman /update di browserMembiarkan orang tanpa IDE memperbarui, upload dari ponselElegantOTA
HTTPUpdateBoard mengunduh sendiri file .bin dari serverBanyak perangkat, perangkat jarak jauh, pembaruan otomatisTidak ada (sudah termasuk di core)

Partition scheme dan ukuran flash

Inilah syarat OTA yang paling sering terlewat: harus ada area kosong kedua untuk menulis program baru. Karena itu, program terbesar yang bisa kamu upload lewat OTA bahkan lebih kecil dari setengah flash. Tabel partisi dipilih di Arduino IDE lewat Tools > Partition Scheme. Di board ESP32 DevKit yang umum dengan flash 4 MB (ESP32 Dev Module), pilihannya adalah:

Partition SchemeArea programOTASistem file (SPIFFS/LittleFS)
Default 4MB with spiffs2 × 1,25 MB (1.310.720 byte)Ya1,375 MB
Minimal SPIFFS (1.9MB APP with OTA)2 × 1,875 MB (1.966.080 byte)Ya128 KB
No OTA (2MB APP/2MB SPIFFS)1 × 2 MBTidak1,875 MB
Huge APP (3MB No OTA/1MB SPIFFS)1 × 3 MBTidak896 KB
Minimal (1.3MB APP/700KB SPIFFS)1 × 1,25 MB (untuk board dengan flash 2 MB)Tidak640 KB
Ketika program besar yang memakai Bluetooth dan Wi-Fi bersamaan memunculkan “Sketch too big”, kebanyakan orang memilih Huge APP. Skema itu tidak punya area program kedua: kodenya bisa di-upload lewat USB tanpa masalah, tapi OTA tidak mau mulai dan gagal dengan “Not Enough Space” atau “Begin Failed”. Kalau kamu ingin OTA, pilih Minimal SPIFFS (1.9MB APP with OTA).

Berapa banyak ruang yang dipakai programmu bisa dilihat di output kompilasi: contoh pertama kami dengan Wi-Fi dan ArduinoOTA mencetak “Sketch uses 758685 bytes (57%) ... Maximum is 1310720 bytes”. Nilai maksimum di sini adalah ukuran satu area program pada skema yang kamu pilih. Kalau pemakaian melewati 90%, bersiaplah pindah ke Minimal SPIFFS dalam waktu dekat. Satu aturan penting lagi: tabel partisi tidak bisa diubah lewat OTA. Kalau kamu mengganti skemanya, upload itu harus dilakukan lewat USB; pembaruan OTA berikutnya berjalan dengan tabel yang baru. Di board dengan flash 8 MB atau 16 MB (seperti banyak model ESP32-S3), memilih ukuran yang benar di menu Flash Size memberimu area OTA yang jauh lebih besar.

Kalau ingin melihat dari partisi mana board-mu sebenarnya berjalan dan berapa ruang yang tersisa untuk OTA, upload sketch kecil di bawah. Sketch ini tidak butuh library dan langsung memakai fungsi OTA ESP-IDF:

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}

Dengan skema default, setelah upload pertama lewat USB, output-nya menampilkan “Running partition: app0 (0x010000)” dan “Next OTA partition: app1 (0x150000)”. Jalankan kode ini lagi setelah pembaruan OTA dan kamu akan melihat board sekarang berjalan dari app1. Nilai ESP.getFreeSketchSpace() adalah ukuran program terbesar yang bisa kamu upload lewat OTA; kalau file .bin barumu lebih besar, pembaruan tidak akan dimulai.

Metode 1: upload nirkabel dari Arduino IDE dengan ArduinoOTA

Library ArduinoOTA sudah termasuk di core ESP32, jadi tidak ada yang perlu diinstal. Begitu board bergabung ke jaringan, board mengumumkan dirinya lewat mDNS; Arduino IDE melihatnya dan menambahkan port jaringan ke menu Port. Ketika kamu menekan Upload, IDE mengirim program lewat port jaringan ini alih-alih USB. Di ESP32, layanan OTA secara default mendengarkan di port 3232. Sketch di bawah menyambung ke Wi-Fi, memulai OTA dengan kata sandi, dan mengedipkan LED onboard sebagai bukti:

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}
BarisApa fungsinya?
ArduinoOTA.setHostname("bluegrays-esp32")Nama yang tampil di daftar Port di IDE dan di jaringan. Kalau kamu punya beberapa board, beri nama yang berbeda untuk masing-masing.
ArduinoOTA.setPassword("ota1234")Tanpa kata sandi, siapa pun di jaringanmu bisa meng-upload kode ke board-mu. IDE menanyakan kata sandi ini sebelum upload.
onStart / onEndDijalankan ketika pembaruan dimulai dan selesai. Tempat yang ideal untuk menghentikan motor, mematikan relay, atau menampilkan “Updating” di layar.
onProgressMemberimu persentase; kamu bisa menggambar progress bar di LCD atau OLED.
onErrorMemberi tahu jenis error: kata sandi, ruang tidak cukup, koneksi, penerimaan, atau error di akhir.
ArduinoOTA.handle()Memeriksa permintaan OTA yang masuk. Kalau tidak sering dipanggil di dalam loop(), board tidak bisa menjawab IDE.

Langkah demi langkah: upload OTA pertamamu

  1. Ubah nilai WIFI_SSID dan WIFI_PASS di kode sesuai jaringanmu. ESP32 hanya bisa tersambung ke jaringan 2,4 GHz.
  2. Di menu Tools, pilih board-mu (misalnya ESP32 Dev Module) dan Partition Scheme yang mendukung OTA (Default atau Minimal SPIFFS).
  3. Lakukan upload pertama dengan kabel USB. Langkah ini wajib karena board belum punya kode OTA.
  4. Buka Serial Monitor pada 115200 baud dan catat alamat IP yang dicetak board.
  5. Cabut kabel USB dan, kalau mau, beri daya board dari sumber lain. Dalam 10–20 detik, baris seperti “bluegrays-esp32 at 192.168.1.x” muncul di bagian network ports (port jaringan) di Tools > Port; pilih baris itu.
  6. Ubah jeda LED di kode dari 500 menjadi 100 lalu tekan Upload. Ketika IDE menanyakan kata sandi, ketik “ota1234”.
  7. Di jendela output kamu akan melihat persentase kemajuan dan akhirnya baris seperti “Done” atau “Result: OK”. Board me-restart dan LED sekarang berkedip cepat.
Kalau port jaringan tidak muncul, pertama pastikan komputermu dan ESP32 berada di jaringan yang sama; jaringan tamu dan beberapa sistem mesh mencegah perangkat saling melihat. Me-restart IDE, me-reboot board, atau sekadar menunggu beberapa detik biasanya sudah cukup. Di Mac dan Linux, IDE memakai skrip espota.py untuk upload, jadi Python 3 harus terinstal di komputermu.

Ada satu keterbatasan yang perlu kamu tahu: port jaringan hanya untuk upload, dan Serial Monitor tidak bekerja secara nirkabel. Untuk melihat pesan dari board, colokkan lagi USB atau tampilkan statusnya di halaman web, layar, atau lewat pesan MQTT. Selama mengembangkan di meja kerja, kamu juga bisa membiarkan board tetap tersambung USB sambil tetap meng-upload lewat jaringan; dengan begitu kamu mendapat upload cepat dan Serial Monitor sekaligus.

Perlindungan kata sandi dan keamanan

Board dengan layanan OTA yang terbuka adalah pintu tempat siapa pun di jaringanmu bisa meng-upload kode. Di ArduinoOTA, setPassword() menyimpan kata sandi sebagai teks biasa di dalam kode; kalau kamu akan membagikan kodenya, kamu bisa memberikan hash MD5 dari kata sandi itu dengan setPasswordHash() sehingga kata sandinya sendiri tidak muncul di kode sumber. ElegantOTA melindungi halaman /update dengan nama pengguna dan kata sandi (HTTP Basic Auth).

  • Beri setiap perangkat kata sandi yang berbeda dan sulit ditebak: nilai seperti “1234” atau “admin” adalah yang pertama dicoba orang.
  • Jangan buka board ke internet: membuka OTA atau halaman /update ke luar dengan port forwarding di router adalah risiko serius; metode-metode ini berjalan lewat HTTP yang tidak terenkripsi.
  • Pakai HTTPUpdate untuk perangkat jarak jauh: karena board sendiri yang meminta pembaruan, koneksi keluar saja sudah cukup; kalau mengambil lewat internet, utamakan HTTPS dengan WiFiClientSecure.
  • Masuk ke keadaan aman selama pembaruan: hentikan motor dan matikan relay pemanas dan pompa di dalam onStart. Restart butuh beberapa detik, dan selama itu kondisi pin bisa tidak menentu.

Metode 2: upload .bin dari browser dengan ElegantOTA

ElegantOTA menambahkan halaman /update yang rapi ke web server yang berjalan di ESP32. Halaman ini kamu buka dari ponsel atau dari komputer mana pun tanpa Arduino IDE, pilih file .bin hasil kompilasi, lalu upload; progress bar muncul di browser. Ini metode paling praktis ketika kamu menyerahkan perangkat ke orang lain atau memperbaruinya di lapangan.

  1. Di Arduino IDE, buka Library Manager, cari ElegantOTA (Ayush Sharma), lalu instal.
  2. Sesuaikan kode di bawah dan upload pertama kali lewat USB.
  3. Buka alamat yang dicetak di Serial Monitor (misalnya http://192.168.1.42/update) di browser-mu dan masuk dengan nama pengguna “admin” dan kata sandi “ota1234”.
  4. Biarkan mode Firmware terpilih dan seret lalu lepas file .bin; ketika upload selesai, board me-restart dengan sendirinya.
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}

Secara default, ElegantOTA bekerja dengan kelas WebServer sinkron yang sudah termasuk di core, jadi pemanggilan server.handleClient() dan ElegantOTA.loop() di dalam loop() wajib ada. Kalau proyekmu sudah memakai ESPAsyncWebServer, kamu bisa mengatur opsi library ELEGANTOTA_USE_ASYNC_WEBSERVER ke 1 dan memakainya dengan server asinkron; cara menyiapkan server asinkron sudah kami bahas di artikel web server asinkron ESP32 dan WebSocket. Mode Filesystem di halaman itu memperbarui image LittleFS atau SPIFFS (file halaman web, file pengaturan) alih-alih program.

Mendapatkan file .bin: mengekspor binary hasil kompilasi

Untuk ElegantOTA dan HTTPUpdate, kamu butuh file program hasil kompilasi. Di Arduino IDE, jalankan Sketch > Export Compiled Binary. IDE mengompilasi program dan meninggalkan beberapa file di folder build di dalam folder sketch-mu. Hanya satu di antaranya yang cocok untuk OTA:

FileIsiDipakai untuk OTA?
myproject.ino.bin (file aplikasi)Hanya aplikasinya (programmu)Ya, ini file yang di-upload
myproject.ino.bootloader.bin (file bootloader)BootloaderTidak
myproject.ino.partitions.bin (file tabel partisi)Tabel partisiTidak
myproject.ino.merged.bin (core 3.x, file gabungan)Gabungan bootloader, tabel, dan programTidak, hanya ditulis lewat USB di alamat 0x0
Pastikan kamu mengompilasi program untuk chip yang ada di board-mu. Kalau kamu mencoba meng-upload .bin yang dikompilasi untuk ESP32 ke ESP32-S3 atau ESP32-C3, file itu ditolak pada verifikasi akhir dan board tetap menjalankan program lama. Kalau kamu salah memilih merged.bin atau bootloader.bin, pembaruan berhenti dengan “Wrong Magic Byte”, error ruang tidak cukup, atau error aktivasi.

Metode 3: pembaruan otomatis dari server dengan HTTPUpdate

Bayangkan kamu punya lima board sensor di sekitar rumah. Daripada meng-upload ke masing-masing dari IDE, kamu menaruh file .bin baru di server dan board-board itu mengunduhnya sendiri. Library HTTPUpdate yang sudah termasuk di core ESP32 melakukan ini dalam satu baris. Pada contoh di bawah, pembaruan dimulai ketika kamu menekan tombol BOOT (GPIO 0) di board:

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}

Untuk mencobanya, taruh file .bin di sebuah folder di komputermu dengan nama firmware.bin dan jalankan python3 -m http.server 8000 di folder itu; ganti alamat IP di kode dengan IP lokal komputermu. Di pemakaian nyata, tombol itu kamu ganti dengan timer: misalnya, sekali setiap jam board membaca file kecil “version.txt”, dan kalau nomor versi di server lebih tinggi daripada versinya sendiri, board memulai pembaruan. Dengan begitu board juga tidak terjebak mengunduh file yang sama dan me-restart berulang-ulang.

Apa yang terjadi kalau koneksi terputus selama OTA?

Jawaban singkatnya: board-mu tidak akan mati total (brick). Karena program baru ditulis ke partisi yang tidak dipakai dan partisi boot baru diganti setelah seluruh file diverifikasi, upload yang terputus membuat board tetap menjalankan program lamanya. Kamu akan melihat “Error Uploading” di IDE, OTA_RECEIVE_ERROR di ArduinoOTA, atau hasil gagal di ElegantOTA; perbaiki masalahnya dan ulangi upload. Kalau listrik padam di tengah upload, ceritanya sama: board menjalankan program lama ketika boot. Satu-satunya risiko nyata adalah program baru itu sendiri yang bermasalah: kalau kamu meng-upload program yang tidak menyambung ke Wi-Fi atau tidak berisi kode OTA, kamu butuh kabel lagi untuk pembaruan berikutnya.

  • Sinyal Wi-Fi lemah: kalau upload macet di sekitar 30–60%, dekatkan board ke router atau pakai modul dengan antena eksternal. Kalau WiFi.RSSI() di Serial Monitor lebih buruk dari -75 dBm, bersiaplah koneksi sering putus; detailnya ada di ESP32 tidak mau terhubung ke Wi-Fi.
  • Daya tidak cukup: menulis ke flash dan memancarkan Wi-Fi menarik arus secara bersamaan. Port USB yang lemah atau kabel yang tipis bisa me-reset board selama upload; ini muncul sebagai error brownout. Pakai catu daya 5 V yang stabil dan mampu memberi setidaknya 500 mA.
  • Jeda panjang di dalam loop(): jeda seperti delay(5000) menunda pemanggilan handle() dan IDE melaporkan “No response from the ESP”. Atur waktunya dengan millis().
  • Firewall: dengan ArduinoOTA, ketika upload dimulai, ESP32 menyambung balik ke komputermu. Kalau Windows Firewall atau antivirus memblokir koneksi masuk ini, upload langsung gagal; izinkan jaringan privat di jendela izin yang muncul pada percobaan pertama.

Mempertahankan OTA di setiap sketch baru

Kekecewaan OTA yang paling umum terjadi seperti ini: kamu meng-upload proyek yang sama sekali berbeda lewat OTA, proyek itu tidak punya kode ArduinoOTA, dan board tidak lagi muncul sebagai port jaringan. Program yang baru di-upload menggantikan program lama sepenuhnya; OTA bukan sesuatu yang “tetap tinggal di board”, setiap program harus membawanya sendiri. Supaya kamu tidak perlu naik tangga lagi ke perangkat di plafon, biasakan aturan berikut:

  • Pakai template: taruh koneksi Wi-Fi dan pengaturan ArduinoOTA di fungsi terpisah (misalnya setupOTA()) dan mulai setiap proyek baru dari file itu.
  • Taruh pemanggilan handle() di bagian paling atas loop() dan jangan pernah meninggalkan perulangan yang memblokir lama di dalam loop().
  • Sambungkan ulang kalau Wi-Fi putus: pakai WiFi.setAutoReconnect(true) atau periksa koneksi secara berkala; board tanpa koneksi tidak bisa menerima pembaruan.
  • Tambahkan jendela perawatan di proyek deep sleep: board yang sedang tidur tidak mendengar permintaan OTA. Buat mode yang menunggu OTA selama 60 detik sebelum tidur kalau sebuah tombol ditahan ketika boot atau ada flag MQTT yang masuk. Untuk mode tidur, lihat artikel deep sleep ESP32.
  • Uji dulu di board kedua di mejamu: sebelum mengirim ke perangkat di lapangan, jalankan kode yang sama di board di sebelahmu; kalau board itu tersambung ke Wi-Fi dan muncul sebagai port jaringan, kode aman untuk dikirim.
  • Cetak nomor versi: simpan konstanta FW_VERSION di bagian atas kode dan tampilkan di halaman web atau layar; kamu akan selalu tahu versi mana yang berjalan di board mana.

OTA di ESP8266 dan Raspberry Pi Pico W

Kode ArduinoOTA dan ElegantOTA di panduan ini juga berjalan di board ESP8266 (NodeMCU, Wemos D1 Mini) dengan sedikit perubahan: ESP8266WiFi.h dipakai alih-alih WiFi.h, ESP8266WebServer alih-alih WebServer, dan port OTA-nya 8266. Di board ESP8266 dengan flash 4 MB, pilih opsi Flash Size yang menyisakan cukup ruang program untuk OTA. Di Raspberry Pi Pico W, core arduino-pico menyediakan dukungan ArduinoOTA; di sini program baru diunduh dulu ke sistem file LittleFS lalu disalin ke tempatnya ketika boot. Karena itu, di Pico W kamu harus menyediakan area sistem file yang lebih besar dari programmu di menu Flash Size. MicroPython tidak punya alat OTA siap pakai; kamu bisa menulis skrip kecil yang mengunduh dan mengganti file .py lewat jaringan, tapi itu bukan pembaruan dua partisi yang terverifikasi seperti di ESP32.

Ide proyek OTA

  • Sensor di plafon atau dinding: ubah ambang board yang mengukur suhu, kelembapan, dan gerakan tanpa menyentuh kabel.
  • Relay rumah pintar: perbarui aturan waktu board relay di panel listrik lewat OTA; taruh relay dalam keadaan aman di dalam onStart.
  • Perangkat Home Assistant: tambahkan fitur baru lewat jaringan ke sensor yang terhubung ke Home Assistant lewat MQTT.
  • Pengendali penyiraman kebun: ubah jadwal penyiraman dan ambang kelembapan tanah tanpa membuka kotak tahan air.
  • Progress bar di LCD: tampilkan nilai onProgress sebagai persentase dan batang di LCD 16x2; proyek OTA ESP32 di BlueGrays melakukan persis hal itu.
  • Pembaruan armada: buat beberapa board memeriksa server yang sama setiap malam untuk versi baru dengan HTTPUpdate.

Kesalahan umum dan cara memperbaikinya

GejalaKemungkinan penyebabSolusi
Tidak ada port jaringan di menu PortBoard di jaringan lain, mDNS diblokir, kode tidak memanggil ArduinoOTA.begin()Pakai jaringan 2,4 GHz yang sama, restart IDE, cek apakah IP tercetak di Serial Monitor
“No response from the ESP”delay() panjang di loop(), board sibuk, atau firewallPakai millis() alih-alih delay(), izinkan IDE di firewall
“Authentication Failed”Kata sandi OTA salahMasukkan nilai setPassword dari kode; kalau lupa, upload sekali lewat USB
“Not Enough Space” / Begin FailedSkema Huge APP atau No OTA, program tidak muat di area keduaPilih Minimal SPIFFS dan upload sekali lewat USB; perkecil programnya
Upload berhenti di tengah jalanSinyal lemah, tegangan turun, koneksi terputusDekatkan board ke router, pakai catu daya 5 V yang stabil, coba lagi; program lama tetap berjalan
Board tidak bergabung ke jaringan setelah uploadKode baru tidak punya Wi-Fi atau OTA, SSID salahPerbaiki lewat USB; mulai sekarang, mulai setiap proyek dari template OTA
“Wrong Magic Byte” atau error aktivasi di ElegantOTAYang dipilih merged.bin, bootloader.bin, atau file yang dikompilasi untuk chip lainUpload hanya file myproject.ino.bin
Ketika menyiapkan OTA pertama kali, biarkan board tetap tersambung USB dengan Serial Monitor terbuka; output onError memberi tahu dalam satu baris apakah masalahnya di kata sandi, ruang, atau koneksi. Begitu semuanya berjalan, kamu bisa mencabut kabelnya.

OTA adalah kunci untuk membawa proyek ESP32 dari meja kerja dan memasangnya di tempat sungguhan: begitu disiapkan dengan benar, perbaikan, fitur baru, dan perubahan ambang tiba tanpa kabel dalam hitungan detik. Di aplikasi BlueGrays, kamu akan menemukan proyek “Pembaruan OTA ESP32: Instal Firmware Tanpa Kabel (dengan Layar LCD)” yang menampilkan IP dan kemajuan di LCD, bersama proyek koneksi Wi-Fi, Web Server Asinkron, mDNS, dan NTP, masing-masing lengkap dengan skema rangkaian dan kode langkah demi langkah.

Pertanyaan umum

Apa itu OTA ESP32?

OTA (Over-The-Air) berarti meng-upload program baru ke ESP32 lewat Wi-Fi alih-alih kabel USB. Board menulis kode baru ke partisi program yang tidak dipakai, memverifikasinya, lalu me-restart dengan versi baru. Sketch pertama yang mendukung OTA perlu kamu upload sekali lewat USB.

Kenapa port jaringan ESP32 tidak muncul di Arduino IDE?

Penyebab paling umum adalah komputer dan board berada di jaringan yang berbeda, jaringan tamu yang mengisolasi perangkat, dan pemanggilan ArduinoOTA.begin() di kode yang tidak pernah dijalankan. Cek di Serial Monitor apakah board sudah mendapat IP, restart IDE, lalu tunggu beberapa detik.

Partition scheme mana yang harus kupilih untuk OTA ESP32?

Di board dengan flash 4 MB, pilih Default (area program 2 × 1,25 MB) atau, kalau programmu besar, Minimal SPIFFS (2 × 1,875 MB). Huge APP dan No OTA tidak punya area program kedua, jadi OTA tidak berfungsi dengan keduanya. Upload pertama setelah mengganti skema harus dilakukan lewat USB.

Apakah upload OTA yang terputus bisa membuat ESP32 mati total?

Tidak. Program baru ditulis ke partisi kosong dan partisi boot baru diganti setelah seluruh file diverifikasi. Kalau koneksi atau listrik terputus, board menjalankan program lama ketika boot dan kamu tinggal mencoba upload lagi.

Apakah Serial Monitor bisa dipakai ketika upload lewat OTA?

Port jaringan hanya untuk meng-upload kode; Serial Monitor tidak bekerja secara nirkabel. Untuk melihat pesan, kamu bisa membiarkan board tetap tersambung ke USB atau menampilkan informasinya di halaman web, layar, atau lewat MQTT.

Bagaimana cara mengatur kata sandi OTA ESP32?

Di ArduinoOTA, panggil ArduinoOTA.setPassword("password") sebelum begin(); IDE menanyakan kata sandi ini sebelum upload. Kalau tidak ingin kata sandinya terlihat di kode, berikan hash MD5-nya dengan setPasswordHash(). Di ElegantOTA, kamu melindungi halamannya dengan begin(&server, "user", "password").

Lihat semua proyek
Pembaruan OTA ESP32: Instal Firmware Tanpa Kabel (dengan Layar LCD)
#132Mahir
Premium

Pembaruan OTA ESP32: Instal Firmware Tanpa Kabel (dengan Layar LCD)

Di proyek ini, kamu belajar cara meng-upload firmware baru ke ESP32 lewat Wi-Fi tanpa kabel USB. Dengan library ArduinoOTA, ESP32 terlihat di jaringan dan otomatis tercantum sebagai bluegrays-ota di tab "Network port" Arduino IDE. Upload pertama dilakukan lewat USB, dan semua pembaruan berikutnya tanpa kabel; fitur penting untuk perangkat di lapangan. Layar LCD I2C menampilkan status Wi-Fi, alamat IP, nama host, persentase upload OTA, dan pesan error.

4.6(14)
22
Koneksi Wi-Fi STA ESP32 (dengan Layar LCD)
#127Mahir

Koneksi Wi-Fi STA ESP32 (dengan Layar LCD)

Di proyek ini, kita menyambungkan ESP32 ke jaringan Wi-Fi rumah dalam mode Station (STA) dengan cara yang aman dan tahan gangguan. Kita menyimpan SSID dan kata sandi di file secrets.h terpisah agar tidak bocor ke Git, menyiapkan mekanisme sambung ulang otomatis, dan menampilkan tingkat sinyal RSSI dan alamat IP di layar LCD I2C. LED bawaan bekerja sebagai indikator status. Ini adalah pengelola koneksi kelas produksi.

4.4(21)
34
Web Server Asinkron ESP32 (dengan Tampilan IP di LCD)
#129Mahir

Web Server Asinkron ESP32 (dengan Tampilan IP di LCD)

Di proyek ini, kita mengubah ESP32 menjadi web server asinkron yang bisa kamu kendalikan dari ponsel atau komputer di jaringan Wi-Fi yang sama. Berkat library ESPAsyncWebServer, server bisa memproses beberapa permintaan bersamaan (berbeda dengan WebServer.h klasik, yang memblokir pada satu permintaan). Kamu bisa membuka alamat IP ESP32 di browser dan mengklik tombol ON/OFF (rute /on dan /off) untuk menyalakan dan mematikan LED yang tersambung ke GPIO 5.

4.8(16)
26
mDNS ESP32: Mengakses Perangkat lewat bluegrays-esp.local (dengan Layar LCD)
#131Mahir
Premium

mDNS ESP32: Mengakses Perangkat lewat bluegrays-esp.local (dengan Layar LCD)

Di proyek ini, kita menambahkan layanan mDNS (Multicast DNS) ke ESP32, sehingga perangkat bisa diakses dengan nama host seperti bluegrays-esp.local, bukan alamat IP. Meskipun IP dari DHCP berubah, perangkat selalu bisa dijangkau dengan nama yang sama. Web server kecil di perangkat menerima perintah kendali LED dari browser lewat alamat http://bluegrays-esp.local/. Layar LCD I2C menampilkan nama host, alamat IP, dan status LED.

4.8(14)
23
Penghitung WebSocket ESP32 (2 Tombol + LCD + Web Real-Time)
#130Mahir
Premium

Penghitung WebSocket ESP32 (2 Tombol + LCD + Web Real-Time)

Di proyek ini, dua tombol yang tersambung ke ESP32 (GPIO 5 menghitung naik, GPIO 4 menghitung turun) mengubah sebuah penghitung. Nilainya langsung diperbarui di LCD I2C 16x2 sekaligus, lewat dukungan WebSocket ESPAsyncWebServer, di setiap browser yang tersambung tanpa memuat ulang halaman. Alih-alih polling HTTP, dipakai satu koneksi yang tetap terbuka, dan ESP32 mengirim nilai baru ke semua orang dengan ws.textAll().

4.5(14)
23
Jam Real-Time dari Internet lewat NTP ESP32
#128Mahir
Premium

Jam Real-Time dari Internet lewat NTP ESP32

ESP32 tersambung ke Wi-Fi dan mengambil waktu nyata dengan presisi milidetik dari server NTP (Network Time Protocol). Berkat fungsi configTzTime(), zona waktu Turki (TRT, UTC+3) otomatis diterapkan, dan pergantian DST di negara yang memakai waktu musim panas otomatis diatur dengan string POSIX TZ. Waktunya ditampilkan di Serial Monitor sekaligus di LCD I2C opsional. configTzTime() memulai layanan SNTP; sinkronisasi ulang berkala terjadi selama koneksi tersedia.

4.5(13)
21
HTTPClient + API Cuaca ESP32 (dengan Layar LCD)
#133Mahir
Premium

HTTPClient + API Cuaca ESP32 (dengan Layar LCD)

Di proyek ini, kita memakai ESP32 untuk melakukan panggilan REST API ke API cuaca (wttr.in) lewat internet dengan HTTPClient.h. Kita mengurai respons JSON yang diterima dengan ArduinoJson v7 dan menampilkan kota, suhu, kelembapan, cuaca, dan informasi angin di layar LCD I2C dalam bahasa Turki dan Inggris. wttr.in gratis dan tidak butuh kunci API; kamu cukup memasukkan nama kota apa pun untuk mengambil kondisi cuaca terkini kota itu. Data diperbarui otomatis setiap 30 menit.

4.7(13)
20
Deep Sleep ESP32: Hemat Baterai (OLED + Penghitung RTC RAM)
#135Mahir
Premium

Deep Sleep ESP32: Hemat Baterai (OLED + Penghitung RTC RAM)

Mode Deep Sleep ESP32 menurunkan konsumsi arus hingga ~10 µA dengan mematikan CPU dan sebagian besar periferal, sehingga sangat penting untuk perangkat IoT bertenaga baterai. Di proyek ini, kita memakai tiga sumber bangun yang berbeda: timer (15 detik), pin eksternal (EXT0, tombol GPIO 33), dan sentuhan (T0/GPIO 4). Variabel yang ditandai RTC_DATA_ATTR dipertahankan selama deep sleep; penghitung boot, penghitung bangun karena timer, dan penghitung bangun karena tombol terus dilacak.

4.3(10)
16