บทความ: ESP32 OTA Updates - อัปเดตฟาร์มแวร์ผ่าน WiFi แบบไม่ต้องเสียบสาย

เรียนรู้วิธีอัปเดตโปรแกรม ESP32 ผ่าน WiFi ด้วยเทคนิค OTA (Over-The-Air) ปลดล็อกความสะดวกในการพัฒนาและบำรุงรักษา IoT devices ของคุณ ไม่ต้องถอดกล่อง ไม่ต้องเสียบ USB

📅 7 มีนาคม 2026⏱️ 20 นาที🎯 ระดับกลาง

🎯 OTA (Over-The-Air) คืออะไร?

OTA (Over-The-Air) เป็นเทคโนโลยีที่ช่วยให้คุณสามารถอัปเดตฟาร์มแวร์ (firmware) ของ ESP32 ผ่านทาง WiFi โดยไม่ต้องเชื่อมต่อสาย USB หรือเสียบสาย Serial Cable เข้าไปในบอร์ด

ลองนึกภาพว่าคุณมี IoT device ติดตั้งอยู่บนเพดาน หรืออยู่ในกล่องที่ปิดสนิท การถอดออกมาเพื่ออัปเดตโปรแกรมก็เป็นเรื่องยาก แต่ด้วย OTA คุณสามารถอัปเดตได้ทันทีผ่าน WiFi ได้เลย!

💡 จุดเด่นของ OTA: ช่วยประหยัดเวลาและความยุ่งยากในการบำรุงรักษา IoT devices จำนวนมาก โดยเฉพาะที่ติดตั้งในที่เข้าถึงยาก

🚀 ทำไมต้องใช้ OTA Updates?

🔧

ไม่ต้องถอดอุปกรณ์

อัปเดตฟาร์มแวร์ได้แม้ว่าอุปกรณ์จะติดตั้งอยู่บนเพดาน ฝั่งผนัง หรืออยู่ในกล่องที่ปิดสนิท

⏱️

ประหยัดเวลา

อัปเดตหลายบอร์ดพร้อมกันผ่านเครือข่าย ไม่ต้องเสียบสายทีละตัว

📦

ลดต้นทุน

ไม่ต้องเดินทางไปยังตำแหน่งติดตั้ง IoT device แต่ละตัว

🔄

อัปเดตได้ตลอดเวลา

แก้ไข bug หรือเพิ่มฟีเจอร์ใหม่ได้ทันที โดยไม่กระทบผู้ใช้งาน

📋 ข้อกำหนดเบื้องต้น (Prerequisites)

🛠️ Hardware

  • ESP32 Board (รุ่นใดก็ได้: DevKit, NodeMCU, Wroom, Wrover)
  • สาย USB สำหรับอัปโหลดครั้งแรก
  • เครือข่าย WiFi 2.4GHz (ต้องเชื่อมต่อเครือข่ายเดียวกับคอมพิวเตอร์)

💻 Software

  • Arduino IDE 2.x หรือ PlatformIO
  • ESP32 Board Library (ล่าสุด)
  • ArduinoOTA library (มีให้ใช้แล้วใน Arduino IDE)
  • Network Tools อย่าง Advanced IP Scanner หรือ nmap

⚠️ ข้อจำกัดที่ต้องรู้

  • • OTA partition ต้องมีขนาดอย่างน้อย 1.5 เท่าของ sketch
  • • ครั้งแรกต้องอัปโหลดผ่าน USB เสมอ
  • • WiFi ต้องเสถียร ไม่งั้นอัปเดตจนกลางคันอาจทำให้บอร์ดเสียหาย
  • • OTA ขนาดใหญ่อาจใช้เวลานาน (ขึ้นกับความเร็ว WiFi)

🔥 ตัวอย่างที่ 1: Basic OTA (OTA พื้นฐาน)

Step 1: อัปโหลดโค้ดครั้งแรกผ่าน USB

อัปโหลดโค้ดนี้ผ่านสาย USB ครั้งแรกเพื่อเปิดใช้งาน OTA บน ESP32

#include <WiFi.h>
#include <ESPmDNS.h>
#include <ArduinoOTA.h>

// ตั้งค่า WiFi
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");

  // เชื่อมต่อ WiFi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  // ตั้งค่า OTA Port (Default: 3232)
  ArduinoOTA.setPort(3232);

  // ตั้งค่าชื่อ Hostname (จะแสดงใน Arduino IDE)
  ArduinoOTA.setHostname("ESP32-OTA-Device");

  // ตั้งค่ารหัสผ่าน (Optional)
  ArduinoOTA.setPassword("admin123");

  // ตั้งค่า callback functions
  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

    Serial.println("Start updating " + type);
  });
  
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });

  ArduinoOTA.begin();
}

