Having an issue with client.print while dumping data from SD card

Greetings and happy holidays,

The setup is an ESP32, microSD module with an SD card using prerecorded data, connection via ESP32’s i.p. address in IE11 (yes… I know…)

I am trying to use client.print to display GPS data to a client. My data is stored on an SD card as written by the GPS module (using the sdFat library). When looking at the GPS data via notepad, or print to a serial monitor, everything is formatted how I desire, one line of data per line as follows:

$GPRMC,002535.000,A,xxxx.xxxx,N,0xxxx.xxxx,W,x.xx,204.10,201218,,,A*76
$GPRMC,002545.000,A,xxxx.xxxx,N,0xxxx.xxxx,W,x.xx,204.10,201218,,,A*76

However; when I use client.print, the data is displayed as two to three chunks of data per line, no spacing, as follows:

$GPRMC,002535.000,A,xxxx.xxxx,N,0xxxx.xxxx,W,x.xx,204.10,201218,,,A*76$GPRMC,002545.000,A,xxxx.xxxx,N,0xxxx.xxxxW,x.xx,180.49,201218,,,A*7E

I am not currently trying to write to the GPS when displaying the data, as for now I’m just reading some previously recorded data in the “test.txt” file – I’m calling client handler from loop(); and that’s it.
I’ve tried several iterations of for loops and other code trying to massage the data into the formatting I want and always get the same result for the most part or the page just refuses to pop up in my browser and times out.

I’m sure I am not following how File.available() works, hence the issues - arduino reference says "Returns the number of bytes available (int). And I’ve seen someone say that should be interpreted as “how much data is left” as I am guessing “read destroys”. Should I be leveraging that to insert new line? I am also wondering how the client / browser might play into this. Adding in client.println(); doesn’t seem to create a new line, or at least how I would imagined. Perhaps there’s an html thing I should be doing?

I could also being going at what I would like to do the wrong way completely. I’ve been fruitless in browser searches on the issue I’m having.

My code has quite a bit of cut and paste from various examples, which if works, I’m ok with – as I learn more I would probably rip it all up and make it “right”. My original intention was to host the .txt file in such a way I could directly download it, but coming up short on searches for a way forward on that front, the example stuff I have found doesn’t seem to work even as stock code.
Thank you for a nudge in the right direction (or a slap on the ass, if your into it).

My hacked together mess:

void clientHandler() {

  WiFiClient client = server.available(); // Listen for incoming clients

  if (client) { // If a new client connects,
    Serial.println("New Client."); // print a message out in the serial port
    String currentLine = ""; // make a String to hold incoming data from the client
    while (client.connected()) { // loop while the client's connected
      if (client.available()) { // if there's bytes to read from the client,
        char c = client.read(); // read a byte, then
        Serial.write(c); // print it out the serial monitor
        header += c;
        if (c == '\n') { // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // re-open the file for reading:
            myFile = SD.open("test.txt");
            if (myFile) {
              //client.print("test.txt:");

              // read from the file until there's nothing else in it:
              for (int i = 0; i <= 70; i++) {
                while (myFile.available()) {
                  d[i] = (myFile.read());
                  client.print(d[i]);
                }
              }
              // The HTTP response ends with another blank line
              client.println();
              // Break out of the while loop
              break;
              // close the file:
              myFile.close();

            } else {
              // if the file didn't open, print an error:
              Serial.println("error opening test.txt");
            }
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') { // if you got anything else but a carriage return character,
          currentLine += c; // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
  return;
}

use client.write(c), not print(c).

but event better, use client.write(myFile)

That works much faster, thanks so much.

However it still strings the GPS sentences together. I have found with my code that it will respond to narrowing the browser window width, I can copy it from there and do a little dance with notepad and get most of it line by line like I want. Except every so often in the file, it will be blown out into two or three sentences mashed together still. Same story with client.write(Myfile)...

I guess maybe I could figure out how to add some kind of delimiter character in the GPS to SD part of the code and use that with excel or something. Not ideal - but I'm not a choosy begger.

Again I'd really like to have it host the text file in a means I could download it directly with out all the post processing. I believe I've seen file hosting done using SPIFFS but I haven't had any luck getting the examples to work. Everything compiles, it just gives me 404's or times out. Plus I'd rather write a replaceable SD card than fry internal storage anyway.

Thanks again for the nudge!

Ryan7777:
That works much faster, thanks so much.

However it still strings the GPS sentences together. I have found with my code that it will respond to narrowing the browser window width, I can copy it from there and do a little dance with notepad and get most of it line by line like I want. Except every so often in the file, it will be blown out into two or three sentences mashed together still. Same story with client.write(Myfile)...

I guess maybe I could figure out how to add some kind of delimiter character in the GPS to SD part of the code and use that with excel or something. Not ideal - but I'm not a choosy begger.

Again I'd really like to have it host the text file in a means I could download it directly with out all the post processing. I believe I've seen file hosting done using SPIFFS but I haven't had any luck getting the examples to work. Everything compiles, it just gives me 404's or times out. Plus I'd rather write a replaceable SD card than fry internal storage anyway.

Thanks again for the nudge!

change content-type to show line ends in browser
client.println("Content-type:text/plain");

client.println("Content-type:text/plain"); works to get everything into one column, I can select all, dump to a text file and drop into google earth and it all works beautifully!

Web design and html is something I've never really messed with - but now I guess I should learn some more about that too.

Thanks again!