Konstruowanie nowych układów jest zajęciem twórczym, wymagającym sporo czasu. Często udaje się wykonać wersję minimum i z braku czasu pozostawiamy działający układ z planami na jego rozbudowę. Na planach się jednak kończy, bo aktualizacja oprogramowania wymaga demontażu układu, lub wpinania się do niego z laptopem. Istnieje proste rozwiązanie tego problemu, które zaoszczędzi nam czasu i problemów z fizycznym dostępem do układu. Metoda ta nazywa się OTA programming (Over-the-air programming), czyli bezprzewodowa aktualizacja oprogramowania.

Czas na konkrety

W Arduino IDE ESP32 mamy gotowy przykładowy kod umożliwiający aktualizację oprogramowania.  Wystarczy z przykładów wybrać ArduinoOTA/BasicOTA, wgrać szkic i gotowe. Minusem tego rozwiązania (przykładowego szkicu) jest to, że OTA jest głównym celem. Możemy dopisać własny fragment kodu, ale robi się z tego niezły "makaron". Proponuję posprzątać w kodzie tak, by OTA działało, ale nie zasłaniało nam właściwego pisanego programu. Wystarczy dodać nowy plik (zakładkę) do projektu. Ja nazwałem ten plik wifiOTA. Jego zawartość zamieszczam poniżej:

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

const char* ssid = "SSID";
const char* password = "HASŁO";

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

  // Tu podajemy nazwę naszego nowego projektu (tak będzie widoczny w ArduinoIDE)
  ArduinoOTA.setHostname("NowyProjektTestowy");

  // Jeżeli chcemy hasło, korzystamy z jednej z poniższych linii
   //ArduinoOTA.setPassword("admin");
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";
    })
    .onEnd([]() {
      Serial.println("\nEnd");
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .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 obslugaOTA(){
      ArduinoOTA.handle();
    }

W powyższym pliku musimy ustawić parametry naszej sieci WiFi oraz nazwę projektu. Nazwa projektu, to dowolna nazwa pod jaką nasz układ będzie widoczny w sieci WiFi przez ArduinoIDE. W sytuacji, gdy chcemy zabezpieczyć nasz układ przed nieautoryzowanym dostępem możemy skorzystać z hasła. Będzie wymagane podczas programowania układu. Hasło możemy podać w sposób jawny lub korzystając z kodowania MD5. Wystarczy odkomentować jedną z instrukcji. Pozostało tylko wykorzystanie OTA we własnym projekcie. Dodajemy do funkcji setup inicjalizację OTA, a do funkcji loop obsługę OTA. Wgrywamy program "normalne" poprzez USB i od tego momentu możemy wgrywać program poprzez sieć WiFi.

void setup() {
  beginOTA();
}

void loop() {
  obslugaOTA();
}

Jak widać na powyższym przykładzie w miejscu przeznaczonym na właściwy kod naszego projektu mamy porządek. Wystarczyły dwie instrukcje i już mamy załatwione programowanie poprzez sieć, przy okazji nasz układ ma już zaimplementowaną obsługę WiFi, z której można korzystać w kodzie. Poniżej zrzut pokazujący , jak widoczny jest nasz układ w ArduinoIDE.

Podsumowanie

Jak widać na powyższym przykładzie zdalne programowanie jest proste w implementacji, zwłaszcza że cały niezbędny kod mamy gotowy do użycia. Przeniesienie wszystkiego do odrębnego pliku ma jeszcze jedną zaletę - bez problemu możemy skopiować przygotowany plik do kolejnych projektów zmieniając tylko nazwę, pod jaką układy będą widoczne w sieci.