ESP32

🔄 ESP32 WiFi OTA 업데이트 시스템 구현하기

소나무기운 2025. 7. 1. 13:25
반응형

[2025/07/01] First Start.

소나무 기운 ,  전자제품 개발/생산

🔄 ESP32 WiFi OTA 업데이트 시스템 구현하기

IoT 개발에서 가장 중요한 기능 중 하나인 OTA(Over-The-Air) 펌웨어 업데이트를 ESP32로 구현해보겠습니다. 이 시스템을 사용하면 물리적 접근 없이도 웹 브라우저를 통해 원격으로 펌웨어를 업데이트할 수 있습니다.

 

💾 소스코드 (PlatformIO, Arduino예제)

ESP32-C3_Wifi-OTA.zip
0.02MB

 

 

🎯 시스템 개요

ESP32가 WiFi Access Point 역할을 수행하며, 클라이언트가 연결하여 웹 인터페이스를 통해 새로운 펌웨어를 업로드할 수 있는 시스템입니다.

 

✨ 주요 기능

📶 WiFi Access Point 생성
🌐 HTTP 웹 서버 구동
📊 실시간 업로드 진행률 표시
🔄 자동 재시작 및 검증

 

 

💻 코드 구현

1️⃣ 메인 파일 (main.ino)

#include "AP.h"
#include "BLE.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

void setup(void) {
  Serial.begin(115200);
  AP_SetRfMode(RF_MODE_AP);
}

void loop() {
  AP_Process();
}

 

 

2️⃣ Access Point 및 웹서버 구현 (AP.cpp)

#include "AP.h"
#include "common.h"
#include "html.h"

WebServer server(80);
uint8_t otaDone = 0;

// 📡 WiFi AP 초기화
void AP_Init(void) {
  WiFi.mode(WIFI_AP);
  bool apStarted = WiFi.softAP("ESP32-OTA", "password123", 1);
  
  esp_err_t result = esp_wifi_set_protocol((wifi_interface_t)ESP_IF_WIFI_AP, WIFI_PROTOCOL_11B);
  WiFi.setTxPower(WIFI_POWER_5dBm);
  
  Serial.println("📶 WiFi AP Started");
  Serial.print("📍 IP Address: ");
  Serial.println(WiFi.softAPIP());
  
  webServerInit();
}

// 🌐 웹서버 초기화
void webServerInit() {
  server.on("/update", HTTP_POST, []() { handleUpdateEnd(); }, []() { handleUpdate(); });
  server.onNotFound([]() {
    char dynamicHtml[4096];
    snprintf(dynamicHtml, sizeof(dynamicHtml), indexHtml, "ESP32-OTA", 0, 0);
    server.send(200, "text/html", dynamicHtml);
  });
  server.begin();
  Serial.println("🚀 Web Server Started on port 80");
}

// 📤 OTA 업로드 처리
void handleUpdate() {
  size_t fsize = UPDATE_SIZE_UNKNOWN;
  if (server.hasArg("size")) {
    fsize = server.arg("size").toInt();
  }
  
  HTTPUpload &upload = server.upload();
  
  if (upload.status == UPLOAD_FILE_START) {
    Serial.printf("📁 Upload Start: %s\n", upload.filename.c_str());
    if (!Update.begin(fsize)) {
      otaDone = 0;
      Update.printError(Serial);
    }
  } 
  else if (upload.status == UPLOAD_FILE_WRITE) {
    if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
      Update.printError(Serial);
    } else {
      otaDone = 100 * Update.progress() / Update.size();
      Serial.printf("📊 Progress: %d%%\n", otaDone);
    }
  } 
  else if (upload.status == UPLOAD_FILE_END) {
    if (Update.end(true)) {
      Serial.println("✅ Upload Successfully Completed");
    } else {
      otaDone = 0;
      Serial.println("❌ Upload Failed");
    }
  }
}

// ✅ 업로드 완료 처리
void handleUpdateEnd() {
  server.sendHeader("Connection", "close");
  if (Update.hasError()) {
    server.send(502, "text/plain", Update.errorString());
    Serial.println("❌ Update Error");
  } else {
    server.sendHeader("Refresh", "10");
    server.sendHeader("Location", "/");
    server.send(307);
    Serial.println("🔄 Restarting ESP32...");
    delay(1000);
    ESP.restart();
  }
}

