OTA-прошивка ESP32 по Wi-Fi — обновляем датчики в теплице без кабеля и поездок

Админ·12 апреля 2026 г.·7 мин чтения

Пошаговая инструкция: добавляем OTA-обновление в любой проект на ESP32. Веб-форма для загрузки прошивки через браузер, защита паролем и автооткат — всё за 80 строк кода.

OTA-прошивка ESP32 по Wi-Fi — обновляем датчики в теплице без кабеля и поездок

В предыдущих статьях серии «Клуб самоделкиных» мы собрали метеостанцию, автополив, весы и GPS-трекер. У всех проектов общая боль: чтобы поправить одну строчку в коде, нужно ехать в поле с ноутбуком и USB-кабелем. Зимой — ещё ладно, техника рядом. А летом, когда ESP32 стоит в теплице за 15 километров? Когда датчик на удалённом пастбище? Когда трекер в кабине комбайна, который не стоит на месте?

OTA (Over-The-Air) решает эту проблему: вы загружаете новую прошивку по Wi-Fi прямо из дома. Открыли браузер, выбрали файл, нажали «Загрузить» — через 30 секунд ESP32 перезагрузился с новым кодом. Без поездки, без кабеля, без потерянного рабочего дня.

Как это работает: 30 секунд теории

ESP32 запускает крошечный веб-сервер на порту 80. Вы открываете его IP-адрес в браузере и видите форму загрузки. Выбираете скомпилированный файл прошивки (.bin), нажимаете «Загрузить». ESP32 принимает файл, записывает его во второй раздел flash-памяти, проверяет целостность и перезагружается. Если новая прошивка не стартует — ESP32 откатывается на предыдущую. Всё это встроено в библиотеку ArduinoOTA и модуль Update — ничего дополнительного ставить не нужно.

Важно: OTA работает через Wi-Fi. ESP32 должен быть подключён к той же сети, что и ваш компьютер, или быть доступен через интернет (об этом — в конце статьи).

Подготовка: 5 минут на библиотеку

Нам понадобятся две встроенные библиотеки, которые уже есть в пакете ESP32 для Arduino IDE: WebServer и Update. Дополнительно ничего устанавливать не нужно — если вы уже прошивали ESP32 по USB (а если вы читаете эту статью — прошивали), всё готово.

Единственное ограничение: прошивка должна поместиться в половину flash-памяти ESP32. У стандартной платы 4 МБ flash, из которых ~1.5 МБ доступно для приложения. Это более чем достаточно для любого IoT-проекта с датчиками, MQTT и Telegram.

Код: OTA-сервер в 80 строк

Берём любой существующий проект — метеостанцию, автополив, трекер — и добавляем к нему OTA-модуль. Ниже — полный рабочий код. Его можно встроить в любой скетч.

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

// === НАСТРОЙКИ === //
const char* WIFI_SSID     = "Название_вашей_сети";
const char* WIFI_PASSWORD  = "пароль_от_wifi";
const char* OTA_USERNAME   = "admin";
const char* OTA_PASSWORD   = "секретный_пароль_ota";

WebServer server(80);

// Страница загрузки прошивки
const char* uploadPage = R"rawliteral(
<!DOCTYPE html><html><head>
<meta charset="utf-8">
<title>OTA Update</title>
<style>
  body{font-family:sans-serif;max-width:480px;margin:40px auto;padding:20px}
  h2{color:#184225} input[type=file]{margin:16px 0}
  button{background:#2E7D4A;color:#fff;border:0;padding:12px 24px;
    border-radius:8px;font-size:16px;cursor:pointer}
  button:hover{background:#184225}
  .progress{width:100%;height:24px;background:#eee;border-radius:12px;margin:16px 0}
  .bar{height:100%;background:#2E7D4A;border-radius:12px;transition:width 0.3s}
</style>
</head><body>
<h2>🔄 Обновление прошивки</h2>
<form method="POST" action="/update" enctype="multipart/form-data">
  <input type="file" name="firmware" accept=".bin"><br>
  <button type="submit">Загрузить прошивку</button>
</form>
<p id="status"></p>
</body></html>
)rawliteral";

void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 40) {
    delay(500);
    attempts++;
  }
  Serial.println("IP: " + WiFi.localIP().toString());

  // Авторизация: без пароля прошивку не зальёшь
  server.on("/", HTTP_GET, []() {
    if (!server.authenticate(OTA_USERNAME, OTA_PASSWORD)) {
      return server.requestAuthentication();
    }
    server.send(200, "text/html", uploadPage);
  });

  // Приём прошивки
  server.on("/update", HTTP_POST,
    // По завершении загрузки
    []() {
      server.send(200, "text/plain",
        Update.hasError() ? "ОШИБКА обновления!" : "OK! Перезагрузка...");
      delay(1000);
      ESP.restart();
    },
    // Приём файла чанками
    []() {
      HTTPUpload& upload = server.upload();
      if (upload.status == UPLOAD_FILE_START) {
        Serial.println("OTA: начало загрузки");
        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.println("OTA: успешно, " + String(upload.totalSize) + " байт");
        } else {
          Update.printError(Serial);
        }
      }
    }
  );

  server.begin();
}

void loop() {
  server.handleClient();
  // ... ваш основной код (датчики, MQTT, алерты) ...
}

Что менять: WIFI_SSID и WIFI_PASSWORD — данные Wi-Fi. OTA_USERNAME и OTA_PASSWORD — логин и пароль для страницы обновления. Никогда не оставляйте OTA без пароля — иначе любой в той же сети сможет залить произвольный код на ваше устройство.

