HTML on SD card with Arduino variable Strings

Hello

I am trying to make an HTML page that can read the filenames on the SD card.
This is working when I type the HTML code in the Arduino IDE, but I want to have the HTML file on the SD card and let the Arduino read the file.

Here is the full code:

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(172, 30, 107, 24);
EthernetServer server(80);

String fileNames[13];
int f;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ;
  }

  Ethernet.begin(mac, ip);

  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  server.begin();

  searchSDFiles();
}

void loop() {
  for (int i = 0; i < f; i++) {
    Serial.println(fileNames[i]);
  }
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<head>");
          client.println("</head>");
          client.println("<body>");
          client.println("<select class=\"files\">");

          for (int i = 0; i < f; i++) {
            client.println("<option value=\"" + String(i) + "\">");
            client.println(fileNames[i]);
            client.println("</option>");

            Serial.println(fileNames[i]);
          }

          client.println("</select>");

          client.println("

");

          client.println("<textarea id=\"fileText\">");
          client.println("</textarea>");

          client.println("</body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}

void searchSDFiles() {
  File logFile = SD.open("/");
  File entry =  logFile.openNextFile();
  f = 0;

  while (true) {
    entry =  logFile.openNextFile();
    if (! entry) {
      // no more files
      break;
    }
    fileNames[f] = String(entry.name());

    entry.close();
    f++;
  }
}

PS: does anyone know why I can't read as many files on the SD card as I want?
when I try to read 20 files, I get no output. And when I try to read 17 files, I get strange characters in the file name.

you allocated only 13 Strings.

Yes, because otherwise it doesn't work.

than don't read more then 13. what are the memory information after compilation?

Ok, but could you please focus on the main problem.
How can I use Arduino variables in an html-file on the SD card?

azerty2001:
Ok, but could you please focus on the main problem.
How can I use Arduino variables in an html-file on the SD card?

the normal way is to have a static html file (a web page), which after load in browser requests data over AJAX

something like

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
<title>Regulator</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="styles.css">
<script src="script.js"></script>
</head>
<body onload="onLoad('I')">
	<div class="header">Values</div>
	<div id="contentDiv">
	</div>
</body>
</html>

and in script.js a fuction

function onLoad(cmd) {
  var xhr = new XMLHttpRequest();
  xhr.onerror = function(e) {
    alert(xhr.status + " " + xhr.statusText);
  }
  xhr.onload = function(e) {
    if (cmd == "E") {
      showEvents(xhr.responseText);
    } else if (cmd == "C") {
      showStats(xhr.responseText);
    } else if (cmd == "L") {
      showCsvFilesList(xhr.responseText);
    } else if (cmd == "A") {
      showAlarm(xhr.responseText);
    } else {
      showValues(xhr.responseText);
    }
  };
  xhr.open("GET", "http://" + host + ":" + restPort + "/" + cmd, true);
  xhr.send();
}

and for example the showCsvFilesList function

function showCsvFilesList(jsonData) {
  var data = JSON.parse(jsonData);
  var contentDiv = document.getElementById("contentDiv");
  var eventsHeaderDiv = document.createElement("DIV");
  eventsHeaderDiv.className = "table-header";
  eventsHeaderDiv.appendChild(createTextDiv("table-header-cell", "File"));
  eventsHeaderDiv.appendChild(createTextDiv("table-header-cell", "Size (kb)"));
  contentDiv.appendChild(eventsHeaderDiv);
  var files = data.f;
  files.sort(function(f1, f2) { return -f1.fn.localeCompare(f2.fn); });
  for (var i = 0; i < files.length; i++) {
    var file = files[i];
    var fileDiv = document.createElement("DIV");
    fileDiv.className = "table-row";
    fileDiv.appendChild(createLinkDiv("table-cell", file.fn, "/CSV/" + file.fn));
    fileDiv.appendChild(createTextDiv("table-cell table-cell-number", "" + file.size));
    contentDiv.appendChild(fileDiv);
  }
}

this are snippets from my project

You are probably running out of memory. Rather than putting all of the names in an array, search the SD card when you need the names.

I need to have the filenames stored in an array, because i need them later.

thanks for your help Juraj, but how can I send a string from the arduino to the HTML file(from the SD card) as an option.

azerty2001:
I need to have the filenames stored in an array, because i need them later.

thanks for your help Juraj, but how can I send a string from the arduino to the HTML file(from the SD card) as an option.

you would need some template engine to combine a web page template from SD card with data on Arduino. other options are to concatenate the page from constant strings and data, or send a static page to browser and let it request data from arduino and merge this data into web page in browser

what is the best option? and how do I do it, because I don't know how to start.

azerty2001:
what is the best option? and how do I do it, because I don't know how to start.

simplest is what you have.
template engines are only for bigger MCUs.
best is, to let the work be done by the browser on a client device. but then you code it for browser in Java Script or similar

I don't really understand what you mean. Could you give me a link where I can see an example of how it's done?
PS: Do you mean with template engine mysql and php?

azerty2001:
I don't really understand what you mean. Could you give me a link where I can see an example of how it's done?
PS: Do you mean with template engine mysql and php?

you know what is a template.
template engine is a general name for function/library that takes template and data and produces the output document/report

mysql is a database engine

oow ok, i think i understand it. but where can i find an example of it

azerty2001:
oow ok, i think i understand it. but where can i find an example of it

I didn't found one for AVR boards. Only for esp8266.
You run out of memory already. You don't have enough RAM for template engine.

also with Arduino Mega?

azerty2001:
also with Arduino Mega?

Mega is good

here Arduino web server template engine - Programming Questions - Arduino Forum

i have watched a video about the esp8266 and that is maybe a good solution for my problem. But does they exist so I can use a network cable, instead of wifi?

azerty2001:
i have watched a video about the esp8266 and that is maybe a good solution for my problem. But does they exist so I can use a network cable, instead of wifi?

yes, but it would be strange to use a chip with build-in WiFi with Ethernet