// ⚡ AP 프로세스 처리
void AP_Process(void) {
  server.handleClient();
}

 

3️⃣ PlatformIO 사전 업로드 스크립트 (pre_upload_script.py)

Import("env")

def before_upload(source, target, env):
    print("🔧 Preparing for upload...")
    for f in source:
        print(f"📄 Source file: {f}")

env.AddPreAction("upload", before_upload)

 

 

 

 

🚀 사용 방법

1️⃣ 초기 설정

  1. 펌웨어 업로드: ESP32에 초기 펌웨어 업로드
  2. 시작: ESP32 재시작 후 WiFi AP 모드로 동작 시작

 

2️⃣ OTA 업데이트 과정

 

단계 설명 화면 예시
📶 WiFi 연결 스마트폰/PC에서 ESP32-OTA WiFi 검색 ![WiFi 목록]
🔐 접속 비밀번호 password123 입력하여 연결 ![비밀번호 입력]
🌐 웹 브라우저 http://192.168.4.1 접속 ![웹 페이지]  
📤 파일 업로드 새 펌웨어 파일(.bin) 선택 및 업로드 ![업로드 화면]
🔄 자동 재시작 업데이트 완료 후 ESP32 자동 재시작 ![완료 메시지]

 

 

⚙️ 기술적 특징

📡 WiFi 설정

  • 프로토콜: 802.11b (호환성 최적화)
  • 전송 출력: 5dBm (저전력)
  • 채널: 1번 고정
  • 기본 IP: 192.168.4.1

 

🔒 보안 고려사항

⚠️ 주의사항
실제 제품에서는 더 강력한 비밀번호 사용 권장
HTTPS 적용 고려

인증 메커니즘 추가 검토


🐛 에러 처리

  • ❌ 업로드 실패 시 502 에러 응답
  • 📊 진행률 실시간 추적 (otaDone 변수)
  • 🖥️ 시리얼 모니터를 통한 디버깅 정보 출력

🔧 platformio.ini 설정 예시

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
extra_scripts = pre_upload_script.py

; OTA 관련 설정
upload_port = COM3
monitor_port = COM3

; 라이브러리 의존성
lib_deps = 
    ESP32WebServer

 

 

 

🚀 확장 가능성

이 기본 구조를 바탕으로 다음과 같은 기능들을 추가할 수 있습니다:

📱 추가 기능

  • 🔵 BLE 지원: Bluetooth를 통한 OTA 업데이트
  • 🎨 웹 인터페이스 개선: 진행률 표시, 파일 검증
  • ⏪ 롤백 기능: 업데이트 실패 시 이전 버전으로 복구
  • 📋 버전 관리: 펌웨어 버전 정보 표시 및 관리
  • 🔐 보안 강화: 사용자 인증, 파일 검증

💡 실제 적용 예시

// 버전 정보 추가
#define FIRMWARE_VERSION "v1.2.3"
#define BUILD_DATE __DATE__ " " __TIME__

void printSystemInfo() {
  Serial.println("===============================");
  Serial.printf("🔧 Firmware Version: %s\n", FIRMWARE_VERSION);
  Serial.printf("📅 Build Date: %s\n", BUILD_DATE);
  Serial.printf("💾 Free Heap: %d bytes\n", ESP.getFreeHeap());
  Serial.println("===============================");
}

 

 

 

 

📝 마무리

마무리 1ESP32의 OTA 기능을 활용하면 IoT 디바이스의 유지보수가 훨씬 편리해집니다. 특히 접근이 어려운 곳에 설치된 디바이스의 경우 무선 업데이트는 필수적인 기능입니다.

 

 

🎯 핵심 포인트

마무리5

 

  • ✅ 간단한 웹 인터페이스로 쉬운 업데이트
  • ✅ 실시간 진행률 모니터링
  • ✅ 자동 검증 및 재시작
  • ✅ 확장 가능한 구조

이 예제를 기반으로 여러분의 프로젝트에 맞는 OTA 시스템을 구축해보세요! 🚀

💡 TIP: 개발 중에는 시리얼 모니터를 활용하여 업데이트 과정을 실시간으로 모니터링하는 것을 추천합니다.

 

 
 

 

 

틀린 부분이나 질문은 댓글 달아주세요.

즐거운 하루 보내세요. 감사합니다.

 

 

반응형