W5100 Web Server - Pages being truncated

Hi,

I have a project with a web server running on an ATMEGA 2560 on Arduino 1.0.4. I have it serving a small webpage successfully except that sometimes it cuts off some of the page. This is particularly noticeable if I'm not accessing it from the local network.

Any ideas about how to diagnose?

You should post the code you are using. That may help.

void Webpage_handler() 
{
 
  
    index=0;  //reset the clientline index
    EthernetClient client = server.available();
    if (client) 
    {
      boolean currentLineIsBlank = true;
      while (client.connected()) 
      {
        if (client.available()) 
        {
          char c = client.read();
          Serial.print(c);

          if(index<BUFSIZ)  //Only add data if the buffer isn't full.
          {
            clientline[index]=c;
            index++;
          }      

          if (c == '\n' && currentLineIsBlank)
          {


#define POSTBUFSIZ 200  //Buffer size for getting data
            char POSTline[POSTBUFSIZ];  //string that will contain command data
            int POSTindex = 0;  //clientline index

            Serial.print("POST Values:");
            while(client.available())
            {
              char   a = client.read();
              // save the variables somewhere
              //     POST += c;
              Serial.print(a);
              if(POSTindex<POSTBUFSIZ)  //Only add data if the buffer isn't full.
              {
                POSTline[POSTindex]=a;
                POSTindex++;
              }

            }
            Serial.println();
            Serial.println("End of Post Values Section");          
            //          Serial.print("POST Values:");
            //          Serial.println(POST);
            Serial.println();
            Serial.println(POSTindex);          
            Serial.println(POSTline);


            Serial.println("Buffer reprint");
            int lap = 0;
            while (lap < POSTindex           )
            {
              Serial.print(POSTline[lap]);
              lap++; 
            }
            Serial.println();  
    

if(strstr(POSTline,"F_SP_HW=")!=0) 
   {
     Serial.println("Found HW Setpoint");
String formresult =String(POSTline).substring(8,10);
//Serial.print(formresult);
int Setpoint_HW = formresult.toInt();
Serial.print("Extracted values");
Serial.println(Setpoint_HW);
if (Setpoint_HW > SP_T_HW_Max) SP_T_HW = SP_T_HW_Max;
else if (Setpoint_HW < SP_T_HW_Min) SP_T_HW = SP_T_HW_Min;
else SP_T_HW = Setpoint_HW;
   }
else if(strstr(POSTline,"F_SP_BR=")!=0) 
   {
     Serial.println("Found Beds Setpoint");
String formresult =String(POSTline).substring(8,10);
//Serial.print(formresult);
int Setpoint_Beds = formresult.toInt();
Serial.print("Extracted values");
Serial.println(Setpoint_Beds);
if (Setpoint_Beds > SP_T_Rooms_Max) SP_T_Bedrooms = SP_T_Rooms_Max;
else if (Setpoint_Beds < SP_T_Rooms_Min) SP_T_Bedrooms = SP_T_Rooms_Min;
else SP_T_Bedrooms = Setpoint_Beds;
   }
else if(strstr(POSTline,"F_SP_KI=")!=0) 
   {
     Serial.println("Found Kitchens Setpoint");
String formresult =String(POSTline).substring(8,10);
//Serial.print(formresult);
int Setpoint_Beds = formresult.toInt();
Serial.print("Extracted values");
Serial.println(Setpoint_Beds);
if (Setpoint_Beds > SP_T_Rooms_Max) SP_T_Kitchen = SP_T_Rooms_Max;
else if (Setpoint_Beds < SP_T_Rooms_Min) SP_T_Kitchen = SP_T_Rooms_Min;
else SP_T_Kitchen = Setpoint_Beds;
   }
else if(strstr(POSTline,"F_SP_UP=")!=0) 
   {
     Serial.println("Found Upstairs Setpoint");
String formresult =String(POSTline).substring(8,10);
//Serial.print(formresult);
int Setpoint_Beds = formresult.toInt();
Serial.print("Extracted values");
Serial.println(Setpoint_Beds);
if (Setpoint_Beds > SP_T_Rooms_Max) SP_T_Upstairs = SP_T_Rooms_Max;
else if (Setpoint_Beds < SP_T_Rooms_Min) SP_T_Upstairs = SP_T_Rooms_Min;
else SP_T_Upstairs = Setpoint_Beds;
   }   
   


            //  Webpage_print();


            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<head><title>Controller 1</title>");
              
            client.println("</head>");
            client.println("<meta http-equiv=refresh content=180 > <body><h1><center>Home Heating Controller</h1></center>
<center>");
            
//                client.println("<hr>");
           
               // client.println("<hr>");
                     client.println("<hr><center><p><b>Room Temperatures</b></p></center>");
            client.println("<table align=""center"" border=""1"" cellpadding=""1"" cellspacing=""1"" style=""width: 500px;"">");
//                client.println("<table align=""center"" border=""1"" cellpadding=""1"" cellspacing=""1"" style=""width: 500px;"">");
            client.println("<thead><tr> <th scope=""col"">Area</th><th scope=""col"">Temperature</th><th scope=""col"">Setpoint</th></tr></thead>");
            client.println("<tbody>");
            
     client.println("<tr><td><p>Kitchen</p></td><td>");   client.print(Temp_Kitchen);
            client.println("</td><td>");
             client.print("<form method=post action=>");  client.print("<input type=text name=F_SP_KI  value=");   client.print(SP_T_Kitchen); client.print("> ");
          client.print("<input type=submit value=Update></form>");
 client.print("</td></tr>");

     client.println("<tr><td><p>Bedrooms</p></td><td>");   client.print(Temp_Bedrooms);
            client.println("</td><td>");
             client.print("<form method=post action=>");  client.print("<input type=text name=F_SP_BR  value=");   client.print(SP_T_Bedrooms); client.print("> ");
          client.print("<input type=submit value=Update></form>");
 client.print("</td></tr>");

     client.println("<tr><td><p>Upstairs</p></td><td>");   client.print(Temp_Upstairs);
            client.println("</td><td>"); client.print("<form method=post action=>");
        client.print("<input type=text name=F_SP_UP  value=");   client.print(SP_T_Upstairs); client.print("> ");
      client.print("<input type=submit value=Update></form>");  client.print("</td></tr>");



     client.println("<tr><td><p>Hot Water</p></td><td>");   client.print(Temp_HW);
            client.println("</td><td>");  //  client.print(SP_T_HW); 
             client.print("<form method=post action=>");
        client.print("<input type=text name=F_SP_HW  value=");   client.print(SP_T_HW); client.print("> ");
      client.print("<input type=submit value=Update></form>");
 client.print("</td></tr>");

           client.println("<tr><td><p>Fire</p></td><td>");   client.print(Temp_Fire);
            client.println("</td><td><p>");    client.print("N/A");  client.print("</p></td></tr>");

           client.println("<tr><td><p>Outside</p></td><td>");   client.print(Temp_Outside);
            client.println("</td><td><p>"); client.print(Humidity_Outside);    client.print("% rH");  client.print("</p></td></tr>");

            client.println("</tbody>");
            
            client.println("</table>");
            
          client.println("<hr>");
             client.println("<center><p><b>Equipment Status</b></p></center>");
     // client.println("<hr>
");
                 client.println("<table align=""center"" border=""1"" cellpadding=""1"" cellspacing=""1"" style=""width: 500px;"">");
            client.println("<thead><tr> <th scope=""col"">Equipment</th><th scope=""col"">Status</th></tr></thead>");
            client.println("<tbody>");
         
            client.println("<tr><td><p>Fire Pump</p></td><td>");  
           if (digitalRead(Pin_Fire_Pump) == 1) { client.print("ON");  }          else  { client.print("OFF");  }
          client.println("</td></tr>");

            client.println("<tr><td><p>Cooker</p></td><td>");  
           if (Cooker_On == 1) { client.print("ON");  }          else  { client.print("OFF");  }
          client.println("</td></tr>");

         
           client.println("<tr><td><p>Kitchen Valve</p></td><td>");  
           if (digitalRead(Pin_Valve_Kitchen) == 1) { client.print("ON");  }      else  { client.print("OFF");  }
         client.println("</td></tr>");
         
            client.println("<tr><td><p>Upstairs Valve</p></td><td>");  
           if (digitalRead(Pin_Valve_Upstairs) == 1) { client.print("ON");  }     else  { client.print("OFF");  }
          client.println("</td></tr>");
         
           client.println("<tr><td><p>Bedrooms Valve</p></td><td>");  
           if (digitalRead(Pin_Valve_Bedrooms) == 1) { client.print("ON");  }     else  { client.print("OFF");  }
         client.println("</td></tr>");
             
           client.println("</tbody></table>");
            
     
            client.print("");
    
            break;
          }
          if (c == '\n') {
            currentLineIsBlank = true;
          } 
          else if (c != '\r') {
            currentLineIsBlank = false;
          }
     
        }



      }

      delay(100);  //Give the web browser time to receive the data
      Serial.println("End of loop");
      Serial.println(clientline);
      client.stop();
    } 
  }

The String data type has been known to cause some weird fails. I use character arrays instead. The Arduino crew has been working on the String problem, but I have not seen any examples of it working well yet.

Here is my code in the playground. Maybe it will give you some ideas.
http://playground.arduino.cc/Code/WebServerST

Thank you for your reply. I will look at rewriting it like you have:

Two questions:

  1. What is the \n below and the \r?
  2. What is the F in client.write(F("</head")); ?

else if (c == ‘\n’) {
currentLineIsBlank = true;
currentLineIsGet = false;
}
else if (c != ‘\r’) {
currentLineIsBlank = false;
}

When I try:

          client.write(F("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<html>"));

I get:
Webpage.ino: In function ‘void Webpage_handler()’:
Webpage:123: error: invalid conversion from ‘const __FlashStringHelper*’ to ‘uint8_t’
Webpage:123: error: initializing argument 1 of ‘virtual size_t EthernetClient::write(uint8_t)’

Any ideas? I had a look on Google and didn’t find much.

omegab:
When I try:

          client.write(F("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<html>"));

I get:
Webpage.ino: In function ‘void Webpage_handler()’:
Webpage:123: error: invalid conversion from ‘const __FlashStringHelper*’ to ‘uint8_t’
Webpage:123: error: initializing argument 1 of ‘virtual size_t EthernetClient::write(uint8_t)’

Any ideas? I had a look on Google and didn’t find much.

Turns out it doesn’t like the client.write?

Apparently it doesn't like client.write() from the playground code. My version here with client.write() doesn't throw that error. ?? I changed the playground code to client.print(). Thanks for the head's up on that error.

Change client.write() to client.print() and it will work.
The \r and \n are the carriage return and line feed.

edit: The F() function keeps those string constants on program memory instead of copying them to SRAM. I just found that is what is causing the client.write() function to fail. It does ok if you do not use the F() function.

client.print(F("This is ok"));
client.write("This is ok");
client.write(F("This will fail"));

Woah.... using the F() function in one place caused the entire download to fail... I didn't realise it immediately as I had made several changes and I thought the bootloader had gotten corrupted!

omegab:
Woah.... using the F() function in one place caused the entire download to fail... I didn't realise it immediately as I had made several changes and I thought the bootloader had gotten corrupted!

Are you saying you can't use the F() function at all? The F() function only fails on mine during the compile attempt if I use client.write(). I am checking this with a Mega 2560 and IDE v1.0.4.

It seems that on the same configuration as you have that using the F() function caused the Upload not to complete. I removed it in the two places I had it and the board came back to life.

When connected from the internet to my arduino, I note that it tries to get the data several times whereas when it connects from the local LAN (on the same smartphone), it is able to get all the data in a single pass. Is there a timeout???

omegab:
When connected from the internet to my arduino, I note that it tries to get the data several times whereas when it connects from the local LAN (on the same smartphone), it is able to get all the data in a single pass. Is there a timeout???

That would depend on the internet traffic and maybe bandwidth throttling.

The only time I see my Mega fail an upload if the compile was ok is if I used "!!!" somewhere. That will abort the upload with some models of the Mega. It puts the bootloader into a diagnostics mode or something like that.