Webpage not re-writing correctly

Hi.

In the code below which works initially by using the writeWebPage function to write HTML to the webpage. When I select the Led On or Off buttons I also want that to update on the webpage. It uses the same function with just different characters but the ‘default’ stays.

Is this approach of re-writing the page the way to go or is there a better approach.

Also, I have noticed the ‘?’ character appearing as an argument immediately after the ip address (throughout the web). What is the significance of this?

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

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 40); // IP address, may need to change depending on network
EthernetServer server(80);  // create a server at port 80

String readString; 
int i = 0;

char one[10];
char two[10];
char three[10];
char combined[30] = {0};

void setup()
{
    pinMode(4, OUTPUT);
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients

      //enable serial data print 
  Serial.begin(9600); 
  Serial.println("servertest1"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204");
               client.println();
               client.println();  
             }
             else {

           writeWebPage("<H1> ","Default","<H1> ");
          

             }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            digitalWrite(4, HIGH);    // set pin 4 high
            Serial.println("Led On");
             writeWebPage("<H1> ","On","<H1> ");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println("Led Off");
             writeWebPage("<H1> ","Off","<H1> ");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
} 

void writeWebPage(char one[],char two[],char three[]){
          strcat(combined, one);
          strcat(combined, two);
          strcat(combined, three);

          EthernetClient client = server.available();
          
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>LED Control</H1>");
          
          client.println("<a href=\"/?on\" target=\"inlineframe\">ON</a>"); 
          client.println("<a href=\"/?off\" target=\"inlineframe\">OFF</a>"); 

          client.println("<IFRAME name=inlineframe style=\"display:none\" >");          
          client.println("</IFRAME>");

          client.println("<H1>Status</H1>");
          client.println(combined);

          client.println("</BODY>");
          client.println("</HTML>");

          Serial.println(combined);

          for( int i = 0; i < sizeof(combined);  ++i ){  // clear buffer
            combined[i] = (char)0;
          }
}

Thanks,

Mark.

Also, I have noticed the '?' character appearing as an argument immediately after the ip address (throughout the web). What is the significance of this?

It marks the start of the name=value pairs in the GET request.

It uses the same function with just different characters but the 'default' stays.

Why shouldn't it? You don't send new data, so what do you expect the browser to do?

Each time the Led buttons are pressed on the webpage the Led’s change but I also pass the following to the writeWebPage function

writeWebPage("

“,“On”,”

“); and writeWebPage(”

“,“Off”,”

");

This should update what’s written on the webpage but it never changes.

This is new data each time so it should change.

I havent played with the ethernet shield much..

but does it 'refresh' the page? (so you can see the updated content?)

Or does it (doubtful) do some sort of ajax updating on the page?

If you click the led button.. and refresh the page.. does it THEN show the updated value/state/status of said LED?

No. The physical Led turns on and off so the buttons work but the text never changes, even if I refresh the page.

When the newline character is sent, your code either sends a 204 header, or the default, then closes the connection. Any webpage send attempt after that will not be received by the client browser.

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging

          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204");
               client.println();
               client.println(); 
             }
             else {

           writeWebPage("<H1> ","Default","<H1> ");
         

             }

          delay(1);
          //stopping client
          client.stop(); // < this stops the webpage send and closes the connection to the client

Would it be best to create a new connection each time the buttons are pressed?

MarkG123: Would it be best to create a new connection each time the buttons are pressed?

Yes, but that is not your problem. Your problem is when the client sends the newline, your code only sends either a 204 header or "Default", then closes the connection. You must redo your code to evaluate the request string and send the correct page before sending the client.stop().

Ok looks like I have a bit of reading up to do on header pages etc. Any good recommendations?

It seems like you have the basics of the protocol, but just have the response wrong.

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging

          //now output HTML data header
          // don't know what this "if" is supposed to do. You may not need this.
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204");
               client.println();
               client.println();
             }
             else if(eadString.indexOf("on") >0)//checks for on
             {
                digitalWrite(4, HIGH);    // set pin 4 high
                Serial.println("Led On");
                 writeWebPage("<H1> ","On","<H1> ");
            }
            else if(readString.indexOf("off") >0)//checks for off
            {
              digitalWrite(4, LOW);    // set pin 4 low
              Serial.println("Led Off");
               writeWebPage("<H1> ","Off","<H1> ");
            }
            else { // if none of the above, send the default
                writeWebPage("<H1> ","Default","<H1> ");
            }

          readString=""
          // then close the connection here
          client.stop(); // < this stops the webpage send and closes the connection to the client

If I post directly into the address bar e.g http://192.168.0.40/?on or http://192.168.0.40/?off it seems to work ok. I think this is what I need the buttons to be able to do.

Is it possible for the buttons to put the full command, IP address plus the argument into the address bar?

I found https://www.ntu.edu.sg/home/ehchua/programming/webprogramming/HTTP_Basics.html very helpful in understand the WebServer sketch for Ethernet.

Then put a form in the html doc with a GET method. The on and off parameters should be like a radio buttons or whatever you want.

Thanks guys. Will have a look at this later in the week.

I got it working by using the “onClick=parent.location” button parameter which adds the command to the URL. The code is below for anybody who wants it. I made the buttons big so can be controlled from a mobile device. Works a treat.

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

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 40); // IP address, may need to change depending on network
EthernetServer server(80);  // create a server at port 80

String readString; 
char cmd[10];


void setup()
{
    pinMode(4, OUTPUT);
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients

    //enable serial data print 
    Serial.begin(9600); 
 
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

        if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204");
               client.println();
               client.println();
             }

          ///////////////////// control arduino pin
          if(readString.indexOf("On") >0)//checks for on
          {
            digitalWrite(4, HIGH);    // set pin 4 high
            Serial.println("Led On");
            writeWebPage("On");
          }
          else if(readString.indexOf("Off") >0)//checks for off
          {
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println("Led Off");
            writeWebPage("Off");
          }
          else
          {
            writeWebPage("Not set");
            Serial.println("Nothing");
          }
       
          //clearing string for next read
          readString="";

          delay(1);
          //stopping client
          client.stop();

        }
      }
    }
  }
} 

void writeWebPage(char cmd[]){
          

          EthernetClient client = server.available();
          
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>LED Control</H1>");
          
          
          client.println("</FORM>");
          client.println("<INPUT TYPE=button button style=font-size:40px;width:200;height:100 onClick=parent.location='On'  value=LED&nbsp;ON>");  // &nbsp = space
          client.println("<INPUT TYPE=button button style=font-size:40px;width:200;height:100 hspace=100 onClick=parent.location='Off' value=LED&nbsp;OFF>");
          client.println("</FORM>");
          

          client.println("<IFRAME name=inlineframe style=\"display:none\" >");          
          client.println("</IFRAME>");
          
        //  client.println("<font size=3 color=red>");
          client.println("<H1>Status:");

          if(cmd == "On")
            client.println("<font color=green>");
          else if(cmd == "Off")
            client.println("<font color=red>");
          else
            client.println("<font color=blue>");
            
          client.println(cmd);
          client.println("<H1>");

          client.println("</BODY>");
          client.println("</HTML>");        
}