Ethernet Shield ENC26J80 + SD CARD

Hi Good Day guys! I need help with my project.

I need to control something using a webpage.
Here is a sample program for a web switch using EtherCard.h library.

#include <EtherCard.h>

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = {192,168,1,2};
byte Ethernet::buffer[700];

const int ledPin = 2;
boolean ledStatus;

char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;

void setup () {
 
  Serial.begin(600);
  Serial.println("WebLed Demo");
 
  if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
    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();
  
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  ledStatus = false;
}
  
void loop() {
 
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if(pos) {
    
    if(strstr((char *)Ethernet::buffer + pos, "GET /?status=ON") != 0) {
      Serial.println("Received ON command");
      ledStatus = true;
    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /?status=OFF") != 0) {
      Serial.println("Received OFF command");
      ledStatus = false;
    }
    
    if(ledStatus) {
      digitalWrite(ledPin, HIGH);
      statusLabel = on;
      buttonLabel = off;
    } else {
      digitalWrite(ledPin, LOW);
      statusLabel = off;
      buttonLabel = on;
    }
      
    BufferFiller bfill = ether.tcpOffset();
    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>LED Status: $S "
      "<a href=\"/?status=$S\"><input type=\"button\" value=\"$S\"></a>"
      "</body></html>"      
      ), statusLabel, buttonLabel, buttonLabel);
    ether.httpServerReply(bfill.position());
  }
}

I slightly understand the code. but I need to clear out some things so that I can full understand it. Here are my questions.

what does this mean?
strstr((char *)Ethernet::buffer + pos, "GET /?status=ON")

I tried printing

(char *)Ethernet::buffer + pos

and the serial monitor prints this

GET /?status=ON HTTP/1.1
Host: 192.168.1.2
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17
Referer: http://192.168.1.2/?status=OFF
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

So what is this for? Why is there a char* on it? What is strstr for? and why does it test if its !=0?

Also if Im not mistaken
bfill.emit_p(PSTR
prints the content of the webpage....what is PSTR for?

After I understand this completely, Instead of putting the html inside the bfill.emit_p, I want to put my html on an SD card and load it on it. Is this possible? If yes, how?
Also instead of putting hyperlinks on buttons I want to put it on images that are on my SD card. how is this possible?

THANKS and more power to the community!

what does this mean?
strstr((char *)Ethernet::buffer + pos, "GET /?status=ON")

Did you look up the strstr() function? It searches the first argument for the second one. Ethernet::buffer is a collection of characters, NULL terminated. pos is an offset from the beginning of the array.

Spend some time with google, looking for functions you do not understand. Learning how to find and interpret documentation is an essential skill.

Thx for the reply sir Paul.
I've been reading documentations but I am having a hard time understanding it alone since I'm learning C from scratch.

based on my understanding. Correct me if I'm wrong

if(strstr((char *)Ethernet::buffer + pos, "GET /?status=ON") != 0)

means that It will read Ethernet::buffer as a char and will null terminate until it read a number of byte "pos". then using strstr, it will check if the read one has "GET /?status=ON"....if it has it will return a value greater than 0 thus entering the if statement. If no it will retun a value 0 thus it will not enter the if statement?

Correct me if I'm wrong

You are, partially. Ethernet::buffer is an array of chars. That array is NULL terminated. Ethernet::buffer + pos is some offset into the array of chars (in other words, searching doesn't start at the start of the string).

So, strstr() is looking for "GET /?status=ON" in Ethernet::buffer, starting from pos. If it finds it, it returns a pointer to the found string. Otherwise it returns NULL (0).

Wow thx for the great explanation sir...its all clear to me now..
I'll post again later after I have made some adjustments to the html..
My next post will be probably about migrating the html code to SD.

Hi guys after some reading and modifying the code for my convenience
and here it is

#include <EtherCard.h>

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
#define BUFFER_SIZE 700
byte Ethernet::buffer[BUFFER_SIZE];
static byte myip[] = {192,168,1,2};

const int ledPin = 6;

void setup () {
 
  Serial.begin(9600);
  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();
  
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
}
  
void loop() {
 
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if(pos) {

    if(strstr((char *)Ethernet::buffer + pos, "GET /?cmd=ON") != 0) {
      Serial.println("Recieve ON");
      digitalWrite(ledPin, HIGH);
    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /?cmd=OFF") != 0) {
      Serial.println("Recieve OFF");
      digitalWrite(ledPin,LOW);
    }
    
     if(strstr((char *)Ethernet::buffer + pos, "GET /?cmd=HALF") != 0) {
       Serial.println("Recieve HALF");
      analogWrite(ledPin,150);
    }
     
     BufferFiller bfill = ether.tcpOffset();
    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>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>"
      "</body></html>"      
      ));
    
    ether.httpServerReply(bfill.position());
  }
}

basically what I want next is to store this html on the embedded sd card on my shield and also instead of using buttons as the link
I want to use images on the SD.
I found some tutorials on doing these like this one Arduino Forum
but its kinda hard to understand and the format is different since it uses a W1500 chip with Ethernet.h library.
What I'm using is a ENC26J80 shield with EtherCard.h library.
A little guide, sample codes would be a great help just to give me an idea on how to start migrating the sample from the
above link to something suitable for my code.

THx!