Building WebUpdater fails in library code...

I wanted to check how the WebUpdater OTA would work so I loaded the WebUpdater sketch from the Arduino examples into Arduino IDE 1.8.2 and copied the ino file content into a new Arduino project named WebUpdater in the Sloeber IDE.

But when I try the Verify function in Sloeber IDE to check the code I get an error in some library code, outside the ino file:

19:19:56 **** Incremental Build of configuration Release for project WebUpdater ****
"C:\\Programs\\sloeber\\arduinoPlugin\\tools\\make\\make" all 
'Building file: C:\Programs\sloeber\arduinoPlugin\libraries\WiFi\1.2.6\src\utility\spi_drv.cpp'
'Starting C++ compile'
"C:\Programs\sloeber\/arduinoPlugin/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Programs\sloeber\/arduinoPlugin/packages/esp8266/hardware/esp8266/2.4.1/tools/sdk/include" "-IC:\Programs\sloeber\/arduinoPlugin/packages/esp8266/hardware/esp8266/2.4.1/tools/sdk/lwip2/include" "-IC:\Programs\sloeber\/arduinoPlugin/packages/esp8266/hardware/esp8266/2.4.1/tools/sdk/libc/xtensa-lx106-elf/include" "-ID:\Engineering\Arduino\WebUpdater/Release/core" -c -Wall -Wextra -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11 -ffunction-sections -fdata-sections -DF_CPU=80000000L -DLWIP_OPEN_SRC -DTCP_MSS=1460 -DDEBUG_ESP_PORT=Serial1 -DARDUINO=10802 -DARDUINO_ESP8266_GENERIC -DARDUINO_ARCH_ESP8266 "-DARDUINO_BOARD=\"ESP8266_GENERIC\"" -DLED_BUILTIN=0 -DESP8266  -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266" -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\variants\generic" -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\libraries\ESP8266HTTPUpdateServer" -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\libraries\ESP8266HTTPUpdateServer\src" -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\libraries\ESP8266mDNS" -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\libraries\ESP8266WebServer" -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\libraries\ESP8266WebServer\src" -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\libraries\ESP8266WiFi" -I"C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\libraries\ESP8266WiFi\src" -I"C:\Programs\sloeber\arduinoPlugin\libraries\WiFi\1.2.6" -I"C:\Programs\sloeber\arduinoPlugin\libraries\WiFi\1.2.6\src" -MMD -MP -MF"libraries\WiFi\src\utility\spi_drv.cpp.d" -MT"libraries\WiFi\src\utility\spi_drv.cpp.o" -D__IN_ECLIPSE__=1 -x c++ "C:\Programs\sloeber\arduinoPlugin\libraries\WiFi\1.2.6\src\utility\spi_drv.cpp"  -o  "libraries\WiFi\src\utility\spi_drv.cpp.o"
C:\Programs\sloeber\arduinoPlugin\libraries\WiFi\1.2.6\src\utility\spi_drv.cpp:21:17: fatal error: SPI.h: No such file or directory
 #include <SPI.h>
                 ^
compilation terminated.
libraries\WiFi\src\utility\subdir.mk:31: recipe for target 'libraries\WiFi\src\utility\spi_drv.cpp.o' failed
make: *** [libraries\WiFi\src\utility\spi_drv.cpp.o] Error 1

19:19:58 Build Finished (took 1s.230ms)

I have set the project to use the ESP8266 libraries version 2.4.1

One other note is that the IDE displays warnings on the following lines in setup() where object WiFi is referenced:

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

  while(WiFi.waitForConnectResult() != WL_CONNECTED){
    WiFi.begin(ssid, password);
    Serial.println("WiFi failed, retrying.");
  }

It seems like it cannot resolve the WiFi object’s methods “mode” and “waitForConnectResult” .
On the lines with WiFi.begin it complains about “Invalid arguments”.

What can be the problem here?
Note:
If I use the Arduino IDE 1.8.2 to verify the example sketch WebUpdater then it does not run into errors, so it must be something I have done wrong in the Sloeber IDE, but what?

