Webserver on Arduino Mega and Ethernet Shield 5100 cannot display images embedded in html code from SD card

Hello,

I have set up a Mega2560 with Ethernet Shield w5100 + SD card reader. HTML code and an embedded image is loaded onto SD card.

Does anyone had the issue that html files put on SD card do not properly display images?

If I ope the index.htm file from my computer, everything is OK. If I put everything onto the Arduino, the pictures are not displayed, only a small pictogramm appears, indicating that there is an image to expect.

here is the code:

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

int led = 13;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xEF, 0xED};
EthernetServer server(80);
String readString;
File HTML_file;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(led, OUTPUT);

  if(!SD.begin(4)) {
    Serial.println("SD card initialization failed!");
    return;
  }
  Serial.println("SD card initialized.");
  if(!SD.exists("index.htm")) {
    Serial.println("index.htm not found");
    return;
  }
  Serial.println("index.htm found");
  
  Ethernet.begin(mac);
  server.begin();
  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  // put your main code here, to run repeatedly:
  
  EthernetClient client = server.available();
  
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.print(c);

        if (readString.length() < 100) {
          readString += c;
        }
        
        if ( c == '\n') {
          Serial.print(readString);
          client.println("HTTP/1.1 200 OK\n\rContent-Type: text/html\n\r\n\r");
          HTML_file = SD.open("index.htm");
          if(HTML_file) {
            while(HTML_file.available()) client.write(HTML_file.read());
            HTML_file.close();
          }
           
          delay(1);
          client.stop();

          readString = "";

        }

      }
    }
  }
}

Here is the html file ("index.htm"):

<!doctype html>
<html lang="de">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Arduino Webpage 1</title>
  </head>
  <body>
    <p>HEADLINE</p>
	<br>
	<img src="Arduinoverysmall.jpg" />
	<p>test test test	</p>
  </body>
</html>

I have reduced the image size, but it didn't help. Also bmp file type didn't help.
Seems that Ethernet Shield type w5100 cannot display images.

Any advice for me?

John

HTTP response lines are terminated with CR+LF, which is "\r\n", not the other way around (as you have it there).

But the main issue is that you are only ever returning -- as the header there says -- HTML. When a browser loads the HTML page, it finds the <img> and so it requests that src filename, expecting an image/jpeg in this case. But in return you just return the same HTML, which is of course, not the image, and not any image it all.

You are accumulating the request in readString (and printing it). You should apply some logic: if they're asking for a specific file, return the content for that file. You also have to specify the correct Content-Type for that file. Of course, the file has to be on the SD. If there is no such file, return 404, which you may have heard of.

I have a Mega 2560 with SD, and it serves several different file types. The browser makes the request for the files it parses from the html doc.

The code is large. It used to be in the playground, but I guess that's gone.

your webserver doesn't seem to be able to send differentiate pages, neither to be able to send different content types.

Hello kenb4, thank you! You are right, I need to react on client request sending the file. There is no automatism that loads the file and transfer it to the client.
Another issue was a too long filename for the image file. "Arduinoverysmall.jpg" didn't work. But "test.jpg" does.

Here is the final code:

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

int led = 13;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xEF, 0xED};
// port adress 80 for html
EthernetServer server(80);
String readString;
File HTML_file, picfile;

//---------------------------------------------------//

void setup() {
  // put your setup code here, to run once:
  
  Serial.begin(9600);
  pinMode(led, OUTPUT);

  if(!SD.begin(4)) {
    Serial.println("SD card initialization failed!");
    return;
  }
  Serial.println("SD card initialized.");
  if(!SD.exists("index.htm")) {
    Serial.println("index.htm not found");
    return;
  }
  Serial.println("index.htm found");

  if(!SD.exists("test.jpg")) {
    Serial.println("test.jpg not found");
    return;
  }
  Serial.println("test.jpg found");
  
  Ethernet.begin(mac);
  server.begin();
  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
}

//----------------------------------------------------//

void loop() {
  
  EthernetClient client = server.available();
  
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.print(c);

        if (readString.length() < 255) {
          readString += c;
        } else {
          readString = ""; // overflow
        }
        
        if ( c == '\n'  && readString.length() > 0 ) { 
          Serial.println(readString);
          Serial.println("-----------------------------------------");
          if ( readString.substring(0,22)=="GET /test.jpg HTTP/1.1" ){
            Serial.println("sending picture file test.jpg");
            picfile = SD.open("test.jpg");
            if(picfile) {
              Serial.println("picture file opened, start with sending");
              while(picfile.available()) client.write(picfile.read());
              picfile.close();
              Serial.println("test.jpg transferred");
              client.stop();
              readString = "";
            }
   
            
          } else if ( readString.substring(0,14)=="GET / HTTP/1.1" ) {
            Serial.println("sending html file");
            client.println("HTTP/1.1 200 OK\r\nContent-type: text/html");
            client.println("Connection: close\r\n");
            HTML_file = SD.open("index.htm");
            if ( HTML_file ) {
              while(HTML_file.available()) client.write(HTML_file.read());
              HTML_file.close();
              Serial.println("HTML file transferred");
              client.stop();
              readString = "";
            }
                   
          } else {
            // ignore this command / request / info  
          }
          if ( readString.length() > 1 ) {
            Serial.print("ignoring: ");Serial.println(readString);
          }  
          readString = "";
          client.stop();
        }

      } // end: client available
    } // end: client connected
  } // end: client existing
}

Thanks
John

SdFat will allow long filenames.

that sounds interesting. I will have a look into it.
Thank you!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.