본문 바로가기
Hardware/MCU(Arduino,ESP8266)

ESP8266 펌웨어 무선(OTA) 업데이트

by lovey25 2020. 9. 2.
반응형

ESP8266 Wifi 모듈에서 스케치를 무선으로 업데이트하는 OTA(Over the Air) 사용방법입니다.

OTA는 무선으로 펌웨어나 설정, 보안 사항 등 변경 내용을 무선으로 배포하는 방식을 총칭하는 용어인데요. ESP8266 모듈에서도 이 스마트해 보이는 기능을 간단하게 사용할 수 있습니다.

제가 요즘 많이 사용하는 ESP01 모듈의 경우 USB 포트가 없기 때문에 코드를 수정해서 올릴 때마다 프로그래밍 보드에 연결하는 수고를 들여야만 합니다. 게다가 만약 어떤 프로젝트의 부품으로 패키징이 완성된 어떤 디바이스에 사용 중이라면 코드를 변경하기 위해서 조립된 패키징을 열어서 ESP 꺼내와서 컴퓨터에 연결해야지 업데이트를 할 수 있기 때문에 여간 불편한 게 아닙니다. 이럴 때 OTA를 사용하면 컴퓨터에 직접 연결할 필요 없이 인터넷만 연결되어 있다면 바로 업데이트를 할 수 있는데요. 그 방법 알아보겠습니다.

OTA를 위한 기본 코드 업로드

OTA는 ESP모듈의 메모리 중 일부분을 임시공간으로 사용하고 와이파이로 업데이트 명령이 들어오면 신규 펌웨어 이미지를 받아 기존 펌웨어에 업데이트 하는 방식으로 동작을 합니다. 그래서 이런 OTA 관련 동작을 하는 기본적인 코드가 필요합니다. 

아래 예제코드는 Arduino IDE에 ESP8266 보드 매니저를 설치하면 기본 설치되는 OTA Basic 예제인데요. OTA를 수행하는데 필요한 기본 루틴이 포함되어 있습니다. 일단 한 번은 업로드가 되어야 OTA가 동작할 테니 USB 포트로 ESP 모듈을 연결하고 스케치를 업로드시켜줍니다. 그리고 앞으로 OTA를 통한 스케치 업데이트를 계속적으로 이용하려면 개발하는 스케치에도 이 루틴은 기본적으로 포함되어야 하겠죠.

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK  "your-password"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  // ArduinoOTA.setHostname("myesp8266");

  // No authentication by default
  ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    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();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  ArduinoOTA.handle();
}

여기서 7,8행은 각자 사용하시는 네트워크 설정대로 SSID와 비번으로 교체해주시면 되겠습니다.

Arduiono IDE에서 OTA 업로드

먼저 Arduino IDE에서 ESP8266 OTA 업로드 방법입니다.

Arduino IDE에서 ESP8266 칩 개발을 위해서는 ESP8266 보드메니저가 있어야 하는데요 아직 설치되어 있지 않다면 "환경설정 > 추가적인 보드 매니저 URLs"에 아래 주소를 입력하고 설치할 준비를 해줍니다.
(http://arduino.esp8266.com/stable/package_esp8266com_index.json)

그리고 "툴 > 보드 > 보드 매니저" 메뉴로 이동해서 esp8266 패키지를 설치합니다.

검색창에 "esp8266"이라고 검색해서 설치를 눌러주시면 됩니다.

설치가 되었다면 "툴 > 보드 > ESP8266 Boards"메뉴에서 Generic ESP8266 Module"을 선택해서 ESP8266 개발환경으로 변경해 줍니다. 보드는 사용하시는 제품에 맞게 골라주시면 되겠죠.

그리고 처음으로 OTA 스케치를 업로드하기위해서 ESP모듈이 연결된 포트를 지정해줍니다.

저는 아두이노 우노 보드를 ESP01 모듈 프로그래밍에 사용하고 있어서 COM11 포트에 Arduino Uno라고 표시되고 있으니 참고해주세요.

이제 준비가 끝났습니다. 지금부터는 원래 스케치를 업로드하는 것과 동일하게 업로드 버튼 꾹 눌러주시면 OTA 업데이트가 시작됩니다.

저는 위 코드에서 32행의 비밀번호 인증부분을 활성화했기 때문에 OTA 업로드 때마다 비밀번호를 확인하게 됩니다. 그래서 아래와 같은 창이 뜨는데요. 스케치에서 설정한 비밀번호 "admin"을 입력해주면 되겠습니다.

그럼 업로드가 무선으로 샤라라~ 되어야 하는데.. 어?! 뭔가 안됩니다.

시리얼 모니터를 연결해보면 ESP 모듈도 OTA 연결에 반응은 하는데 새로운 펌웨어를 전송하는 연결에 문제가 있는 것 같습니다. 구글링 해보니 방화벽이 원인일 수 있다고 하네요.

저는 윈도우 환경을 사용하는데요. 의심스러운 방화벽을 끄고 다시 업로드해보겠습니다.

진행률이 쭉쭉 올라가면서 깔끔하게 업로드가 완료되었습니다. 업로드가 된 후에는 알아서 모듈이 리부팅을 해줍니다.

앞으로도 계속 OTA 업로드를 사용해야 하니 저는 윈도 방화벽에 ESP8266 보드가 연결된 IP에 대해서 모든 포트를 열어주는 예외 규칙을 추가했습니다.

PlatformIO에서 OTA 업로드

Arduino IDE에서 간단하게 OTA 업로드가 가능했었는데요. 주로 코드 작성을 하는 환경은 VS Code이기 때문에 PlatformIO에서도 OTA 업로드 설정을 해 두겠습니다.

PlatformIO의 OTA 관련 자세한 내용은 아래 공식 문서를 참고하시면 되는데요.

 

Espressif 8266 — PlatformIO 5.0.0b3 documentation

There are two file systems for utilizing the on-board flash on the ESP8266: SPIFFS and LittleFS. They provide a compatible API but have incompatible on-flash implementations, so it is important to choose one or the per project as attempting to mount a SPIF

docs.platformio.org

중요한 내용만 발췌하자면,

PlatformIO.ini에서 기존에 ESP모듈 업로드에 사용하시는 설정에 아래 내용만 추가해 주시면 됩니다. 

upload_protocol = espota
upload_port = [IP주소]
upload_flags =
  --port=8266
  --auth=admin

제가 사용하는 ESP01 모듈 기준으로 아래와 같이 Arduino IDE 보다도 더 간단하게 업로드 성공했습니다.

이제는 조립 다 해놓은 케이스 열어서 코드 업데이트하고 다시 조립하는 귀찮은 일은 안 해도 돼서 너무 좋네요.

 

끝!

반응형

댓글