[u]Problem Solved![/u] I had to use "Arduino/Add a library to the selected project" and unselect WiFi and make sure ESP8266WiFi was checked instead. In my case both were checked and I guess thus created some kind of conflict. Now the project verifies and builds. I have not tested yet if it actually also works.

Additional question on the WebUpdater code: Just want to know what is MDNS used for? It seems like it never works to use the hostname for connection, only IP address. I have now commented out the mDNS items in the WebUpdater code and it still works the same, i.e. I can update the firmware via the webpage shown by the ESP but only via the IP address, which has to be known. Is mDNS only applicable if the ESP8266 is running as a station towards an existing WiFi network? I am using it as an AP always...

It works in both Station and AP mode. Its purpose is to resolve the domain name .local. It should work right out of the box on OSX, iOS and Linux, but you might have to install it on Windows for it to work (it’s included with programs like iTunes for Windows).

Pieter

Thanks, then I will keep it disabled. We do not use any of these computer types. Our target users are Windows and Android only...

Another question:
Is there some way to customize the firmware update webform?
The source of the form page looks like this:

<html><body><form method='POST' action='' enctype='multipart/form-data'>
                  <input type='file' name='update'>
                  <input type='submit' value='Update'>
               </form>
         </body></html>

I have tried to locate where this is created but failed so far.
I would like to add some text and also a title to the webpage, so I need to find exactly where it is defined.
Any ideas?

https://github.com/esp8266/Arduino/blob/b93cba104610a7db7021765a79a415e2546aa359/libraries/ESP8266HTTPUpdateServer/src/ESP8266HTTPUpdateServer.cpp#L10-L15

I located the file inside the library of my project and changed the text a bit.
Turns out that for some reason the head tag does not “take” when I use it like this:

static const char serverIndex[] PROGMEM =
  R"(<html><head><title>WiFi module firmware updater</title></head>
     <body>Select firmware file, then click the Update button!

     <form method='POST' action='' enctype='multipart/form-data'>
                  <input type='file' name='update'>
                  <input type='submit' value='Update'>
               </form>
         </body></html>)";

This displays two lines of text above the buttons, i.e. the supposed title is just printed inside the body of the document.
Strange…
But if I copy the text above into an html file on my disk and double-click it so it opens in FireFox then the title is displayed in the browser tab as expected.

Press CTRL+U or F12 in the browser to see the actual HTML. Or save it on your disk.

OK, I must have done something strange the first time around. Now I added a new head/title item and it worked as expected. Don't know what was wrong the first time, I changed the text then and can't recreate the problem... It all works now, thanks!

Now I will add the update function to my configuration program too.

Yet another question... Now that I have modified the webpage of the WebUpdater library I am in a situation where I have a modified file that is not residing in my project directory. I need to somehow include this in Subversion for version control, but where is it actually located? If I right-click the tab with the file it says: TCP_UART_ESP/libraries/ESP8266HTTPUpdateServer/src/ESP8266HTTPUpdateServer.cpp But when I look in my project directory I can find TCP_UART_ESP/libraries, but this directory is [u]empty[/u], no files at all! So it seems like the actual code is located somewhere else entirely... How do people manage to keep track of changes in version control (Subversion) for Arduino projects? This is my first real such project....

BosseB:
Yet another question…
Now that I have modified the webpage of the WebUpdater library I am in a situation where I have a modified file that is not residing in my project directory.
I need to somehow include this in Subversion for version control, but where is it actually located?
If I right-click the tab with the file it says:
TCP_UART_ESP/libraries/ESP8266HTTPUpdateServer/src/ESP8266HTTPUpdateServer.cpp
But when I look in my project directory I can find TCP_UART_ESP/libraries, but this directory is empty, no files at all!
So it seems like the actual code is located somewhere else entirely…
How do people manage to keep track of changes in version control (Subversion) for Arduino projects?
This is my first real such project…

the content of core and libraries in Sloeber project are Eclipse links. they are there for C++ indexer and your reference.

Isn’t in he library a constructor or method to set custom html from sketch?

Juraj:
Isn’t in the library a constructor or method to set custom html from sketch?

Well, I am not versed in C++ so I don’t know how you find the constructor. But here is the accompanying h file content:

#ifndef __HTTP_UPDATE_SERVER_H
#define __HTTP_UPDATE_SERVER_H

class ESP8266WebServer;

class ESP8266HTTPUpdateServer
{
  public:
    ESP8266HTTPUpdateServer(bool serial_debug=false);

    void setup(ESP8266WebServer *server)
    {
      setup(server, NULL, NULL);
    }

    void setup(ESP8266WebServer *server, const char * path)
    {
      setup(server, path, NULL, NULL);
    }

    void setup(ESP8266WebServer *server, const char * username, const char * password)
    {
      setup(server, "/update", username, password);
    }

    void setup(ESP8266WebServer *server, const char * path, const char * username, const char * password);

  protected:
    void _setUpdaterError();

  private:
    bool _serial_output;
    ESP8266WebServer *_server;
    char * _username;
    char * _password;
    bool _authenticated;
    String _updaterError;
};
#endif

In this I cannot see any call that allows redefining the index page. There are a few overloaded versions of the setup() function to allow for running in various modes, though.

The page itself is defined at the top of the cpp file (I have removed my additions):

static const char serverIndex[] PROGMEM =
  R"(<html><body><form method='POST' action='' enctype='multipart/form-data'>
                  <input type='file' name='update'>
                  <input type='submit' value='Update'>
               </form>
         </body></html>)";
static const char successResponse[] PROGMEM = 
  "<META http-equiv=\"refresh\" content=\"15;URL=/\">Update Success! Rebooting...\n";

So it seems like the index page is hard coded and can only be modified via the library sourcecode…

BosseB:
So it seems like the index page is hard coded and can only be modified via the library sourcecode…

I’m afraid you’re correct.
You could try to open a feature request/enhancement on GitHub?

Also, a file in the SPIFFS might be a better idea than a hardcoded string variable.

the ESP8266HTTPUpdateServer class source code is so shallow. It simply puts together the httpserver and the Update system. I would treat it like an example and copy it in my project and modify as I need.

I didn’t look closer on it until now. The ESP8266HTTPUpdateServer requires to upload the firmware to the esp8266, but there is ESP8266httpUpdate library, where the esp8266 checks some url if there is new firmware available for download.

Yes, I have seen the auto-update function as well. But it does not apply to our system because the ESP will create its own AP network to enable communication with a data collection system. So it does not have an Internet connection at all. To update the firmware we will connect to its AP from our PC and then either use our configuration program to set it up including uploading new firmware if needed. Or while connected open the webpage 1.2.3.4/firmware and then use the browse button to select the bin file and after that hit the Update button. We have password protected this update page.

I will have a look at just copying over the library to the source dir as you suggest, this will make it simple to version the file(s). Probably need to copy a few more files though, since ESP8266HTTPUpdateServer has other dependencies.

Thanks!

PS: Is there a way in Sloeber to open an explorer widow on the directory where a library file resides so one can easily get there to copy files? DS

BosseB: Probably need to copy a few more files though, since ESP8266HTTPUpdateServer has other dependencies.

'the library' are the two files .h and .cpp. the dependencies are other libraries and they should by resolved

Where is the proper place for the files inside the project dir?
The files I have created myself so far live in the top folder but there exists an empty folder named “library” there too.
So should I copy files over to /library or should I drop them into ?
I made a test as follows:

  • Copied the two files from:
    C:\Programs\sloeber\arduinoPlugin\packages\esp8266\hardware\esp8266\2.4.1\libraries\ESP8266HTTPUpdateServer\src
    to
    D:\Engineering\Arduino\TCP_UART_ESP
  • Removed the library from current project (Arduino/Add a library to the selected project) by unchecking the copied file
  • Then I slightly changed the index page in the current dir and created the bin file, which I uploaded via the webpage.
    All seemed to have worked just fine! The changed text was shown!

Is this the correct way to do the operation?

BosseB: Is this the correct way to do the operation?

I would do the same.