ESP8266 Web Server using SPIFFS (SPI Flash File System) – NodeMCU

This tutorial shows how to build a web server that serves HTML and CSS files stored on the ESP8266 NodeMCU filesystem (SPIFFS) using Arduino IDE. Instead of having to write the HTML and CSS text into the Arduino sketch, we’ll create separate HTML and CSS files.

ESP8266 Web Server using SPIFFS (SPI Flash File System) HTML CSS files

The web server we’ll build shows how to control the ESP8266 outputs and how to display sensor readings. As an example, we’ll control an LED and display sensor readings from a BME280 sensor.

You can use the concepts learned in this tutorial to control any output or display sensor readings from other sensors.

Recommended reading: ESP32 Web Server using SPIFFS

Project Overview

Before going straight to the project, it’s important to outline what our web server will do, so that it’s easier to understand.

ESP8266 Web Server using SPIFFS page HTML CSS Demonstration smartphone
  • The web server controls an LED connected to the ESP8266 GPIO 2. This is the ESP8266 on-board LED. You can control any other GPIO;
  • The web server page shows two buttons: ON and OFF – to turn GPIO 2 on and off;
  • The web server page also shows the current GPIO state;
  • You’ll also use a BME280 sensor to display sensor readings (temperature, humidity, and pressure).

The following figure shows a simplified diagram to demonstrate how everything works.

ESP8266 NodeMCU SPIFFS Web Server Project Overview

Prerequisites

Before proceeding with this project, make sure you check all the following prerequisites.

1. Install ESP8266 Board in Arduino IDE

We’ll program the ESP8266 using Arduino IDE, so you must have the ESP8266 add-on installed. Follow the next tutorial to install it:

2. Filesystem Uploader Plugin

To upload files to the ESP8266 SPI Flash Filesystem (SPIFFS), we’ll use the Filesystem Uploader Plugin. Install the plugin in your Arduino IDE:

3. Installing Libraries

One of the easiest ways to build a web server using files from the filesystem is using the ESPAsyncWebServer library. 

Installing the ESPAsyncWebServer library

This library is not available to download through the Arduino IDE libraries manager. So, you need to follow the next steps to install the library:

  1. Click here to download the ESPAsyncWebServer library. You should have a .zip folder in your Downloads folder
  2. Unzip the .zip folder and you should get ESPAsyncWebServer-master folder
  3. Rename your folder from ESPAsyncWebServer-master to ESPAsyncWebServer
  4. Move the ESPAsyncWebServer folder to your Arduino IDE installation libraries folder

Alternatively, you can go to Sketch > Include Library > .zip Library and select the previously downloaded library.

Installing the ESPAsyncTCP

The ESPAsyncWebServer library also needs the ESPAsyncTCP library to operate properly. Follow the next steps to install the ESPAsyncTCP library:

  1. Click here to download the ESPAsyncTCP library. You should have a .zip folder in your Downloads folder
  2. Unzip the .zip folder and you should get ESPAsyncTCP-master folder
  3. Rename your folder from ESPAsyncTCP-master to ESPAsyncTCP
  4. Move the ESPAsyncTCP folder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

Alternatively, you can go to Sketch > Include Library > .zip Library and select the previously downloaded library.

Installing BME280 libraries

In this tutorial, we’ll display readings from a BME280 sensor (Guide with ESP8266). You need to install the following libraries:

You can install these libraries through the Arduino IDE Libraries Manager. Go to Sketch > Include Libraries > Manage Libraries. Then, search for the libraries’ name to install them.

Parts Required

ESP8266 NodeMCU BME280 Temperature Humidity Pressure Sensor LED Circuit

To proceed with this project, you need the following parts:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Schematic Diagram

Connect all the components by following the next schematic diagram.

ESP8266 NodeMCU BME280 LED Wiring Schematic Diagram
BME280ESP8266
Vin3.3V
GNDGND
SCLGPIO 5
SDAGPIO 4

Organizing Your Files

To build the web server you need three different files. The Arduino sketch, the HTML file and the CSS file. The HTML and CSS files should be saved inside a folder called data inside the Arduino sketch folder, as shown below:

ESP8266 NodeMCU SPIFFS Web Server Files Directories

Creating the HTML File

Create an index.html file with the following content or download all project files here:

