Ethernet Shield: HTML

First of all, I'm not new to the Arduino, I've made some (advanced) projects before.
Anyways, I have the Ethernet Shield w/ SD Card and am currently using it as a web server. I was wondering if I could have the Arduino display HTML files that are already on the SD card rather then needing to type in all the HTML in the Arduino itself.

If you would like to see my code, which is currently a little messy, here:

/*
 * local url is http://192.168.1.80:8080/
 */
#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#define greenLEDpin 8
#define redLEDpin 9
boolean led2 = true;
int hits = 0;
int count =0;

/************ ETHERNET STUFF ************/
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x00, 0x1C, 0x0E };
byte ip[] = { 
  192, 168, 1, 80 };
Server server(8080);


/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
#define error(s) error_P(PSTR(s))
void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup() {
  Serial.begin(9600);

  pinMode(greenLEDpin, OUTPUT);
  pinMode(redLEDpin, OUTPUT);

  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());  

  pinMode(10, OUTPUT);              
  digitalWrite(10, HIGH);              

  if (!card.init(SPI_FULL_SPEED, 4)) error("card.init failed!");

  if (!volume.init(&card)) error("vol.init failed!");

  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();

  if (!root.openRoot(&volume)) error("openRoot failed");

  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();

  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);

  Serial.println();
  PgmPrintln("Done");

  Ethernet.begin(mac, ip);
  server.begin();
}

void ListFiles(Client client, uint8_t flags) {

  dir_t p;

  root.rewind();
  client.println("<ul>");
  while (root.readDir(p) > 0) {
    if (p.name[0] == DIR_NAME_FREE) break;

    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') continue;

    if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;

    client.print("<li><a href=\"");
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.print('.');
      }
      client.print(p.name[i]);
    }
    client.print("\">");

    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.print('.');
      }
      client.print(p.name[i]);
    }

    client.print("</a>");

    if (DIR_IS_SUBDIR(&p)) {
      client.print('/');
    }

    if (flags & LS_DATE) {
      root.printFatDate(p.lastWriteDate);
      client.print(' ');
      root.printFatTime(p.lastWriteTime);
    }
    if (!DIR_IS_SUBDIR(&p) && (flags & LS_SIZE)) {
      client.print(' ');
      client.print(p.fileSize);
    }
    client.println("</li>");
  }
  client.println("</ul>");
}

#define BUFSIZ 1024

void loop()
{

// this is red LED blink
  if(count >=500)
  {  
    led2 = !led2;
    digitalWrite(redLEDpin, led2);
    count = 0;
  }
  count +=1;
// end red LED blink

  char clientline[BUFSIZ];
  int index = 0;

  Client client = server.available();
  if (client) {
    boolean current_line_is_blank = true;

    index = 0;

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          if (index >= BUFSIZ) 
            index = BUFSIZ -1;

          continue;
        }

        clientline[index] = 0;

        Serial.println(clientline);

        if (strstr(clientline, "GET / ") != 0) {


          /**************** Main page HTML starts here.*****************/

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html; charset=UTF-8");
          client.println();

          client.println("<html>");
          client.println("<head>");
          client.println("<title>Arduino WebServer</title>");
          client.println("</head>");

          client.println("<body>");
          client.println("
");
          client.println("<B>Hello World!!</B>");
          client.println("
");
          client.println("
");

          hits ++;
          client.print("Hits: ");
          client.print(hits);

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

          /**************** Main page HTML ends here.*****************/

        } 
        else if (strstr(clientline, "GET /") != 0) {
          char *filename;

          filename = clientline + 5; 

          (strstr(clientline, " HTTP"))[0] = 0;

          Serial.println(filename);

          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<h2>Error 404</h2>");
            client.println("<s2>You know what that means...<s2>");
            client.println("");

            break;
          }

          Serial.println("Opened!");

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/plain");
          client.println();

          int16_t c;
          while ((c = file.read()) > 0) {

            client.print((char)c);
          }
          file.close();
        } 
        else {
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>Error 404</h2>");
          client.println("<s2>You know what that means...<s2>");
          client.println("");
        }
        break;
      }
    }
    digitalWrite(greenLEDpin, HIGH);
    delay(1);
    digitalWrite(greenLEDpin, LOW);
    client.stop();
  }
}

FYI, I'm using Arduino UNO with the Arduino Ethernet Shield (W5100)

Have a look at this thread:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1291319677/6

Not my work just something I've used and it works for pictures and if memory serves html as well...

Kevin

Thanks, I got it to use HTML files properly, but I cant get it to show pictures, not even in the unedited (except for mac, ip, and port) code in the post you showed me.

Edit: I can view pictures but somehow the the file names are shortened from the original file.

For example, if the file is named "W3SCHOOLS.JPG"
it gets changed to "W3SCHO~1.JPG"

Is this a HTML thing or an Arduino thing? This isn't a big problem but can it be fixed?

Thanks a bunch!!!
It works perfectly, now I just need to design a website. :smiley:

Is this a HTML thing or an Arduino thing?

It's a FAT filesystem thing. What you're seeing is the ancient (in "computer years") filename crudeness that's hidden by modern OSes.

You may need to "think DOS" and rename your files to 8.3 form. Another alternative (which would probably speed up the operation quite a bit) is to host the images elsewhere, and just serve up links to them from the Arduino. That eliminates the need to stuff relatively large files through the skinny pipes going to the SD card and Ethernet interfaces. It also lets you give them the long file names you're accustomed to.

Ah, I see, I'm familiar with DOS, so it shouldn't be a problem.
Thanks.