void loop() {
  ArduinoOTA.handle();  // ต้องเรียกใน loop เสมอ
}

Step 2: ตรวจสอบ IP Address

เปิด Serial Monitor (115200 baud) และจด IP address ของ ESP32:

Ready
IP address: 192.168.1.100

📡 ตัวอย่างที่ 2: อัปเดตผ่าน Arduino IDE

Step 1: เลือก Port ผ่าน WiFi

หลังจากอัปโหลดโค้ด Basic OTA แล้ว ให้:

  1. เปิด Arduino IDE
  2. ไปที่ Tools → Port
  3. คุณจะเห็น IP address ของ ESP32 ปรากฏขึ้น เช่น: esp32-ota-device at 192.168.1.100
  4. คลิกเลือก Port นั้น

Step 2: แก้ไขโค้ด

ตอนนี้ลองแก้โค้ดใน loop() ให้ทำอย่างอื่น:

void loop() {
  ArduinoOTA.handle();  // ต้องเรียกใน loop เสมอ
  
  // ลองเพิ่มโค้ดนี้
  static unsigned long lastPrint = 0;
  if (millis() - lastPrint > 5000) {
    Serial.println("OTA is working! Device running...");
    lastPrint = millis();
  }
}

Step 3: อัปเดตผ่าน WiFi

  1. คลิก Upload ใน Arduino IDE (หรือกด Ctrl+U)
  2. Arduino IDE จะค้นหา ESP32 ผ่าน WiFi แทน USB
  3. ดู Process ที่ Serial Monitor หรือ Arduino IDE
  4. เมื่อเสร็จสิ้น ESP32 จะรีสตาร์ทใหม่พร้อมโค้ดใหม่

✅ สำเร็จ! ตอนนี้คุณสามารถอัปเดต ESP32 ได้โดยไม่ต้องเสียบสาย USB แล้ว! ทุกครั้งที่อัปโหลดโค้ดใหม่ ระบบจะ OTA อัปเดตให้อัตโนมัติ

🌐 ตัวอย่างที่ 3: OTA ผ่าน Web Server (Browser)

💡 ข้อดี: อัปเดตได้โดยไม่ต้องใช้ Arduino IDE เหมาะสำหรับให้ลูกค้าอัปเดตเองผ่านหน้าเว็บ

โค้ด Web Server OTA

#include <WiFi.h>
#include <WebServer.h>
#include <ESP32httpUpdate.h>

WebServer server(80);

const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// หน้าเว็บสำหรับอัปเดต
const char* serverIndex = 
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Update'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
"$.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!'); "
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";

void setup(void) {
  Serial.begin(115200);

  // เชื่อมต่อ WiFi
  WiFi.begin(ssid, password);
  Serial.println("");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  // รับส่งไฟล์ HTML
  server.on("/", HTTP_GET, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/html", serverIndex);
  });
  
  // Handler สำหรับอัปเดต
  server.on("/update", HTTP_POST, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
    ESP.restart();
  }, []() {
    HTTPUpload& upload = server.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.printf("Update: %s\n", upload.filename.c_str());
      if (!Update.begin(UPDATE_SIZE_UNKNOWN)) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_END) {
      if (Update.end(true)) {
        Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
      } else {
        Update.printError(Serial);
      }
    }
  });

  server.begin();
}

void loop(void) {
  server.handleClient();
  delay(2);
}

วิธีใช้งาน

  1. อัปโหลดโค้ดนี้ครั้งแรกผ่าน USB
  2. เปิด Browser และไปที่ http://ESP32_IP_ADDRESS
  3. คุณจะเห็นหน้าเว็บสำหรับอัปเดต
  4. คลิก Choose File และเลือกไฟล์ .bin จาก Arduino IDE
  5. ไฟล์ .bin จะอยู่ที่: C:\Users\YOUR_USER\AppData\Local\Temp\arduino_build_xxxxxx.ino.bin
  6. คลิก Update และรอสักครู่
  7. ESP32 จะรีสตาร์ทใหม่พร้อมฟาร์มแวร์ใหม่!

🔬 เทคนิคขั้นสูง (Advanced OTA Tips)

1. การตรวจสอบเวอร์ชันฟาร์มแวร์