<!DOCTYPE html>
<!-- 
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com  
-->
<html>
<head>
  <title>ESP8266 Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
  <h1>ESP8266 Web Server</h1>
  <p>GPIO state<strong> %STATE%</strong></p>
  <p>
    <a href="/on"><button class="button">ON</button></a>
    <a href="/off"><button class="button button2">OFF</button></a>
  </p>
  <p>
    <span class="sensor-labels">Temperature</span>
    <span id="temperature">%TEMPERATURE%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <span class="sensor-labels">Humidity</span>
    <span id="humidity">%HUMIDITY%</span>
    <sup class="units">&#37;</sup>
  </p>
  <p>
    <span class="sensor-labels">Pressure</span>
    <span id="pressure">%PRESSURE%</span>
    <sup class="units">hPa</sup>
  </p>
</body>
<script>
  setInterval(function ( ) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("temperature").innerHTML = this.responseText;
      }
    };
    xhttp.open("GET", "/temperature", true);
    xhttp.send();
  }, 10000 ) ;

  setInterval(function ( ) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("humidity").innerHTML = this.responseText;
      }
    };
    xhttp.open("GET", "/humidity", true);
    xhttp.send();
  }, 10000 ) ;

  setInterval(function ( ) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("pressure").innerHTML = this.responseText;
      }
    };
    xhttp.open("GET", "/pressure", true);
    xhttp.send();
  }, 10000 ) ;
</script>
</html>

View raw code

Because we’re using CSS and HTML in different files, we need to reference the CSS file on the HTML text.

<link rel="stylesheet" type="text/css" href="style.css">

The <link> tag tells the HTML file that you’re using an external style sheet to format how the page looks. The rel attribute specifies the nature of the external file, in this case that it is a stylesheet—the CSS file—that will be used to alter the appearance of the page.

The type attribute is set to “text/css” to indicate that you’re using a CSS file for the styles. The href attribute indicates the file location; since both the CSS and HTML files will be in the same folder, you just need to reference the filename: style.css.

In the following line, we write the first heading of our web page. In this case we have “ESP8266 Web Server”. You can change the heading to any text:

<h1>ESP8266 Web Server</h1>

Then, add a paragraph with the text “GPIO state: ” followed by the GPIO state. Because the GPIO state changes accordingly to the state of the GPIO, we can add a placeholder that will then be replaced for whatever value we set on the Arduino sketch.

To add placeholder use % signs. To create a placeholder for the state, you can use %STATE%, for example.

<p>GPIO state<strong> %STATE%</strong></p>

You attribute a value to the STATE placeholder in the Arduino sketch.

Then, create an ON and an OFF buttons. When you click the on button, we redirect the web page to to root followed by /on url. When you click the off button you are redirected to the /off url.

<a href="/on"><button class="button">ON</button></a>
<a href="/off"><button class="button button2">OFF</button></a>

Finally, create three paragraphs to display the temperature, humidity and pressure.

<p>
  <span class="sensor-labels">Temperature</span>
  <span id="temperature">%TEMPERATURE%</span>
  <sup class="units">°C</sup>
</p>
<p>
  <span class="sensor-labels">Pressure</span>
  <span id="pressure">%PRESSURE%</span>
  <sup class="units">hPa</sup>
</p>
<p>
  <span class="sensor-labels">Humidity</span>
  <span id="humidity">%HUMIDITY%</span>
  <sup class="units">%</sup>
</p>

We use the %TEMPERATURE%, %HUMIDITY% and %PRESSURE% placeholders. These will then be replaced by the actual temperature readings in the Arduino sketch.

Automatic Updates

We also add a bit of JavaScript in our HTML file that is responsible for updating the temperature readings without the need to refresh the web page.

The following snipet of code is responsible for the temperature.

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperature").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 10000 ) ;

To update the temperature, we have a setInterval() function that runs every 10 seconds.

Basically, it makes a request in the /temperature URL to get the latest temperature reading.

  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 10000 ) ;

When it receives that value, it updates the HTML element with temperature id.

if (this.readyState == 4 && this.status == 200) {
  document.getElementById("temperature").innerHTML = this.responseText;
}

In summary, this previous section is responsible for updating the temperature asynchronously. The same process is repeated for the humidity and pressure readings.

Creating the CSS File

Create the style.css file with the following content or download all project files here:

/***
   Rui Santos
   Complete project details at https://RandomNerdTutorials.com
***/

