ESP8266 Webserver with SPIFFS, display sensor signals - Example?

Hello together!

I have an ESP8266 running with Wifi, Webserver and SPIFFS, which works fine! I can upload index.html even with CSS and all this stuff and access the webpage via phone. So far so good...

What I want to do is to design a webpage with some buttons, forms and displays(!!!) to control my LED Lamps and store it on my EPS8266. It shall replace Blynk when I don't have internet access.

I am able to put buttons, forms etc and send the data to the ESP8266, but not other way around. All examples I found for displaying e.g. temperatures are "generating" the html code with strings inside the arduino sketch. This way one can manipulate the page content with a temperature value and send this to the browser, of course, but it becomes a disease when it comes to bigger, more complicated HTML pages.

So whats my question?
Can anybody explain to me how I can send data from the ESP8266 (e.g. temperature) to a webpage hosted in the SPIFFS? A working example would be great! I can't find anything like this in the web.

It shall be possible to manipulate e.g. a button color, text or something depending on data send from the ESP8266 webserver or not?

Best regards
Daniel

What is a "SPIFFS"?

Oh thats the filesystem belonging to the ESP8266 core. It works like a USB stick, one can just upload files to it like "index.html" and it the browser requests it, the Webserver will pick it from the file system and send it.

However this means, that the webpage itself and the arduino sketch are separated. So i am wondering if I e.g. place a text field in my index.html, store it on the file system and let the browser open it, how can I manipulate teh content of this webpage?

Best regards
Daniel

The below is for the arduino ethernet shield, but may port to the esp8266 platform. In the below, analog data is displayed in a frame in the web page. You should be able to serve the static main page with iframes for the data display, from the SPIFFS memory location, and then populate the iframes with real time data from the esp8266. As to buttons I usually avoided refreshing the main page by returning the status code 204. Been a long time since tinkering with this, but now have a wemos esp8266 board and would like to port this to the wifi board. probably lots of html ways to display data.

// zoomkat's meta refresh data frame test page 5/25/13
// use http://192.168.1.102:84 in your brouser for main page
// http://192.168.1.102:84/data static data page
// http://192.168.1.102:84/datastart meta refresh data page
// for use with W5100 based ethernet shields
// set the refresh rate to 0 for fastest update
// use STOP for single data updates

#include <SPI.h>
#include <Ethernet.h>

const int analogInPin0 = A0;
const int analogInPin1 = A1;
const int analogInPin2 = A2;
const int analogInPin3 = A3;
const int analogInPin4 = A4;
const int analogInPin5 = A5;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // arduino ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
unsigned long int x=0; //set refresh counter to 0
String readString; 

//////////////////////

void setup(){
  Serial.begin(9600);
    // disable SD SPI if memory card in the uSD slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();
  Serial.println("meta refresh data frame test 5/25/13"); // so I can keep track of what is loaded
}

void loop(){
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
         if (readString.length() < 100) {
          readString += c; 
         } 
        //check if HTTP request has ended
        if (c == '\n') {

          //check get atring received
          Serial.println(readString);

          //output HTML data header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          //generate data page
          if(readString.indexOf("data") >0) {  //checks for "data" page
            x=x+1; //page upload counter
            client.print("<HTML><HEAD>");
            //meta-refresh page every 1 seconds if "datastart" page
            if(readString.indexOf("datastart") >0) client.print("<meta http-equiv='refresh' content='1'>"); 
            //meta-refresh 0 for fast data
            if(readString.indexOf("datafast") >0) client.print("<meta http-equiv='refresh' content='0'>"); 
            client.print("<title>Zoomkat's meta-refresh test</title></head><BODY>
");
            client.print("page refresh number: ");
            client.print(x); //current refresh count
            client.print("

");
            
              //output the value of each analog input pin
            client.print("analog input0 is: ");
            client.print(analogRead(analogInPin0));
            
            client.print("
analog input1 is: ");
            client.print(analogRead(analogInPin1));
                        
            client.print("
analog input2 is: ");
            client.print(analogRead(analogInPin2));
            
            client.print("
analog input3 is: ");
            client.print(analogRead(analogInPin3));
                                    
            client.print("
analog input4 is: ");
            client.print(analogRead(analogInPin4));
            
            client.print("
analog input5 is: ");
            client.print(analogRead(analogInPin5));
            client.println("
</BODY></HTML>");
           }
          //generate main page with iframe
          else
          {
            client.print("<HTML><HEAD><TITLE>Zoomkat's frame refresh test</TITLE></HEAD>");
            client.print("Zoomkat's Arduino frame meta refresh test 5/25/13");
            client.print("

Arduino analog input data frame:
");
            client.print(F("<a href='/data' target='DataBox'><button type='button'>SINGLE-STOP</button></a>"));
            client.print(F("<a href='/datastart' target='DataBox'><button type='button'>META-REFRESH</button></a>"));
            client.print(F("<a href='/datafast' target='DataBox'><button type='button'>FAST-DATA</button></a>
"));
            
            client.print("<iframe src='/data' width='350' height='250' name='DataBox'>");
            client.print("</iframe>
</HTML>");
          }
          delay(1);
          //stopping client
          client.stop();
          //clearing string for next read
          readString="";
        }
      }
    }
  }
}

i usually store JS,HTML,CSS scripts into flash ( just like spiffs) like this

const char homePage[] PROGMEM = R"=====(       // start of array                     
                            
                            <html>
                            <head>
                            <title> your title </title>

                            <style>
                            </style> 

                            </head>

                             <body>

                            <script>
                            // all JS goes here
                            </script>

                            </body>
                            </html>

   )=====";   // end of array

you can even embed your images in the tags to get rendered on client's browser just fine with this simple trick

 background-image: url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgA...shssksk');

this URL lets you convert/encode your image into base64

and use this to render your page ( defined above )

 server.send_P(200, "text/html", homePage, sizeof(homePage) );

that way you will never run into stack crash issues,

you can dynamically fetch ( or even send ) data from (to) ESP to (from) your browser with AJAX XMLHttpRequest() just like this

<script>


function send_data ( what_to_send ) {    // formatted as:    score?var1=874&var2=984
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
gotResponse( this.responseText );    // you get the response from ESP here, ie:  data_ = "34466" is received here as string
}
};
 xhttp.open("GET", what_to_send , true);
 xhttp.send();
}


</script>

and on ESP receives/replies as

server.on("/score", processThem );


void   processThem() {

String var11 = server.arg("var1");  // you get  874
String var22 = server.arg("var2");  // you get  984

String data_ = "34466";

 server.send(200, "text/plain", data_ );  // this is where you send your data back to browser

}

So whats my question?
Can anybody explain to me how I can send data from the ESP8266 (e.g. temperature) to a webpage hosted in the SPIFFS? A working example would be great! I can't find anything like this in the web.

You might want to search for some examples that implement 'websockets'.

Don

Take a look at ESP8266 Web Server using SPIFFS with Arduino IDE (NodeMCU) | Random Nerd Tutorials

ffur