เพิ่มระบบตรวจสอบเวอร์ชันเพื่อป้องกันการอัปเดตซ้ำ:

#define FIRMWARE_VERSION "1.0.2"

void setup() {
  Serial.begin(115200);
  Serial.println("Firmware Version: " + String(FIRMWARE_VERSION));
  
  // OTA setup code...
}

2. การ Rollback กลับเวอร์ชันเก่า

หากอัปเดตใหม่แล้วมีปัญหา สามารถ rollback ได้:

// ใน setup() หลังจาก OTA begin
if (!Update.isFinished()) {
  // ถ้า OTA ไม่สำเร็จ ให้ rollback
  Update.abort();
  Serial.println("OTA failed! Rolling back...");
  ESP.restart();
}

// หรือสั่ง rollback เอง
// Update.rollback();

3. การจัดการ Partition Table

ใช้ Tools → Partition Scheme ใน Arduino IDE:

  • Default (4MB with spiffs): OTA 1.2MB
  • Minimal SPIFFS (1.9MB APP with OTA): OTA 1.2MB
  • Huge APP (3MB No OTA/SMIFFS): ไม่รองรับ OTA

4. การทำ HTTPS OTA (ปลอดภัยกว่า)

ใช้ ESP32httpUpdate กับ HTTPS:

WiFiClientSecure client;
// ข้ามการตรวจสอบ certificate (สำหรับทดสอบ)
client.setInsecure();  

t_httpUpdate_return ret = httpUpdate.update(client, "https://example.com/firmware.bin");

switch(ret) {
  case HTTP_UPDATE_FAILED:
    Serial.println("Update failed: " + httpUpdate.getLastErrorString());
    break;
  case HTTP_UPDATE_NO_UPDATES:
    Serial.println("No updates available");
    break;
  case HTTP_UPDATE_OK:
    Serial.println("Update OK!");
    break;
}

🛠️ ปัญหาที่พบบ่อยและวิธีแก้ไข

❌ ปัญหา: OTA Port ไม่ปรากฏ

สาเหตุ: อาจเป็นเพราะ Firewall บล็อก หรือ ESP32 ไม่อยู่ในเครือข่ายเดียวกัน

วิธีแก้: ปิด Firewall/พิจารณาเพิ่ม Port 3232 ใน allowlist หรือใช้ static IP

❌ ปัญหา: Update Failed / Auth Failed

สาเหตุ: ใส่รหัสผ่านผิด หรือ sketch ขนาดใหญ่เกินไป

วิธีแก้: ตรวจสอบรหัสผ่าน และ Partition Scheme

❌ ปัญหา: WiFi Disconnect ระหว่างอัปเดต

สาเหตุ: สัญญาณ WiFi ไม่ดี หรือ interference จากอุปกรณ์อื่น

วิธีแก้: ย้ายใกล้ Access Point/ใช้ WiFi คุณภาพสูง หรือเพิ่ม retry logic

⚠️ ปัญหา: ESP32 ค้าง หลังอัปเดต

สาเหตุ: ฟาร์มแวร์ใหม่มี bug หรือใช้ RAM จนเต็ม

วิธีแก้: รอ 30 วินาทีให้ watchdog reset หรือถอดใส่ไฟใหม่

❌ ปัญหา: OTA เริ่มไม่ได้หลัง Power Cycle

สาเหตุ: ลืมเรียก ArduinoOTA.handle() ใน loop()

วิธีแก้: ตรวจสอบให้แน่ใจว่ามี ArduinoOTA.handle(); ใน loop()

✅ สรุป

ในบทความนี้คุณได้เรียนรู้:

  • ✅ หลักการทำงานของ OTA (Over-The-Air Updates)
  • ✅ วิธีอัปเดต ESP32 ผ่าน Arduino IDE โดยไม่ใช้ USB
  • ✅ วิธีสร้าง Web Server สำหรับอัปเดตผ่าน Browser
  • ✅ เทคนิคขั้นสูง: version checking, rollback, HTTPS OTA
  • ✅ การแก้ปัญหาที่พบบ่อย

🚀 ถัดไป

ลองนำไปประยุกต์ใช้กับ โปรเจกต์ IoT จริง หรือดู วิธีประหยัดแบตเตอรี่ด้วย Deep Sleep

CynoIoT

Platform สำหรับจัดการและควบคุม IoT devices ที่ง่ายและปลอดภัย

ติดต่อเรา

  • Email: support@cynoiot.com
  • Line: @cynoiot

© 2026 CynoIoT. All rights reserved.