html {
  font-family: Arial;
  display: inline-block;
  margin: 0px auto;
  text-align: center;
}
h1 {
  color: #0F3376;
  padding: 2vh;
}
p {
  font-size: 1.5rem;
}
.button {
  display: inline-block;
  background-color: #008CBA;
  border: none;
  border-radius: 4px;
  color: white;
  padding: 16px 40px;
  text-decoration: none;
  font-size: 30px;
  margin: 2px;
  cursor: pointer;
}
.button2 {
  background-color: #f44336;
}
.units {
  font-size: 1.2rem;
 }
.sensor-labels {
  font-size: 1.5rem;
  vertical-align:middle;
  padding-bottom: 15px;
}

View raw code

This is just a basic CSS file to set the font size, style and color of the buttons and align the page. We won’t explain how CSS works. A good place to learn about CSS is the W3Schools website.

ESP8266 Asynchronous Web Server Sketch

Copy the following code to the Arduino IDE or download all project files here. Then, you need to type your network credentials (SSID and password) to connect the ESP8266 to your local network.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Import required libraries
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Set LED GPIO
const int ledPin = 2;
// Stores LED state
String ledState;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

String getTemperature() {
  float temperature = bme.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float temperature = 1.8 * bme.readTemperature() + 32;
  Serial.println(temperature);
  return String(temperature);
}
  
String getHumidity() {
  float humidity = bme.readHumidity();
  Serial.println(humidity);
  return String(humidity);
}

String getPressure() {
  float pressure = bme.readPressure()/ 100.0F;
  Serial.println(pressure);
  return String(pressure);
}

// Replaces placeholder with LED state value
String processor(const String& var){
  Serial.println(var);
  if(var == "STATE"){
    if(digitalRead(ledPin)){
      ledState = "ON";
    }
    else{
      ledState = "OFF";
    }
    Serial.print(ledState);
    return ledState;
  }
  else if (var == "TEMPERATURE"){
    return getTemperature();
  }
  else if (var == "HUMIDITY"){
    return getHumidity();
  }
  else if (var == "PRESSURE"){
    return getPressure();
  }  
}
 
void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);

  // Initialize the sensor
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // Initialize SPIFFS
  if(!SPIFFS.begin()){
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP32 Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/index.html", String(), false, processor);
  });
  
  // Route to load style.css file
  server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/style.css", "text/css");
  });

  // Route to set GPIO to HIGH
  server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){
    digitalWrite(ledPin, HIGH);    
    request->send(SPIFFS, "/index.html", String(), false, processor);
  });
  
  // Route to set GPIO to LOW
  server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){
    digitalWrite(ledPin, LOW);    
    request->send(SPIFFS, "/index.html", String(), false, processor);
  });

  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", getTemperature().c_str());
  });
  
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", getHumidity().c_str());
  });
  
  server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", getPressure().c_str());
  });

  // Start server
  server.begin();
}
 
void loop(){
  
}

View raw code

How the code works

Continue reading to learn how the code works, or skip to the next section.

First, include the necessary libraries:

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

You need to type your network credentials in the following variables:

const char* ssid = "REPLACE_WITH_YOUR_SSID"; 
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Create an instance that refers to the BME280 sensor called bme:

Adafruit_BME280 bme; // I2C

Next, create a variable that refers to GPIO 2 called ledPin, and a String variable to hold the led state: ledState.

const int ledPin = 2;
String ledState;

Create an AsynWebServer object called server that is listening on port 80.

AsyncWebServer server(80);

Get Sensor Readings

We create three functions to return the sensor readings as strings: the getTemperature(), getHumidity() and getPressure() functions.

Here’s how the getTemperature() function looks like (the other functions are similar).

String getTemperature() {
  float temperature = bme.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float temperature = 1.8 * bme.readTemperature() + 32;
  Serial.println(temperature);
  return String(temperature);
}

If you want to display temperature in Fahrenheit degrees, you just need to uncomment the corresponding line in the getTemperature() function:

float temperature = 1.8 * bme.readTemperature() + 32;

To learn more about interfacing the BME280 sensor with the ESP8266, you can read the following tutorial:

processor()

The processor() function attributes a value to the placeholders we’ve created on the HTML file. It accepts as argument the placeholder and should return a String that will replace the placeholder. The processor() function should have the following structure:

