Load full html on SD ( Ethernet Shield)

Good day guys! For my project im using an ENC26j80 Ethernet shield with sd card.

I am trying to make a web switch. for testing purposes I tried 1st with a simple led web switch.
Here is my code modified from the tutorials.

#include <EtherCard.h>
#include <SdFat.h>
#include <SdFatUtil.h>


// Ethernet Part declaration
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
#define BUFFER_SIZE 700
BufferFiller bfill;
byte Ethernet::buffer[BUFFER_SIZE];
static byte myip[] = {192,168,1,15};
// Ethernet Part ends here

// SD card declaration
const uint8_t SdChipSelect = 4;
Sd2Card card;
SdVolume volume;
SdFile myfile;
SdFile root;
// SD card declaration ends here

const int ledPin = 6;

// store error strings in flash to save RAM
#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);
  
   //SD card debugging

  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());
  
  if (!card.init(SPI_HALF_SPEED, 4)) error("card.init failed!");
  
  // initialize a FAT volume
  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");
  
  Serial.println();
  PgmPrintln("Done");
//SD card debugging ends here
  

//Ethernet Debugging
  Serial.println("Control WebPage");
 
  if (ether.begin(BUFFER_SIZE, mymac, 10)==0)
    Serial.println( "Failed to access Ethernet controller");
 else
   Serial.println("Ethernet controller initialized");
 
  if (!ether.staticSetup(myip))
    Serial.println("Failed to set IP address");
  Serial.println();
//Ethernet Debugging Ends Here

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



  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
}

const char http_Unauthorized[] PROGMEM =
    "HTTP/1.0 401 Unauthorized\r\n"
    "Content-Type: text/html\r\n\r\n"
    "<h1>401 Unauthorized</h1>";

void homepage(){
      bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
      "<html><head><title>WebLed</title></head>"
      "<body><center>Web Remote
"
      "<a href=\"/?cmd=ON\"><input type=\"button\" value=\"ON\"></a>
<a href=\"/?cmd=OFF\"><input type=\"button\" value=\"OFF\"></a>
"
      "<a href=\"/?cmd=HALF\"><input type=\"button\" value=\"HALF\"></a></center>"
      "</body></html>"      
      ));
}

void loop() {
  //checking for requesting client
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  

  
  if(pos) {
    bfill = ether.tcpOffset();
    
    //storing buffer on data variable
    char *data = (char *) Ethernet::buffer + pos;
    
    if (strncmp("GET /", data, 5) != 0) {
            // Unsupported HTTP request
            // 304 or 501 response would be more appropriate
            bfill.emit_p(http_Unauthorized);
        }
    else {
        data += 5;
            
            if (data[0] == ' ') {
                // Return home page
                homepage();
            }
            else if (strncmp("?cmd=ON ", data, 8) == 0) {
                homepage();
                Serial.println("Recieve ON");
                digitalWrite(ledPin, HIGH);
     
            }
            else if (strncmp("?cmd=OFF ", data, 9) == 0) {
                homepage();
                Serial.println("Recieve OFF");
                digitalWrite(ledPin, LOW);
            }
            else if (strncmp("?cmd=HALF ", data, 10) == 0) {
                homepage(); 
                Serial.println("Recieve HALF");
                analogWrite(ledPin,150);
            }
            else {
                // Page not found
                bfill.emit_p(http_Unauthorized);
            }
        }
    ether.httpServerReply(bfill.position());
  }
}

So far this program is working fine but without fetching anything from the SD card..
As you can see I am able to initialize the SD and web with no problems.
The problem is I can't load my html from the sd.

What I tried is putting the html code from void homepage() to a text file on the sd
then I did something like this inside void homepage();

myfile.open("test.txt", O_READ);
char* d;
 while ((*d = myfile.read()) > 0) {
   bfill.emit_p((char*)d);
 }

but its not working...I also tried following from the tutorial

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

