Over The Air Update (Arduino IDE)

Beim Over The Air Update (OTA) wird der Sketch nicht über die serielle Verbindung, sondern über WLAN an das ESP8266 Modul gesendet. Dies ist sehr praktisch wenn das ESP8266 Modul so verbaut wurde, dass es nur schwer zugänglich ist. Zum Beispiel ist bei uns im Wohnzimmer in einer Unterputzdose ein Wemos D1 mini als IR-Sender verbaut ist. Für jedes Update den Wemos auszubauen wäre sehr umständlich.

Die drei Optionen

Es gibt drei verschiedene Möglichkeiten ein Over The Air Update durchzuführen. Dieser Beitrag beschäftigt sich mit Update über die Arduino IDE, die wohl am häufigsten genutzte Variante.

Arduino IDE – Es kann direkt aus der Arduino IDE ein Update durchgeführt werden. Einfach unter dem Menüpunkt Port das entsprechende Modul wählen und starten.

Web Browser – Bringt aus meiner Sicht keine großen Vorteile, hier kann über ein kleines Webfrontend auf dem ESP8266 Modul ein Upload der kompilierten BIN-Datei gestartet werden.

HTTP Server – Hier gibt es ein “Simple Update” und ein “Advanced Update”. Beim einfachen Update wird beim Aufruf einer Funktion eine vorab definierte BIN-Datei vom HTTP Server geladen und beim erweiterten Update können mehrere BIN-Dateien auf dem HTTP Server abgelegt und dann den Modulen per MAC Adresse zugewiesen werden. Zudem wird ein Update nur bei einer Abweichung durchgeführt.

Requirements

Neben einer möglichst aktuellen Arduino IDE (1.6.7 oder neuer) muss zwingend Python 2.7 auf dem System installiert sein. Auf einem Windows System sollte “Add python.exe to Path” bei der Installation gewählt werden. Zudem muss das ESP8266 Modul im Boards Manager der Arduino IDE eingerichtet sein. Eine einfache Anleitung gibt es auf GitHub.

Für das Over The Air Update sollte sich das ESP8266 Modul im gleichen Netzwerk befinden und es muss genügend freier Speicher zur Verfügung stehen. Der neue Sketch muss doppelt bzw. zusammen mit dem alten Sketch in den Flash Speicher passen!

Der Weg zum Over The Air Update

Nehmt einfach den OTA Sketch den ich euch unten bereitgestellt habe und passt ihn wie beschrieben an. Der erste Upload muss natürlich noch über die serielle Verbindung (USB) erfolgen.

Wurde der Sketch installiert, zieht sich das ESP8266 Modul über WLAN eine IP Adresse vom DHCP Server und teilt diese per mDNS über UDP mit. Wenn alles geklappt hat, erscheint das ESP Modul mit dem Präfix esp8266-[ChipID] in der Arduino IDE unter Ports wie unten auf dem Bild zu sehen. Die ChipID besteht aus den letzten 6 Stellen der MAC-Adresse. Eventuell ist noch ein Neustart der Arduino IDE notwendig, damit dieser sichtbar wird. Sollte es dort nicht erscheinen, macht ein Blick auf den Serial Monitor Sinn. Meldet sich das ESP8266 Modul erfolgreich am WLAN an und erhält eine IP-Adresse, kann es auch an der Firewall liegen.

Over The Air Update - Arduino IDE

Solange keine wesentlichen Bestandteile aus dem Sketch gelöscht werden, kann jetzt immer wieder ein Over The Air Update über die Arduino IDE durchgeführt werden.

Serial Monitor

Gerade in der Testphase von größeren Projekten ist der Serial Monitor ein sehr wichtiges Hilfsmittel für das Troubleshooting. Versucht ihr über IP den Serial Monitor zu öffnen, erhaltet ihr leider die Fehlermeldung “Serial monitor is not supported on network”. Eine Alternative ist der Einsatz eines Wifi Telnet Servers. Dieser kann wie der Serial Monitor verwendet werden und es wird nur ein Telnet Client wie Putty benötigt. Da sich der Telnet Server auch ohne OTA nutzen lässt, erstelle ich hierzu noch einen eigenen Beitrag.

Sketch

Der erste Sketch ist auf das wesentliche gekürzt. Vorab müssen aber mindestens die folgenden Zeilen in jedem Sketch angepasst werden!

const char* ssid = "SSID";
const char* password = "PASSWORD";

Die Variable ArduinoOTA.setPassword solltet ihr nicht nur aus Sicherheitsgründen setzen. So habt ihr auch noch die Chance ein versehentlich falsch ausgewähltes Board vor dem Überschreiben zu retten, vorausgesetzt natürlich ihr bekommt es mit!

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