String processor(const String& var){
  Serial.println(var);
  if(var == "STATE"){
    if(digitalRead(ledPin)){
      ledState = "ON";
    }
    else{
      ledState = "OFF";
    }
    Serial.print(ledState);
    return ledState;
  }
  else if (var == "TEMPERATURE"){
    return getTemperature();
  }
  else if (var == "HUMIDITY"){
    return getHumidity();
  }
  else if (var == "PRESSURE"){
    return getPressure();
  }
}

This function first checks if the placeholder is the STATE we’ve created on the HTML file.

if(var == "STATE"){

If it is, then, accordingly to the LED state, we set the ledState variable to either ON or OFF.

if(digitalRead(ledPin)){
  ledState = "ON";
}
else{
  ledState = "OFF";
}

Finally, we return the ledState variable. This replaces the STATE placeholder with the ledState string value.

return ledState;

If it finds the %TEMPERATURE% placeholder, we return the temperature by calling the getTemperature() function created previously.

else if (var == "TEMPERATURE"){
  return getTemperature();
}

The same happens for the %HUMIDITY% and %PRESSURE% placeholders by calling the corresponding functions:

else if (var == "TEMPERATURE"){
  return getTemperature();
}
else if (var == "HUMIDITY"){
  return getHumidity();
}
else if (var == "PRESSURE"){
  return getPressure();
}  

setup()

In the setup(), start by initializing the Serial Monitor and setting the GPIO as an output.

Serial.begin(115200);
pinMode(ledPin, OUTPUT);

Initialize the BME280 sensor:

if (!bme.begin(0x76)) {
  Serial.println("Could not find a valid BME280 sensor, check wiring!");
  while (1);
}

Initialize SPIFFS:

if(!SPIFFS.begin()){
  Serial.println("An Error has occurred while mounting SPIFFS");
  return;
}

Wi-Fi connection

Connect to Wi-Fi and print the ESP8266 address:

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP());

Async Web Server

The ESPAsyncWebServer library allows us to configure the routes where the server will be listening for incoming HTTP requests and execute functions when a request is received on that route. For that, use the on method on the server object as follows:

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send(SPIFFS, "/index.html", String(), false, processor);
});

When the server receives a request on the root “/” URL, it will send the index.htmlfile to the client. The last argument of the send() function is the processor, so that we can replace the placeholder with the value we want – in this case the ledState.

Because we’ve referenced the CSS file on the HTML file, the client will make a request for the CSS file. When that happens, the CSS file is sent to the client:

server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send(SPIFFS, "/style.css","text/css");
});

You also need to define what happens on the /on and /off routes. When a request is made on those routes, the LED is either turned on or off, and the ESP32 serves the HTML file.

server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){
  digitalWrite(ledPin, HIGH);
  request->send(SPIFFS, "/index.html", String(),false, processor);
});
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){
  digitalWrite(ledPin, LOW);
  request->send(SPIFFS, "/index.html", String(),false, processor);
});

In the HTML file, we’ve written a JavaScript code that requests the temperature, humidity and pressure on the /temperature, /humidity, /pressure routes, respectively, every 10 seconds. So, we also need to handle what happens when we receive a request on those routes.

We simply need to send the updated sensor readings. The updated sensor readings are returned by the getTemperature(), getHumidity() and getPressure() functions we’ve created previously.

The readings are plain text, and should be sent as a char, so, we use the c_str() method.

server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", getTemperature().c_str());
});
  
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", getHumidity().c_str());
});
  
server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", getPressure().c_str());
});

In the end, we use the begin() method on the server object, so that the server starts listening for incoming clients.

server.begin();

Because this is an asynchronous web server, you can define all the requests in the setup(). Then, you can add other code to the loop() while the server is listening for incoming clients.

Uploading Code and Files

Save the Arduino sketch as ESP8266_SPIFFS_Web_Server or download all project files here.

  • Go to Sketch > Show Sketch folder, and create a folder called data. Save the HTML and CSS files inside that folder;
  • In Tools > Board, select the ESP8266 board you’re using;
  • Then, go to Tools > Flash size and select 4M (1M SPIFFS).
Select ESP8266 NodeMCU board with SPIFFS Arduino IDE

Finally, upload the files to your board. Go to Tools > ESP8266 Data Sketch Upload and wait for the files to be uploaded.