Первая прошивка: единственный раз по кабелю

Парадокс OTA: чтобы прошивать удалённо, первый раз нужно прошить по USB. Это логично — ESP32 «из коробки» не знает о вашей Wi-Fi сети и не имеет OTA-сервера.

Подключаете ESP32 кабелем, заливаете код через Arduino IDE — как обычно. После перезагрузки открываете Serial Monitor, видите строку IP: 192.168.1.XXX. Запоминаете адрес.

Открываете браузер, вводите http://192.168.1.XXX. Появляется окно ввода логина/пароля (те, что в коде). Вводите — видите страницу с формой загрузки. Готово, OTA работает.

Как отправить обновление

Допустим, вы хотите изменить порог температуры в метеостанции — было 35°C, ставите 38°C. Меняете строку в коде, нажимаете в Arduino IDE: Sketch → Export Compiled Binary (или Ctrl+Alt+S). В папке проекта появится файл *.ino.esp32.bin.

Открываете браузер, заходите на IP ESP32, выбираете этот .bin файл, жмёте «Загрузить прошивку». Через 20–40 секунд ESP32 перезагрузится с новым кодом. Вы даже не вставали со стула.

Если новая прошивка «сломалась» (не стартует Wi-Fi, зависла) — ESP32 автоматически откатится на предыдущую версию. Это встроенная защита модуля Update.

Интеграция с существующими проектами

Добавить OTA в уже работающий скетч — три шага:

  • Шаг 1. Добавьте #include <WebServer.h> и #include <Update.h> в начало файла
  • Шаг 2. Скопируйте блок с server.on("/", ...) и server.on("/update", ...) в вашу функцию setup(), после подключения к Wi-Fi
  • Шаг 3. Добавьте server.handleClient(); в начало loop()

Всё. Ваш проект продолжает работать как раньше — датчики, алерты, MQTT — но теперь вы можете обновить код удалённо.

Один нюанс: WebServer и HTTPClient используют один и тот же стек Wi-Fi. Если у вас одновременно идёт отправка в Telegram и кто-то открыл OTA-страницу — ничего не сломается, но загрузка может быть чуть медленнее. На практике это незаметно.

Безопасность: три обязательных правила

OTA — это мощный инструмент, но и потенциальная уязвимость. Без защиты любой человек в вашей Wi-Fi сети может залить произвольный код на устройство. Три правила, которые нельзя игнорировать:

  • Пароль обязателен. Код выше использует HTTP Basic Auth. Это минимум. Без пароля — не деплойте
  • Не выставляйте OTA-порт наружу. ESP32 должен быть доступен только из локальной сети. Если нужен доступ из интернета — через VPN или SSH-туннель, но не через проброс порта на роутере
  • Обновляйте пароль периодически. Его можно зашить в код и менять при каждом обновлении — иронично, но обновление пароля делается через OTA

OTA из интернета: когда ESP32 далеко

Локальная сеть — это хорошо, когда теплица рядом с домом. А если ESP32 стоит на поле, подключённом к мобильному роутеру с SIM-картой? Или в коровнике на другом конце района?

Два рабочих варианта:

VPN. WireGuard на вашем домашнем сервере или VPS. ESP32 подключается к VPN-сети — и вы видите его IP из любой точки мира. Настройка WireGuard на ESP32 — тема отдельной статьи, но это вполне реально.

HTTP-pull. Вместо того чтобы вы заходили на ESP32, ESP32 сам проверяет сервер на наличие обновлений. Раз в час делает GET-запрос на ваш сервер: «Есть новая прошивка?» Если есть — скачивает и обновляется. Это называется «pull OTA» и используется в промышленных IoT-системах.

// Pull OTA — ESP32 сам проверяет обновления
#include <HTTPClient.h>
#include <Update.h>

void checkForUpdate() {
  HTTPClient http;
  http.begin("http://ваш-сервер.ru/firmware/latest.bin");
  http.addHeader("X-Device-ID", WiFi.macAddress());

  int httpCode = http.GET();
  if (httpCode == 200) {
    int contentLength = http.getSize();
    if (contentLength > 0 && Update.begin(contentLength)) {
      WiFiClient* stream = http.getStreamPtr();
      size_t written = Update.writeStream(*stream);
      if (written == contentLength && Update.end(true)) {
        Serial.println("OTA pull: успешно!");
        ESP.restart();
      }
    }
  }
  http.end();
}

Вызываете checkForUpdate() раз в час из loop(). На сервере просто кладёте новый .bin файл — и все устройства обновятся автоматически. Когда у вас 20 ESP32 в разных теплицах — это единственный разумный способ.

Что дальше

OTA — это фундамент для серьёзной IoT-инфраструктуры. Без неё каждое обновление — это поездка. С ней — 30 секунд в браузере.

В следующих статьях серии:

  • MQTT + VK бот — когда датчиков больше десяти, HTTP-запросы в Telegram перестают справляться. MQTT-брокер + бот ВКонтакте = единый хаб управления всей фермой
  • Дашборд на Nuxt — собственный веб-интерфейс с графиками, алертами и push-уведомлениями. Без Grafana, без облака, полностью под вашим контролем

Код из статьи — рабочий. Добавляете в любой существующий проект, прошиваете один раз по кабелю — и дальше обновляете удалённо. Если что-то не получилось — пишите в комментариях.

💬 Комментарии

Чтобы оставить комментарий, войдите или зарегистрируйтесь

Загрузка комментариев...

Похожие статьи