ESP8266 OTA Example Won't Compile

I cannot get the simple example code for the ESP8266 to compile without error in PI/Atom (ArduinoOTA->BasicOTA). It compiles w/o error with the Arduino IDE. The errors seem to relate to the C++11 Lambda functions:

src/main.cpp: In function 'void setup()':
src/main.cpp:39:14: error: 'class ArduinoOTAMdnsClass<WiFiServer, WiFiClient, WiFiUDP>' has no member named 'onStart'
   ArduinoOTA.onStart([]() {
              ^

src/main.cpp: In lambda function:
src/main.cpp:41:20: error: 'class ArduinoOTAMdnsClass<WiFiServer, WiFiClient, WiFiUDP>' has no member named 'getCommand'
     if (ArduinoOTA.getCommand() == U_FLASH) {
                    ^
src/main.cpp: In function 'void setup()':
src/main.cpp:50:14: error: 'class ArduinoOTAMdnsClass<WiFiServer, WiFiClient, WiFiUDP>' has no member named 'onEnd'
   ArduinoOTA.onEnd([]() {
              ^
src/main.cpp:53:14: error: 'class ArduinoOTAMdnsClass<WiFiServer, WiFiClient, WiFiUDP>' has no member named 'onProgress'
   ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
              ^
src/main.cpp:56:14: error: 'class ArduinoOTAMdnsClass<WiFiServer, WiFiClient, WiFiUDP>' has no member named 'onError'
   ArduinoOTA.onError([](ota_error_t error) {
              ^
src/main.cpp:56:25: error: 'ota_error_t' has not been declared
   ArduinoOTA.onError([](ota_error_t error) {
                         ^
src/main.cpp: In lambda function:
src/main.cpp:58:18: error: 'OTA_AUTH_ERROR' was not declared in this scope
     if (error == OTA_AUTH_ERROR) {
                  ^
src/main.cpp:60:25: error: 'OTA_BEGIN_ERROR' was not declared in this scope
     } else if (error == OTA_BEGIN_ERROR) {
                         ^
src/main.cpp:62:25: error: 'OTA_CONNECT_ERROR' was not declared in this scope
     } else if (error == OTA_CONNECT_ERROR) {
                         ^
src/main.cpp:64:25: error: 'OTA_RECEIVE_ERROR' was not declared in this scope
     } else if (error == OTA_RECEIVE_ERROR) {
                         ^
src/main.cpp:66:25: error: 'OTA_END_ERROR' was not declared in this scope
     } else if (error == OTA_END_ERROR) {
                         ^
src/main.cpp: In function 'void setup()':
src/main.cpp:70:20: error: no matching function for call to 'ArduinoOTAMdnsClass<WiFiServer, WiFiClient, WiFiUDP>::begin()'
   ArduinoOTA.begin();
                    ^

I can find only one post relating to these exact errors and the proposed solution was to add the C++11 build flag, which I did. My PlatformIO.ini looks like this:

[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
build_flags = -std=c++11

As I said, the Arduino IDE compiles the example without error. What am I doing wrong?

Thanks.

That shouldn’t be needed… it normally works out of the box (and does for me…)…

i.e. On Windows (hence the slow compile time) this platformio.ini

[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino

with this main.cpp

#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();
}

get me the following build output

> Executing task in folder basic_ota: C:\Users\Peter\.platformio\penv\Scripts\platformio.exe run <

Processing d1_mini (platform: espressif8266; board: d1_mini; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/d1_mini.html
PLATFORM: Espressif 8266 2.2.3 > WeMos D1 R2 and mini
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES: toolchain-xtensa 2.40802.190218 (4.8.2), tool-esptool 1.413.0 (4.13), tool-esptoolpy 1.20600.0 (2.6.0), framework-arduinoespressif8266 2.20502.0 (2.5.2)      
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 28 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <ArduinoOTA> 1.0
|   |-- <ESP8266WiFi> 1.0
|   |-- <ESP8266mDNS> 1.2
|   |   |-- <ESP8266WiFi> 1.0
|-- <ESP8266mDNS> 1.2
|   |-- <ESP8266WiFi> 1.0
|-- <ESP8266WiFi> 1.0
Compiling .pio\build\d1_mini\src\main.cpp.o
Generating LD script .pio\build\d1_mini\ld\local.eagle.app.v6.common.ld
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\BearSSLHelpers.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\CertStoreBearSSL.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\ESP8266WiFi.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\ESP8266WiFiAP.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\ESP8266WiFiGeneric.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\ESP8266WiFiMulti.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\ESP8266WiFiSTA-WPS.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\ESP8266WiFiSTA.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\ESP8266WiFiScan.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\WiFiClient.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\WiFiClientSecureAxTLS.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\WiFiClientSecureBearSSL.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\WiFiServer.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\WiFiServerSecureAxTLS.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\WiFiServerSecureBearSSL.cpp.o
Compiling .pio\build\d1_mini\lib33a\ESP8266WiFi\WiFiUdp.cpp.o
Compiling .pio\build\d1_mini\liba7a\ESP8266mDNS\ESP8266mDNS.cpp.o
Compiling .pio\build\d1_mini\liba7a\ESP8266mDNS\ESP8266mDNS_Legacy.cpp.o
Compiling .pio\build\d1_mini\liba7a\ESP8266mDNS\LEAmDNS.cpp.o
Archiving .pio\build\d1_mini\lib33a\libESP8266WiFi.a
Compiling .pio\build\d1_mini\liba7a\ESP8266mDNS\LEAmDNS_Control.cpp.o
Compiling .pio\build\d1_mini\liba7a\ESP8266mDNS\LEAmDNS_Helpers.cpp.o
Compiling .pio\build\d1_mini\liba7a\ESP8266mDNS\LEAmDNS_Structs.cpp.o
Compiling .pio\build\d1_mini\liba7a\ESP8266mDNS\LEAmDNS_Transfer.cpp.o
Compiling .pio\build\d1_mini\libb28\ArduinoOTA\ArduinoOTA.cpp.o
Archiving .pio\build\d1_mini\libFrameworkArduinoVariant.a
Compiling .pio\build\d1_mini\FrameworkArduino\Esp-frag.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\Esp-version.cpp.o
Archiving .pio\build\d1_mini\liba7a\libESP8266mDNS.a
Compiling .pio\build\d1_mini\FrameworkArduino\Esp.cpp.o
Archiving .pio\build\d1_mini\libb28\libArduinoOTA.a
Compiling .pio\build\d1_mini\FrameworkArduino\FS.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\FunctionalInterrupt.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\HardwareSerial.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\IPAddress.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\MD5Builder.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\Print.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\Schedule.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\ScheduledFunctions.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\StackThunk.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\Stream.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\StreamString.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\Tone.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\Updater.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\WMath.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\WString.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\abi.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\base64.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\cbuf.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\cont.S.o
Compiling .pio\build\d1_mini\FrameworkArduino\cont_util.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_app_entry_noextra4k.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_eboot_command.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_flash_utils.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_i2s.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_main.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_noniso.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_phy.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_postmortem.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_si2c.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_sigma_delta.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_timer.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_waveform.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_wiring.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_wiring_analog.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_wiring_digital.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_wiring_pulse.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_wiring_pwm.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\core_esp8266_wiring_shift.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\debug.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\gdb_hooks.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\heap.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\libb64\cdecode.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\libb64\cencode.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\libc_replacements.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\sntp-lwip2.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\spiffs\spiffs_cache.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\spiffs\spiffs_check.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\spiffs\spiffs_gc.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\spiffs\spiffs_hydrogen.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\spiffs\spiffs_nucleus.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\spiffs_api.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\spiffs_hal.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\sqrt32.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\time.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\uart.cpp.o
Compiling .pio\build\d1_mini\FrameworkArduino\umm_malloc\umm_malloc.cpp.o
Archiving .pio\build\d1_mini\libFrameworkArduino.a
Linking .pio\build\d1_mini\firmware.elf
Retrieving maximum program size .pio\build\d1_mini\firmware.elf
Checking size .pio\build\d1_mini\firmware.elf
Building .pio\build\d1_mini\firmware.bin
Creating BIN file ".pio\build\d1_mini\firmware.bin" using ".pio\build\d1_mini\firmware.elf"
Memory Usage -> http://bit.ly/pio-memory-usage
DATA:    [===       ]  33.8% (used 27700 bytes from 81920 bytes)
PROGRAM: [===       ]  29.3% (used 306336 bytes from 1044464 bytes)
==================================================================== [SUCCESS] Took 55.34 seconds ====================================================================

Maybe your esp8266 framework hasn’t installed properly? Try uninstalling and re-installing that platform via PIO Home → Platforms?

If you’re referring to this issue … that may be misleading at best, as it’s for the esp32 core, not esp8266…and the author never commented as to if that fixed the problem… although it’s peculiar you’re getting basically the same error.

Thanks for giving it a try, I know it must be possible because lots of people do it and this error is vanishingly rare. However, I’m going to need to dig deeper. I removed the ESP8266 framework and restarted Atom/PlatformIO. I re-installed – it did not go smoothly, I had to abort and restart because it got stuck with the install-spinning-arrow thing for a long time – and got the same result as before, not the result you got. I tried the whole process again, and everything finished without problem. Restarted Atom, re-installed the ESP8266. Same thing.
Added these to the PlatformIO.ini file:

build_flags = -std=c++11
lib_deps = ArduinoOTA

Same error.
Tried the 1.0 version of the ArduinoOTA library (like you have): same error.

And yes, it is very peculiar that I am getting the same error (verbatim).

This is a builtin library and shouldn’t be declared. Does the result stay the same when you remove the hidden .pio folder in project, remove the afforementioned line and recompile?

1 Like

I removed the lib_deps = ArduinoOTA line as well as the .pio folder and recompile with exactly the same errors.
Is is possible that the difference between a successful dependency graph and mine (unsuccessful) is relevant?
Successful:

Dependency Graph
|-- <ArduinoOTA> 1.0
|   |-- <ESP8266WiFi> 1.0
|   |-- <ESP8266mDNS> 1.2
|   |   |-- <ESP8266WiFi> 1.0
|-- <ESP8266mDNS> 1.2
|   |-- <ESP8266WiFi> 1.0
|-- <ESP8266WiFi> 1.0

Unsuccessful:

Dependency Graph
|-- <ESP8266mDNS> 1.2
|   |-- <ESP8266WiFi> 1.0
|-- <ArduinoOTA> 1.0.1
|   |-- <SD(esp8266)> 2.0.0
|   |   |-- <SDFS> 0.1.0
|   |   |   |-- <SPI> 1.0
|   |   |   |-- <ESP8266SdFat> 1.0.16
|   |   |   |   |-- <SPI> 1.0
|   |-- <ESP8266WiFi> 1.0
|-- <ESP8266WiFi> 1.0

Why are they so radically different? The code being compiled is identical in both cases.

Also: When I search for the libraries I am including, should they be under .platformio/lib or is it OK that they are found in the Arduino libraries?

And why are the library names in the first md code block in red and the ones in the second aren’t?

No it’s not… In the successful one, the ESP8266 core provided ArduinoOTA library is being used (1.0). In the unsuccessful one, the first party Arduino created ArduinoOTA library is being used (1.0.1). This be because when you added the lib_deps line… you told PlatformIO your project needs a non-core / external library. For order of business is to remove the lib_deps = ArduinoOTA line… as Max pointed out.

Have you tried using the platformio.ini and main.cpp I used as is… just to rule out any copy/paste or unintended edit errors? Make sure you clean the project’s build files first (PlatformIO sidebar icon-> Project Tasks → Clean), or even start a new project.

Yes and no. I did not make clear that I had removed all the extra platformio.ini lines and have been using exactly the one generated by the system when a new project is created (identical to yours). I was still getting the same errors. Also, the difference between <ArduinoOTA> libraries is simply a version difference, Ijust went back, uninstalled 1.0.1, installed 1.0 of <ArduinoOTA> and it made no difference – same errors.
I copied and pasted your code (again, as-is) into a new project. I did not add the #include <Arduino.h> that we are told is necessary (but maybe isn’t, because the presence/absence of that statement makes no difference). Although I cannot rule out c/p issues, the compile errors do not point in that direction (based on my understanding of compile errors). Those errors result from exactly the same code and exactly the same platformio.ini file, after a clean. The difference seems to be either 1) which libraries are getting included; or 2) the order in which the libraries are included. I tend to think it’s the former. To re-ask my question, should everything that gets compiled in this project come from inside the .platformio environment or is it permissible that some of it is being drawn from the (potentially older) Arduino environment libraries?

After all of that, if I UNINSTALL the ArduinoOTA library, compilation succeeds.

Dependency Graph
|-- <ESP8266mDNS> 1.2
|   |-- <ESP8266WiFi> 1.0
|-- <ArduinoOTA> 1.0
|   |-- <ESP8266mDNS> 1.2
|   |   |-- <ESP8266WiFi> 1.0
|   |-- <ESP8266WiFi> 1.0
|-- <ESP8266WiFi> 1.0

And the dependency graph makes much more sense.
Can someone explain why uninstalling of a required library results in a successful compilation?

Because the ArduinoOTA library authored by Arduino (installed when you specify it via lib_deps), is NOT the same as the one provided as part of the ESP8266 core (built in, and not needing to be installed) hence the errors, and difference in dependencies.

I am beginning to see the light.
Although I had long ago removed the lib_deps entry, the failure to compile was due to my having explicitly installed the ArduinoOTA library from Arduino. When I look at that code (thanks for the link), I see all the references to SD card code I was getting in my dependency graph. So the problem was not the lib_deps but rather my failure to realize that there was an OTA library that was built in and explicitly installing the wrong one.
Problem solved. Lesson learned. Thanks.

And to confirm: It works. Like magic.

3 Likes