Upload Files to ESP8266 NodeMCU SPIFFS ESP8266 Sketch Data Upload

Then, press the Arduino IDE upload button to upload the code to the ESP8266.

Upload Code Arduino IDE to ESP8266 NodeMCU

When everything is successfully uploaded, open the Serial Monitor at a baud rate of 115200. Press the ESP8266 on-board RST button, and it should print the ESP8266 IP address.

ESP8266 NodeMCU IP address Serial Monitor Arduino IDE

Demonstration

Open a browser and type your ESP8266 IP address. The following web page should load.

ESP8266 Web Server using SPIFFS page HTML CSS Demonstration

Press the ON and OFF buttons to control the ESP8266 on-board LED. You can also visualize the latest sensor readings. The sensor readings are updated automatically without the need to refresh the web page.

Wrapping Up

Using the ESP8266 SPI Flash File System (SPIFFS) is specially useful to store HTML and CSS files to serve to a client – instead of having to write all the code in the Arduino sketch.

We have other related projects that you may like:

Learn more about the ESP8266:

Thanks for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

44 thoughts on “ESP8266 Web Server using SPIFFS (SPI Flash File System) – NodeMCU”

  1. Hello Sara,
    I just finished building a thermostat to replace my old mercury switch thermostat. In this project I used the ESP8266, DHT22, and BLYNK. I can now control my heat/ac remotely. However I want to replace BLYNK with my own server so I went out yesterday and purchased a set of books (HTML, CSS, JAVASCRIPT, and JQUERY). How fortuitous for me that your project was just posted; it will be very helpful. Thank you. I do have a question; what schematic capture software did you use in this project?

  2. Is there any project, which sends sensor data to my own website and from across the world I can see the sensors data.

  3. Great article! I’m curious about the limitations, though. How much space is available for HTML and CSS files? Enough for the web pages to be heavily graphical? Can CSS media queries be used to make the site responsive? Can php be installed so that exec() can leveraged to execute programs on the ESP8266 via a button or link on a webpage?

    • Hey Leon,

      Thanks, that’s what I thought but I have a follow up question; do I include the exclamation mark (!) on the end of Fritzing when I search for it on the WEB. Just kidding have a nice day!

  4. Great posting. It meets all of the requirements for a project I am working on except one. I won’t be where there is internet so I need the 8266 to be configured as an access point. It only needs to serve one client (a smartphone). Could you tell me how to do that? I have tried in the past with other projects, to no avail. It is no problem to set up the access point, but for some reason the asynchronous communication fails. Thanks!

  5. This tutorial is almost perfectly suited to my project.
    I need to read a value from my solar water heating system, apply human intelligence from the weather forecast and return a command to initiate a burn cycle on the boiler if the sun is not going to shine much later in the day.

    As a real beginner with software, I’d been prepare to achieve my goal by hacking various parts from other tutorials but not looking forward to it. This looks perfect for me to tweak to my requirement.

  6. Hi,
    I do not have this. I use IDE 1.8.3. Does this come in a later release or do I have to install this tool?
    ” Go to Tools > ESP8266 Data Sketch Upload

  7. I found Adafruit BME280 Library under Sketch -> Include Llibrary -> Manage Libraries… but I could not find the Adafruit Sensor library. I do see that in GitHub. Can you tell me how to load it from there? Thanks.

  8. Hello Markus,

    Look at your file preferences in IDE(FILE->Preferences) to see which directory your sketches are saved to.

    Go to that directory and see if it contains a “tools” directory.

    If it doesn’t then create a new directory path (sketchbook directory /tools /ESP8266FS /tool) or it does then add the last two folders.

    Unpack the tar file in some junk folder and then copy and paste the esp8266fs.jar it into the tool folder you just created.

    You should see the new option when you reopen IDE; look carefully.

    Regards,

    Roger

  9. Markus,
    You need to install the ESP files separately from the Arduino IDE. You do so by editing a line in preferences, which adds a selection to Boards Manager in the IDE. You then install the boards from there. Look around a bit and you’ll find the complete instructions on RNT…(a GREAT resource).
    Dave

  10. Thanks for the post! using this setup do you know how I could get the contents of an html text input form from the web page to a variable?

  11. Hi there,
    I installed this on one of my WEMOS D1 mini Pro V1.0.0 ESP8266F.X based board. I set the board type to NodeMCU 1.0 (ESP12E Module), and the Flash Size to 1M SPIFFS.
    Everything loaded and ran fine except that the functions of the webpage ‘Buttons’ (the ON button and the OFF button) were ‘Opposite’.
    When I clicked the ON, the LED went OFF, and the URL changed to I.P./off
    When I clicked the OFF, the LED went ON, and the URL changed to I.P./on
    I changed a few things in the IDE Sketch and got it to work as it should – but it doesn’t make sense why it works as it should now – any ideas?
    Here are the parts of the Sketch that I changed. You will see my commented out parts with my initials next to the line (//jhh).

    First part of change:
    if(var == “STATE”){
    if(digitalRead(ledPin)){
    ledState = “OFF”;
    // ledState = “ON”; //jhh
    }
    else{
    ledState = “ON”;
    // ledState = “OFF”; //jhh
    }

    Second part of change:
    // Route to set GPIO to HIGH
    server.on(“/on”, HTTP_GET, [](AsyncWebServerRequest *request){
    digitalWrite(ledPin, LOW);
    //digitalWrite(ledPin, HIGH); //jhh
    request->send(SPIFFS, “/index.html”, String(), false, processor);
    });

    // Route to set GPIO to LOW
    server.on(“/off”, HTTP_GET, [](AsyncWebServerRequest *request){
    digitalWrite(ledPin, HIGH);
    //digitalWrite(ledPin, LOW); //jhh
    request->send(SPIFFS, “/index.html”, String(), false, processor);
    });

    I’m not sure why, but other comments I’ve posted on your projects have never been answered, they return a message saying they are being reviewed by the moderator. Who knows, maybe this one will get a response as it could affect others. Thanks Johnhh.

    • Hi John.
      We receive lots of comments every day. It’s very difficult to review and answer every comment we receive. I’m sorry for that.

      I’ve just tested this code again and it is working properly.

      Did you connect an LED to your ESP8266 or are you just controlling the on-board LED?
      The on-board LED behaves the other way around. When you send a LOW signal it turns on, when you send a HIGH signal it turns off.
      Or are you using another pin?
      Regards,
      Sara

      • Thanks for getting back to me.
        Yes, I’m using the on-board LED, so if what you say is correct, then that makes sense. Does this only happen with the WEMOS board? My other boards behave normally.
        Another question I had was about your ESP32-Camera Motion picture capture, and was about how to improve the ‘White Balance’ on the captured picture. Any suggestions?
        Many thanks Johnhh

        • the onboard LED on the ESP8266-12E as found on the wemos has reversed logic as it is attached between Vcc and GPIO2.
          If you would add an external LED to gpio2 (through a series resistor) it should just work fine

  12. why delay is not working in this part
    server.on(“/off”, HTTP_GET, [](AsyncWebServerRequest *request){
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
    delay(1000);

    request->send(SPIFFS, “/index.html”, String(), false, processor);
    });

  13. Hi,
    Im trying to work my way through this code and have a question

    In the processor() there is a variable “var” but i cannot see how/where it gets assigned a value.

    Can someone point me in the right direction please
    I’m very much a beginner lol.
    Bob

  14. Hi
    I tried to replace your sensor with a DHT22
    Unfortunatly I’m not able to read temperature and humidity !
    I’m getting ‘nan’
    Do you have experience with this sensor and SPIFFS ?
    I can’t understand why
    Thanks for your answer
    JCB

    • Hi Usman.
      I’m sorry about that.
      We receive lots of comments every day, it is difficult to read and answer all comments.
      So, you want the LED to start blinking when you send an ON command?
      The best approach is to create a flag variable that will change accordingly to the command received.
      Then, in the loop() you decide what happens when that variable changes from one state to another.
      It is recommended to blink the LED without delay (using timers instead).
      Let me know if you need further help.
      Regards,
      Sara

  15. ESP8266 NodeMCU can be used as Web server with html webpage.  Many times you may want to add images in web page. This can be achieved with help of SPIFFS (SPI Flash File System) or use of dataURL for small size images. Lets see step by step to upload image in web page.

  16. Hi Rui, Hi Sara,
    as usual another good project and tutorial!!!
    What should I do to implement in this project the part referred to WiFiManager with ESP8266 – Autoconnect?
    In this way it will be a complete stand alone gadget to be used everywhere.

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.