the 1st one doesn't load the web page at all and upon looking at the serial monitor, it stops at "Free RAM:"
while the 2nd one always return an error of "wrong conversion of char...something like that"

So where have I gone wrong? I hope someone can hel me! thx to all! :smiley:

The file.read() function returns a char, not a char *. Don't use a non-initialiazed pointer to hold the value returned by file.read.

Don't use an int, either.

Most importantly, don't try to summarize error messages and code. Post the exact code and the exact error messages.

Thx for the reply sir!

Here is the code that I tried

#include <EtherCard.h>
#include <SdFat.h>
#include <SdFatUtil.h>


// Ethernet Part declaration
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
#define BUFFER_SIZE 700
BufferFiller bfill;
byte Ethernet::buffer[BUFFER_SIZE];
static byte myip[] = {192,168,1,15};
// Ethernet Part ends here

// SD card declaration
const uint8_t SdChipSelect = 4;
Sd2Card card;
SdVolume volume;
SdFile myfile;
SdFile root;
// SD card declaration ends here

const int ledPin = 6;

// store error strings in flash to save RAM
#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);
  
   //SD card debugging

  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());
  
  if (!card.init(SPI_HALF_SPEED, 4)) error("card.init failed!");
  
  // initialize a FAT volume
  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");


  Serial.println();
  PgmPrintln("Done");
//SD card debugging ends here
  

//Ethernet Debugging
  Serial.println("Control WebPage");
 
  if (ether.begin(BUFFER_SIZE, mymac, 10)==0)
    Serial.println( "Failed to access Ethernet controller");
 else
   Serial.println("Ethernet controller initialized");
 
  if (!ether.staticSetup(myip))
    Serial.println("Failed to set IP address");
  Serial.println();
//Ethernet Debugging Ends Here

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



  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
}

const char http_Unauthorized[] PROGMEM =
    "HTTP/1.0 401 Unauthorized\r\n"
    "Content-Type: text/html\r\n\r\n"
    "<h1>401 Unauthorized</h1>";

void homepage(){
            myfile.open("test.txt", O_READ);
            char d;
            while ((d = myfile.read()) > 0) {
              bfill.emit_p((char)d);
          }
              myfile.close();
}

void loop() {
  //checking for requesting client
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  

  
  if(pos) {
    bfill = ether.tcpOffset();
    
    //storing buffer on data variable
    char *data = (char *) Ethernet::buffer + pos;
    
    if (strncmp("GET /", data, 5) != 0) {
            // Unsupported HTTP request
            // 304 or 501 response would be more appropriate
            bfill.emit_p(http_Unauthorized);
        }
    else {
        data += 5;
            
            if (data[0] == ' ') {
                // Return home page
                homepage();
            }
            else if (strncmp("?cmd=ON ", data, 8) == 0) {
                homepage();
                Serial.println("Recieve ON");
               digitalWrite(ledPin, HIGH);


            }
            else if (strncmp("?cmd=OFF ", data, 9) == 0) {
                homepage();
                Serial.println("Recieve OFF");
                digitalWrite(ledPin, LOW);
            }
            else if (strncmp("?cmd=HALF ", data, 10) == 0) {
                homepage(); 
                Serial.println("Recieve HALF");
                analogWrite(ledPin,150);
            }
            else {
                // Page not found
                bfill.emit_p(http_Unauthorized);
            }
        }
    ether.httpServerReply(bfill.position());
  }
}

so basically instead of void homepage loading the html on arduino..it tries to retrieve the html code on a test.txt file on my SD.
upon using this code an error shows.

_7_WebLedsss.ino: In function 'void homepage()':
_7_WebLedsss:109: error: invalid conversion from 'char' to 'const prog_char*'
_7_WebLedsss:109: error: initializing argument 1 of 'void BufferFiller::emit_p(const prog_char*, ...)'

what does this mean sir? maybe my approach is wrong? or is it possible that instead of retrieving it on a txt file I can retrieve it on a htm file?

You can see that the function wants a pointer to where the data is, not the data. Use &d, instead of d.