const char* ssid = "SSID";
const char* password = "PASSWORD";

void setup()
{
  Serial.begin(115200);
  Serial.println("Over The Air Update - Basic");

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

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

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

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

  // No authentication by default
  // ArduinoOTA.setPassword((const char *)"1234");

  ArduinoOTA.begin();
}

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

Der Sketch ist so natürlich komplett nutzlos. Nicht einmal die LED blinkt! 😉 Also packen wir noch ein paar Features hinzu. Dieser kann zum Test gleich per Over The Air Update auf das ESP Modul gesendet werden.

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

const char* ssid = "SSID";
const char* password = "PASSWORD";

void setup()
{
  Serial.begin(115200);
  Serial.println("Over The Air Update - Full");

  Serial.printf("Sketch size: %u\n", ESP.getSketchSize());
  Serial.printf("Free size: %u\n", ESP.getFreeSketchSpace());

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  // ... Give ESP 10 seconds to connect to station.
  unsigned long startTime = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("Connection Failed! Rebooting...");
    delay(3000);
    ESP.restart();
  }
  
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  pinMode(BUILTIN_LED, OUTPUT);  // initialize onboard LED as output

  // OTA Settings

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

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

  // No authentication by default
  // ArduinoOTA.setPassword((const char *)"1234");
  
  // OTA Start
  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));;Serial.println();
  });
  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();
  blinkLED();
}

////////////////////////////////////////////////////////////////////////////////////////
// Blink function

const long interval = 1000;
int ledState = LOW;
unsigned long previousMillis = 0;

void blinkLED()
{
  unsigned long currentMillis = millis();

  // if enough millis have elapsed
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;

    // toggle the LED
    ledState = !ledState;
    digitalWrite(BUILTIN_LED, ledState);
  }
}

5 Gedanken zu „Over The Air Update (Arduino IDE)“

  1. Hi, vielen Dank für die Anleitung. Leider sieht das Endergebnis bei mir immer gleich aus: Arduino IDE (Vers. 1.8.0) öffnet einen Passwort-Requester und quittiert jede Eingabe mit: “Falsches Passwort!”. Ich habe im Netz schon geschaut – dieses Problem haben viele Leute, nur eine Lösung scheint es dafür nicht zu geben.

    1. Hallo Chris,

      also das Beispiel funktioniert bei mir immer noch, gerade getestet. Ich nutze den gleichen Code in anderen Projekten und habe damit keine Probleme. Hast du eine Log Ausgabe mit Fehlerdetails? Du hast auch Python 2.7.x installiert und den Path Parameter gesetzt? Ich habe mittlerweile auch unterschiedliche Versionen genutzt, aktuell die Arduino IDE 1.8.8 und die ESP8266 Version 2.5 in meiner Umgebung.

      Viele Grüße
      Stefan

  2. Das man den Port verändern kann erschließt sich mir nicht wirklich..
    Habe nur die Zeile genommen, die meinem Modul einen Hostnamen gibt
    um es bei Werkzeuge/Port klar zu identifizieren, somit brauche ich auch kein Passwort setzen.

  3. Jaaa, wirklich sehr interessant. Bei mir erscheint leider noch nicht einmal der Port. Habe schon (fast) alles versucht, neueste Arduino IDE 1.8.10, anderer Laptop, andere Windows-Version, anderen ESP. Bin leicht am Verzweifeln. Und nein, es ist nicht Python 3 installiert, damit soll es ja auch nicht funktionieren. PC und ESP zigmal neu gestartet. Jemand noch einen Tipp ?? Danke !

  4. Ich habe die Erfahrung gemacht, dass bei Sketches, die ein “zu langes” delay() in der Loop haben, der Host nicht in der Liste der “Netzwerk-Ports” angeboten wird. ArduinoOTA.handle() ist dann vermutlich nicht lange genug “sichtbar”.

    Noch eine Anmerkung zu Ausgabe mit Serial.print(ln). Das halte ich für ziemlich sinnfrei, denn wenn ich über den Serial Port nicht updaten kann, werde ich dessen Ausgabe auch kaum zu sehen bekommen 😉
    Es gibt aber Situationen, wo man die Ausgabe z.B. auf einem angeschlossenen Display anzeigen kann.
    Das funktioniert bei mir ganz gut, nur
    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf(“Progress: %u%%r”, (progress / (total / 100)));
    }
    zeigt bei mir immer 0%.
    Keine Ahnung, woher sich onProgress() die notwendigen Parameter zur Laufzeit holt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert