esp8266 self OTA update firmware from server – 1
OTA (Over the Air) update is the process of uploading firmware to an ESP module using a Wi-Fi connection rather than a serial port. Such functionality becomes extremely useful in case of limited or no physical access to the module.
OTA may be done using:
- Arduino IDE
- Web Browser
- HTTP Server
First of all read the tutorial “esp8266: flash firmware binary (.bin) compiled and signed“.
In this article we will explain how to do an automatic update from an HTTP server.
Automatic OTA update every application start
ESPhttpUpdate
class can check for updates and download a binary file from HTTP web server. It is possible to download updates from every IP or domain address on the network or Internet.
Note that by default this class closes all other connections except the one used by the update, this is because the update method blocks. This means that if there’s another application receiving data then TCP packets will build up in the buffer leading to out of memory errors causing the OTA update to fail. There’s also a limited number of receive buffers available and all may be used up by other applications.
There are some cases where you know that you won’t be receiving any data but would still like to send progress updates. It’s possible to disable the default behavior (and keep connections open) by calling closeConnectionsOnUpdate(false)
. (Cit.)
Create a basic web server
Now we are going o create a fast server to download the firmware, next to manage REST.
Prepare environment
- We use NodeJS, you can download It from here.
- After installation create a new directory
OTAServer
. - CD inside the
OTAServer
folder.
Initialize application
- Inside folder launch
npm init
.
D:\Projects\IdeaProjects\OTAWebPages\OTAServer>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (otaserver)
version: (1.0.0)
description: Server to test HTTP server OTA update
entry point: (index.js)
test command:
git repository:
keywords: OTA esp8266 esp32 Server
author: Renzo Mischianti
license: (ISC)
About to write to D:\Projects\IdeaProjects\OTAWebPages\OTAServer\package.json:
{
"name": "otaserver",
"version": "1.0.0",
"description": "Server to test HTTP server OTA update",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"OTA",
"esp8266",
"esp32",
"Server"
],
"author": "Renzo Mischianti",
"license": "ISC"
}
Is this OK? (yes) yes
- Install express the basic server in NodeJS
npm install express --save-dev
Basic web server code
- Create
index.js
. - Add this content on
index.js
.
const express = require('express');
const { networkInterfaces } = require('os');
const app = express();
const nets = networkInterfaces();
// Server port
const PORT = 3000;
app.get('/', (request, response) => response.send('Hello from www.mischianti.org!'));
app.listen(PORT, () => {
const results = {}; // Or just '{}', an empty object
for (const name of Object.keys(nets)) {
for (const net of nets[name]) {
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
if (net.family === 'IPv4' && !net.internal) {
if (!results[name]) {
results[name] = [];
}
results[name].push(net.address);
}
}
}
console.log('Listening on port '+PORT+'\n', results)
});
- Start the application with
node index.js
.
D:\Projects\IdeaProjects\OTAWebPages\OTAServer>node index.js
Listening on port 3000
{
'VirtualBox Host-Only Network': [ '192.168.56.1' ],
'VMware Network Adapter VMnet1': [ '192.168.113.1' ],
'VMware Network Adapter VMnet8': [ '192.168.116.1' ],
Ethernet: [ '192.168.1.70' ]
}
- Grab correct IP from the console, we can’t use
localhost
or127.0.0.1
for our test, so I print at start all the interfaces, and in my case the IP of the current application isEthernet: [ '192.168.1.70' ]
- Put on the browser the url http://192.168.1.70:3000/.
- Check in the browser page the sentence “Hello from www.mischianti.org!”.
Create the initial sketch
We can use the basic example that you can find on File -> Examples -> ESP8266httpUpdate -> httpUpdate
.
We change It to point at our new server.
/*
* Basic Sketch for automatic update of firmware at start
*
* Renzo Mischianti <www.mischianti.org>
*
* https://mischianti.org
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#ifndef APSSID
#define APSSID "<YOUR-SSID>"
#define APPSK "<YOUR-PASSWD>"
#endif
ESP8266WiFiMulti WiFiMulti;
#define FIRMWARE_VERSION "0.2"
void update_started() {
Serial.println("CALLBACK: HTTP update process started");
}
void update_finished() {
Serial.println("CALLBACK: HTTP update process finished");
}
void update_progress(int cur, int total) {
Serial.printf("CALLBACK: HTTP update process at %d of %d bytes...\n", cur, total);
}
void update_error(int err) {
Serial.printf("CALLBACK: HTTP update fatal error code %d\n", err);
}
void setup() {
Serial.begin(115200);
// Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
for (uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(APSSID, APPSK);
Serial.print(F("Firmware version "));
Serial.println(FIRMWARE_VERSION);
delay(2000);
}
void loop() {
// wait for WiFi connection
if ((WiFiMulti.run() == WL_CONNECTED)) {
WiFiClient client;
// The line below is optional. It can be used to blink the LED on the board during flashing
// The LED will be on during download of one buffer of data from the network. The LED will
// be off during writing that buffer to flash
// On a good connection the LED should flash regularly. On a bad connection the LED will be
// on much longer than it will be off. Other pins than LED_BUILTIN may be used. The second
// value is used to put the LED on. If the LED is on with HIGH, that value should be passed
ESPhttpUpdate.setLedPin(LED_BUILTIN, LOW);
// Add optional callback notifiers
ESPhttpUpdate.onStart(update_started);
ESPhttpUpdate.onEnd(update_finished);
ESPhttpUpdate.onProgress(update_progress);
ESPhttpUpdate.onError(update_error);
ESPhttpUpdate.rebootOnUpdate(false); // remove automatic update
Serial.println(F("Update start now!"));
// t_httpUpdate_return ret = ESPhttpUpdate.update(client, "http://192.168.1.70:3000/firmware/httpUpdateNew.bin");
// Or:
t_httpUpdate_return ret = ESPhttpUpdate.update(client, "192.168.1.70", 3000, "/firmware/httpUpdateNew.bin");
switch (ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
Serial.println(F("Retry in 10secs!"));
delay(10000); // Wait 10secs
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
delay(1000); // Wait a second and restart
ESP.restart();
break;
}
}
}
Remember to add your SSID and PASSWD
If you upload the sketch you will get this error on Serial output.
[SETUP] WAIT 4...
[SETUP] WAIT 3...
[SETUP] WAIT 2...
[SETUP] WAIT 1...
CALLBACK: HTTP update fatal error code -104
HTTP_UPDATE_FAILD Error (-104): Wrong HTTP Code
This because It can’t find the Firmware on path http://192.168.1.70:3000/firmware/httpUpdateNew.bin, and the server return an HTTP code 404 Not found.
If you stop the server receive
[SETUP] WAIT 4...
[SETUP] WAIT 3...
[SETUP] WAIT 2...
[SETUP] WAIT 1...
Firmware version 0.1
Update start now!
CALLBACK: HTTP update fatal error code -1
HTTP_UPDATE_FAILD Error (-1): HTTP error: connection failed
Retry in 10secs!
Generate binary file
Refer to the article “esp8266: flash del firmware binario(.bin) compilato e firmato”. to understand all type of compiled binary file.
Follow these steps to generate binary file:
- Click on
Sketch -> Export Compiled Binary
;
- Click on
Sketch -> Open Sketch Folder
; - Rename the .bin file to
httpUpdateNew.bin
.
Create download url
Now return to OTAServer
folder and:
- Create
firmware
folder. - Put a
httpUpdateNew.bin
file inside the firmware folder. - Add to your index.js the download URL in GET
const express = require('express');
const { networkInterfaces } = require('os');
const path = require('path');
const app = express();
const nets = networkInterfaces();
// Server port
const PORT = 3000;
app.get('/', (request, response) => response.send('Hello from www.mischianti.org!'));
let downloadCounter = 1;
app.get('/firmware/httpUpdateNew.bin', (request, response) => {
response.download(path.join(__dirname, 'firmware/httpUpdateNew.bin'), 'httpUpdateNew.bin', (err)=>{
if (err) {
console.error("Problem on download firmware: ", err)
}else{
downloadCounter++;
}
});
console.log('Your file has been downloaded '+downloadCounter+' times!')
})
app.listen(PORT, () => {
const results = {}; // Or just '{}', an empty object
for (const name of Object.keys(nets)) {
for (const net of nets[name]) {
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
if (net.family === 'IPv4' && !net.internal) {
if (!results[name]) {
results[name] = [];
}
results[name].push(net.address);
}
}
}
console.log('Listening on port '+PORT+'\n', results)
});
- Restart application with
Ctrl+C
andnode index.js
. - Test the URL by write in the Browser URL
http://192.168.1.70:3000/firmware/httpUpdateNew.bin
If all ok, the download start, and you can find in the console these lines
D:\Projects\IdeaProjects\OTAWebPages\OTAServer>node index.js
Listening on port 3000
{
'VirtualBox Host-Only Network': [ '192.168.56.1' ],
'VMware Network Adapter VMnet1': [ '192.168.113.1' ],
'VMware Network Adapter VMnet8': [ '192.168.116.1' ],
Ethernet: [ '192.168.1.70' ]
}
Your file has been downloaded 1 times!
Your file has been downloaded 2 times!
Final test
Now if we change FIRMWARE_VERISON to 0.2 and retry the result become like so:
[SETUP] WAIT 4...
[SETUP] WAIT 3...
[SETUP] WAIT 2...
[SETUP] WAIT 1...
Firmware version 0.1
Update start now!
CALLBACK: HTTP update process started
CALLBACK: HTTP update process at 0 of 307872 bytes...
CALLBACK: HTTP update process at 0 of 307872 bytes...
CALLBACK: HTTP update process at 4096 of 307872 bytes...
CALLBACK: HTTP update process at 8192 of 307872 bytes...
CALLBACK: HTTP update process at 12288 of 307872 bytes...
CALLBACK: HTTP update process at 16384 of 307872 bytes...
CALLBACK: HTTP update process at 20480 of 307872 bytes...
CALLBACK: HTTP update process at 24576 of 307872 bytes...
CALLBACK: HTTP update process at 28672 of 307872 bytes...
CALLBACK: HTTP update process at 32768 of 307872 bytes...
CALLBACK: HTTP update process at 36864 of 307872 bytes...
CALLBACK: HTTP update process at 40960 of 307872 bytes...
CALLBACK: HTTP update process at 45056 of 307872 bytes...
CALLBACK: HTTP update process at 49152 of 307872 bytes...
CALLBACK: HTTP update process at 53248 of 307872 bytes...
CALLBACK: HTTP update process at 57344 of 307872 bytes...
CALLBACK: HTTP update process at 61440 of 307872 bytes...
CALLBACK: HTTP update process at 65536 of 307872 bytes...
CALLBACK: HTTP update process at 69632 of 307872 bytes...
CALLBACK: HTTP update process at 73728 of 307872 bytes...
CALLBACK: HTTP update process at 77824 of 307872 bytes...
CALLBACK: HTTP update process at 81920 of 307872 bytes...
CALLBACK: HTTP update process at 86016 of 307872 bytes...
CALLBACK: HTTP update process at 90112 of 307872 bytes...
CALLBACK: HTTP update process at 94208 of 307872 bytes...
CALLBACK: HTTP update process at 98304 of 307872 bytes...
CALLBACK: HTTP update process at 102400 of 307872 bytes...
CALLBACK: HTTP update process at 106496 of 307872 bytes...
CALLBACK: HTTP update process at 110592 of 307872 bytes...
CALLBACK: HTTP update process at 114688 of 307872 bytes...
CALLBACK: HTTP update process at 118784 of 307872 bytes...
CALLBACK: HTTP update process at 122880 of 307872 bytes...
CALLBACK: HTTP update process at 126976 of 307872 bytes...
CALLBACK: HTTP update process at 131072 of 307872 bytes...
CALLBACK: HTTP update process at 135168 of 307872 bytes...
CALLBACK: HTTP update process at 139264 of 307872 bytes...
CALLBACK: HTTP update process at 143360 of 307872 bytes...
CALLBACK: HTTP update process at 147456 of 307872 bytes...
CALLBACK: HTTP update process at 151552 of 307872 bytes...
CALLBACK: HTTP update process at 155648 of 307872 bytes...
CALLBACK: HTTP update process at 159744 of 307872 bytes...
CALLBACK: HTTP update process at 163840 of 307872 bytes...
CALLBACK: HTTP update process at 167936 of 307872 bytes...
CALLBACK: HTTP update process at 172032 of 307872 bytes...
CALLBACK: HTTP update process at 176128 of 307872 bytes...
CALLBACK: HTTP update process at 180224 of 307872 bytes...
CALLBACK: HTTP update process at 184320 of 307872 bytes...
CALLBACK: HTTP update process at 188416 of 307872 bytes...
CALLBACK: HTTP update process at 192512 of 307872 bytes...
CALLBACK: HTTP update process at 196608 of 307872 bytes...
CALLBACK: HTTP update process at 200704 of 307872 bytes...
CALLBACK: HTTP update process at 204800 of 307872 bytes...
CALLBACK: HTTP update process at 208896 of 307872 bytes...
CALLBACK: HTTP update process at 212992 of 307872 bytes...
CALLBACK: HTTP update process at 217088 of 307872 bytes...
CALLBACK: HTTP update process at 221184 of 307872 bytes...
CALLBACK: HTTP update process at 225280 of 307872 bytes...
CALLBACK: HTTP update process at 229376 of 307872 bytes...
CALLBACK: HTTP update process at 233472 of 307872 bytes...
CALLBACK: HTTP update process at 237568 of 307872 bytes...
CALLBACK: HTTP update process at 241664 of 307872 bytes...
CALLBACK: HTTP update process at 245760 of 307872 bytes...
CALLBACK: HTTP update process at 249856 of 307872 bytes...
CALLBACK: HTTP update process at 253952 of 307872 bytes...
CALLBACK: HTTP update process at 258048 of 307872 bytes...
CALLBACK: HTTP update process at 262144 of 307872 bytes...
CALLBACK: HTTP update process at 266240 of 307872 bytes...
CALLBACK: HTTP update process at 270336 of 307872 bytes...
CALLBACK: HTTP update process at 274432 of 307872 bytes...
CALLBACK: HTTP update process at 278528 of 307872 bytes...
CALLBACK: HTTP update process at 282624 of 307872 bytes...
CALLBACK: HTTP update process at 286720 of 307872 bytes...
CALLBACK: HTTP update process at 290816 of 307872 bytes...
CALLBACK: HTTP update process at 294912 of 307872 bytes...
CALLBACK: HTTP update process at 299008 of 307872 bytes...
CALLBACK: HTTP update process at 303104 of 307872 bytes...
CALLBACK: HTTP update process at 307200 of 307872 bytes...
CALLBACK: HTTP update process at 307872 of 307872 bytes...
CALLBACK: HTTP update process at 307872 of 307872 bytes...
CALLBACK: HTTP update process at 307872 of 307872 bytes...
CALLBACK: HTTP update process finished
HTTP_UPDATE_OK
ets Jan 8 2013,rst cause:2, boot mode:(3,7)
load 0x4010f000, len 3460, room 16
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4
tail 4
chksum 0xc9
csum 0xc9
v0005cd10
@cp:B0
ld
[SETUP] WAIT 4...
[SETUP] WAIT 3...
[SETUP] WAIT 2...
[SETUP] WAIT 1...
Firmware version 0.2
To prevent continuously update you must use a timer or an action that do that work.
Automatic FileSystem OTA update every application start
As same manner we can manage filesystem update. Let’s go fast now, because It’s the same logic of firmware update.
Generate FileSystem binary file
To manage filesystem data you must install the relative plugin, select one of this
WeMos D1 mini (esp8266), integrated SPIFFS Filesystem (deprecated)
WeMos D1 mini (esp8266), integrated LittleFS Filesystem (reccomended)
Now we are going to add data
directory to the sketch folder, and we create a file version.txt
with this content
0.2
and use the plugin to upload.
In the console we find the right command to generate this file.
[LittleFS] data : D:\Projects\Arduino\sloeber-workspace-OTA\ArduinoOTAesp8266_basic_fs_http_update\data
[LittleFS] size : 2024
[LittleFS] page : 256
[LittleFS] block : 8192
/version.txt
[LittleFS] upload : C:\Users\renzo\AppData\Local\Temp\arduino_build_649994/ArduinoOTAesp8266_basic_fs_http_update.mklittlefs.bin
[LittleFS] address : 0x200000
[LittleFS] reset : --before default_reset --after hard_reset
[LittleFS] port : COM17
[LittleFS] speed : 921600
[LittleFS] python : C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\tools\python3\3.7.2-post1\python3.exe
[LittleFS] uploader : C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\tools\upload.py
esptool.py v3.0
Serial port COM17
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 68:c6:3a:a6:32:e5
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 2072576 bytes to 2279...
Writing at 0x00200000... (100 %)
Wrote 2072576 bytes (2279 compressed) at 0x00200000 in 0.1 seconds (effective 312864.3 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
[LittleFS] data : D:\Projects\Arduino\sloeber-workspace-OTA\ArduinoOTAesp8266_basic_fs_http_update\data
[LittleFS] size : 2024
[LittleFS] page : 256
[LittleFS] block : 8192
/version.txt
[LittleFS] upload : C:\Users\renzo\AppData\Local\Temp\arduino_build_649994/ArduinoOTAesp8266_basic_fs_http_update.mklittlefs.bin
[LittleFS] address : 0x200000
[LittleFS] reset : --before default_reset --after hard_reset
[LittleFS] port : COM17
[LittleFS] speed : 921600
[LittleFS] python : C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\tools\python3\3.7.2-post1\python3.exe
[LittleFS] uploader : C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\tools\upload.py
esptool.py v3.0
Serial port COM17
Now we can grab a lot of information, like the file
[LittleFS] upload : C:\Users\renzo\AppData\Local\Temp\arduino_build_649994/ArduinoOTAesp8266_basic_fs_http_update.mklittlefs.bin
Create sketch
Now we are going to modify the sketch already used for firmware.
/*
* Basic Sketch for automatic update of filesystem at start
*
* Renzo Mischianti <www.mischianti.org>
*
* https://mischianti.org
*/
#include <Arduino.h>
#include "LittleFS.h"
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#ifndef APSSID
#define APSSID "<YOUR-SSID>"
#define APPSK "<YOUR-PASSWD>"
#endif
ESP8266WiFiMulti WiFiMulti;
#define FIRMWARE_VERSION "0.1"
void update_started() {
Serial.println("CALLBACK: HTTP update process started");
}
void update_finished() {
Serial.println("CALLBACK: HTTP update process finished");
}
void update_progress(int cur, int total) {
Serial.printf("CALLBACK: HTTP update process at %d of %d bytes...\n", cur, total);
}
void update_error(int err) {
Serial.printf("CALLBACK: HTTP update fatal error code %d\n", err);
}
void setup() {
Serial.begin(115200);
// Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
for (uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(APSSID, APPSK);
Serial.print(F("Firmware version "));
Serial.println(FIRMWARE_VERSION);
Serial.print(F("Inizializing FS..."));
if (LittleFS.begin()){
Serial.println(F("done."));
}else{
Serial.println(F("fail."));
}
String fileSystemVersion = "Not set!";
Serial.print(F("FileSystem version "));
File versionFile = LittleFS.open(F("/version.txt"), "r");
if (versionFile) {
fileSystemVersion = versionFile.readString();
versionFile.close();
}
Serial.println(fileSystemVersion);
delay(2000);
}
void loop() {
// wait for WiFi connection
if ((WiFiMulti.run() == WL_CONNECTED)) {
WiFiClient client;
// The line below is optional. It can be used to blink the LED on the board during flashing
// The LED will be on during download of one buffer of data from the network. The LED will
// be off during writing that buffer to flash
// On a good connection the LED should flash regularly. On a bad connection the LED will be
// on much longer than it will be off. Other pins than LED_BUILTIN may be used. The second
// value is used to put the LED on. If the LED is on with HIGH, that value should be passed
ESPhttpUpdate.setLedPin(LED_BUILTIN, LOW);
// Add optional callback notifiers
ESPhttpUpdate.onStart(update_started);
ESPhttpUpdate.onEnd(update_finished);
ESPhttpUpdate.onProgress(update_progress);
ESPhttpUpdate.onError(update_error);
ESPhttpUpdate.rebootOnUpdate(false); // remove automatic update
Serial.println(F("Update start now!"));
t_httpUpdate_return ret = ESPhttpUpdate.updateFS(client, "http://192.168.1.70:3000/filesystem/httpUpdateNewFS.bin");
switch (ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
Serial.println(F("Retry in 10secs!"));
delay(10000); // Wait 10secs
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
delay(1000); // Wait a second and restart
ESP.restart();
break;
}
}
}
At start you get on Serial output this result
[SETUP] WAIT 4...
[SETUP] WAIT 3...
[SETUP] WAIT 2...
[SETUP] WAIT 1...
Firmware version 0.1
Inizializing FS...done.
FileSystem version 0.2
Update start now!
CALLBACK: HTTP update fatal error code -102
HTTP_UPDATE_FAILD Error (-102): File Not Found (404)
Retry in 10secs!
The filesystem version if grabbed from version.txt file and show with this code
String fileSystemVersion = "Not set!";
Serial.print(F("FileSystem version "));
File versionFile = LittleFS.open(F("/version.txt"), "r");
if (versionFile) {
fileSystemVersion = versionFile.readString();
versionFile.close();
}
Serial.println(fileSystemVersion);
and the core line code is
t_httpUpdate_return ret = ESPhttpUpdate.updateFS(client, "http://192.168.1.70:3000/filesystem/httpUpdateNewFS.bin");
that manage the download and update.
Create FileSystem download end-point
Now we add the download end point to the implementation of the server.
- In OTAServer create the folder filesystem,
- Change version to
0.3
inversion.txt
, regenerate without upload, and copy the fileArduinoOTAesp8266_basic_fs_http_update.mklittlefs.bin
to the folder - Rename in
httpUpdateNewFS.bin
.
Now modify the original by add the highlighted code.
const express = require('express');
const { networkInterfaces } = require('os');
const path = require('path');
const app = express();
const nets = networkInterfaces();
// Server port
const PORT = 3000;
app.get('/', (request, response) => response.send('Hello from www.mischianti.org!'));
let downloadCounter = 1;
app.get('/firmware/httpUpdateNew.bin', (request, response) => {
response.download(path.join(__dirname, 'firmware/httpUpdateNew.bin'), 'httpUpdateNew.bin', (err)=>{
if (err) {
console.error("Problem on download firmware: ", err)
}else{
downloadCounter++;
}
});
console.log('Your file has been downloaded '+downloadCounter+' times!')
})
let downloadFSCounter = 1;
app.get('/filesystem/httpUpdateNewFS.bin', (request, response) => {
response.download(path.join(__dirname, 'filesystem/httpUpdateNewFS.bin'), 'httpUpdateNewFS.bin', (err)=>{
if (err) {
console.error("Problem on download filesystem: ", err)
}else{
downloadFSCounter++;
}
});
console.log('Your file FS has been downloaded '+downloadFSCounter+' times!')
})
app.listen(PORT, () => {
const results = {}; // Or just '{}', an empty object
for (const name of Object.keys(nets)) {
for (const net of nets[name]) {
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
if (net.family === 'IPv4' && !net.internal) {
if (!results[name]) {
results[name] = [];
}
results[name].push(net.address);
}
}
}
console.log('Listening on port '+PORT+'\n', results)
});
Final test
[SETUP] WAIT 4...
[SETUP] WAIT 3...
[SETUP] WAIT 2...
[SETUP] WAIT 1...
Firmware version 0.1
Inizializing FS...done.
FileSystem version 0.2
Update start now!
CALLBACK: HTTP update process started
CALLBACK: HTTP update process at 0 of 2072576 bytes...
CALLBACK: HTTP update process at 0 of 2072576 bytes...
CALLBACK: HTTP update process at 4096 of 2072576 bytes...
CALLBACK: HTTP update process at 8192 of 2072576 bytes...
CALLBACK: HTTP update process at 12288 of 2072576 bytes...
CALLBACK: HTTP update process at 16384 of 2072576 bytes...
CALLBACK: HTTP update process at 20480 of 2072576 bytes...
CALLBACK: HTTP update process at 24576 of 2072576 bytes...
CALLBACK: HTTP update process at 28672 of 2072576 bytes...
CALLBACK: HTTP update process at 32768 of 2072576 bytes...
CALLBACK: HTTP update process at 36864 of 2072576 bytes...
CALLBACK: HTTP update process at 40960 of 2072576 bytes...
CALLBACK: HTTP update process at 45056 of 2072576 bytes...
CALLBACK: HTTP update process at 49152 of 2072576 bytes...
CALLBACK: HTTP update process at 53248 of 2072576 bytes...
[...]
CALLBACK: HTTP update process at 1994752 of 2072576 bytes...
CALLBACK: HTTP update process at 1998848 of 2072576 bytes...
CALLBACK: HTTP update process at 2002944 of 2072576 bytes...
CALLBACK: HTTP update process at 2007040 of 2072576 bytes...
CALLBACK: HTTP update process at 2011136 of 2072576 bytes...
CALLBACK: HTTP update process at 2015232 of 2072576 bytes...
CALLBACK: HTTP update process at 2019328 of 2072576 bytes...
CALLBACK: HTTP update process at 2023424 of 2072576 bytes...
CALLBACK: HTTP update process at 2027520 of 2072576 bytes...
CALLBACK: HTTP update process at 2031616 of 2072576 bytes...
CALLBACK: HTTP update process at 2035712 of 2072576 bytes...
CALLBACK: HTTP update process at 2039808 of 2072576 bytes...
CALLBACK: HTTP update process at 2043904 of 2072576 bytes...
CALLBACK: HTTP update process at 2048000 of 2072576 bytes...
CALLBACK: HTTP update process at 2052096 of 2072576 bytes...
CALLBACK: HTTP update process at 2056192 of 2072576 bytes...
CALLBACK: HTTP update process at 2060288 of 2072576 bytes...
CALLBACK: HTTP update process at 2064384 of 2072576 bytes...
CALLBACK: HTTP update process at 2068480 of 2072576 bytes...
CALLBACK: HTTP update process at 2072576 of 2072576 bytes...
CALLBACK: HTTP update process at 2072576 of 2072576 bytes...
CALLBACK: HTTP update process at 2072576 of 2072576 bytes...
CALLBACK: HTTP update process finished
HTTP_UPDATE_OK
ets Jan 8 2013,rst cause:2, boot mode:(3,7)
load 0x4010f000, len 3460, room 16
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4
tail 4
chksum 0xc9
csum 0xc9
v00065100
~ld
[SETUP] WAIT 4...
[SETUP] WAIT 3...
[SETUP] WAIT 2...
[SETUP] WAIT 1...
Firmware version 0.1
Inizializing FS...done.
FileSystem version 0.3
Thanks
- Firmware management
- OTA update with Arduino IDE
- OTA update with Web Browser
- Self OTA uptate from HTTP server
- Non standard Firmware update
Confused about the behaviour of the server you proposed (under JS) I tested the line python3 http.server 3000 and It works. No more is added. One code line, no more. I deal, by the moment, with the first step. This code line I suggest is able to manage GET asks proposed from the ESP8266. Greetings.
Hi Miguel,
the server is quite simple, if you have difficult in something particular, ask without problem.
Bye Renzo