[SUCCESS] IDE WebServer example - why so much garbage?

Ok, I've been wrestling with trying to get ethernet stuff to work - local network only ... Arduino --> Ethernet shield --> router --> local PC. I used the IDE WebServer sketch, with tiny modifications to eliminate auto-refreshing, plus indicate to the SerialMonitor when the analog readings are sent,

/*
  Web Server
 
 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe */

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(57600);
//   while (!Serial.available() ) {
//    ; // wait for serial port to connect. Needed for Leonardo only
//  }

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
//	  client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          
      // NEW (08/17/13) 
      Serial.println("-analog display");

          //output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("
");       
          }
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

I had noticed in my other programs the enormous amount of junk sent over the link when a page update is requested, see below.

My question is - from the monitor dump it looks like the ... if (c == '\n' && currentLineIsBlank) { ... part of the loop is executed "4" times whenever a page update is performed. IE, notice that "-analog display" prints out multiple times for each refresh request. There are 2 refreshes shown below, demarcated with the "****************' line.

What is going on here? Why so much garbage? Why repeat 4 times?

new client
GET / HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
User-Agent: Mozilla/5.0 (Linux; Android 4.2.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31
DNT: 1
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

-analog display
client disonnected
new client
GET /favicon.ico HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Accept: /
DNT: 1
User-Agent: Mozilla/5.0 (Linux; Android 4.2.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31
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

-analog display
client disonnected
new client
GET /apple-touch-icon-precomposed.png HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Accept: /
DNT: 1
User-Agent: Mozilla/5.0 (Linux; Android 4.2.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31
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

-analog display
client disonnected
new client
GET /apple-touch-icon.png HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Accept: /
DNT: 1
User-Agent: Mozilla/5.0 (Linux; Android 4.2.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31
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

-analog display
client disonnected


new client
GET / HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
User-Agent: Mozilla/5.0 (Linux; Android 4.2.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31
DNT: 1
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

-analog display
client disonnected
new client
GET /favicon.ico HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Accept: /
DNT: 1
User-Agent: Mozilla/5.0 (Linux; Android 4.2.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31
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

-analog display
client disonnected
new client
GET /apple-touch-icon-precomposed.png HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Accept: /
DNT: 1
User-Agent: Mozilla/5.0 (Linux; Android 4.2.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31
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

-analog display
client disonnected
new client
GET /apple-touch-icon.png HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Accept: /
DNT: 1
User-Agent: Mozilla/5.0 (Linux; Android 4.2.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31
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

-analog display
client disonnected

You might have issues with the looping used in the example code. I made the below removing the looping setup to allow a little more flexibility for reading/displaying the analog inputs.

// zoomkat's meta refresh data frame test page 5/25/13
// use http://192.168.1.102:84 in your brouser for main page
// http://192.168.1.102:84/data static data page
// http://192.168.1.102:84/datastart meta refresh data page
// for use with W5100 based ethernet shields
// set the refresh rate to 0 for fastest update
// use STOP for single data updates

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

const int analogInPin0 = A0;
const int analogInPin1 = A1;
const int analogInPin2 = A2;
const int analogInPin3 = A3;
const int analogInPin4 = A4;
const int analogInPin5 = A5;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // arduino ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
unsigned long int x=0; //set refresh counter to 0
String readString; 

//////////////////////

void setup(){
  Serial.begin(9600);
    // disable SD SPI if memory card in the uSD slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();
  Serial.println("meta refresh data frame test 5/25/13"); // so I can keep track of what is loaded
}

void loop(){
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
         if (readString.length() < 100) {
          readString += c; 
         } 
        //check if HTTP request has ended
        if (c == '\n') {

          //check get atring received
          Serial.println(readString);

          //output HTML data header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          //generate data page
          if(readString.indexOf("data") >0) {  //checks for "data" page
            x=x+1; //page upload counter
            client.print("<HTML><HEAD>");
            //meta-refresh page every 1 seconds if "datastart" page
            if(readString.indexOf("datastart") >0) client.print("<meta http-equiv='refresh' content='1'>"); 
            //meta-refresh 0 for fast data
            if(readString.indexOf("datafast") >0) client.print("<meta http-equiv='refresh' content='0'>"); 
            client.print("<title>Zoomkat's meta-refresh test</title></head><BODY>
");
            client.print("page refresh number: ");
            client.print(x); //current refresh count
            client.print("

");
            
              //output the value of each analog input pin
            client.print("analog input0 is: ");
            client.print(analogRead(analogInPin0));
            
            client.print("
analog input1 is: ");
            client.print(analogRead(analogInPin1));
                        
            client.print("
analog input2 is: ");
            client.print(analogRead(analogInPin2));
            
            client.print("
analog input3 is: ");
            client.print(analogRead(analogInPin3));
                                    
            client.print("
analog input4 is: ");
            client.print(analogRead(analogInPin4));
            
            client.print("
analog input5 is: ");
            client.print(analogRead(analogInPin5));
            client.println("
</BODY></HTML>");
           }
          //generate main page with iframe
          else
          {
            client.print("<HTML><HEAD><TITLE>Zoomkat's frame refresh test</TITLE></HEAD>");
            client.print("Zoomkat's Arduino frame meta refresh test 5/25/13");
            client.print("

Arduino analog input data frame:
");
            client.print("&nbsp;&nbsp;<a href='/datastart' target='DataBox' title=''yy''>META-REFRESH</a>");
            client.print("&nbsp;&nbsp;&nbsp;&nbsp;<a href='/data' target='DataBox' title=''xx''>SINGLE-STOP</a>");
            client.print("&nbsp;&nbsp;&nbsp;&nbsp;<a href='/datafast' target='DataBox' title=''zz''>FAST-DATA</a>
");
            client.print("<iframe src='/data' width='350' height='250' name='DataBox'>");
            client.print("</iframe>
</HTML>");
          }
          delay(1);
          //stopping client
          client.stop();
          //clearing string for next read
          readString="";
        }
      }
    }
  }
}

Thanks, your code wouldn't display anything on my machine. I did have to use Ethernet.begin(mac, ip); to get past setup(), but otherwise seeing nothing on the browser. Got to run out now, look at it later, :-).

This is the request for the page.

GET / HTTP/1.1

This is the browser request for the site icon

GET /favicon.ico HTTP/1.1

Is this an apple device? Requesting an apple icon.

GET /apple-touch-icon-precomposed.png HTTP/1.1

Another apple icon.

GET /apple-touch-icon.png HTTP/1.1

Only the first did you do. The rest of these were the web browser getting icons.

Tim, turns out the 4X repeat business is when using Chrome on my Android tablet. When using Chrome on my PC, I only get a 2X repeat, and with IE8 on my PC, it's down to a 1X display [ie, no repeat]. So some of the extraneous garbage is browser-related.

Again, this was for the WebServer sketch that is packaged in the Ethernet library of the Arduino IDE. Not super-efficient it would seem [see next post, however].

Zoomkat gets A-PLUSES!!

I've been looking at different Arduino web-server sketches to modify for use on the base station of my home-automation system - local router only, no outside activity.

Basically, I want ability to display data and turn things on/off using buttons, plus ultimately, I'd like feedback on the page showing the results of the actions (eg, a button changes color to indicate an Led turned on, etc) - currently none of the sketches I've looked at do this.

Some sketches, as previously illustrated, transmit a LOT of data across the ethernet link when HTML pages are requested from the server. However, Zoomkat's sketches take the prize for doing a lot of work, but with tiny traffic across the ethernet link. The following sketch was mined from this page, reply #11,
http://forum.arduino.cc/index.php?topic=163908.0

I made a few changes as indicated, largely to display all link traffic. I also converted control codes so they could be seen, eg .13. ==> '\r'.

/*
file: zoomkat_server2
revised: 08/17/13.

status: works great, very little garbage transferred
  over the link with HTML page requests.
-----------------------------------------------

NOTES:
1. removals indicated by //.//
2. some new things added, as marked.
3. original radio buttons work poorly, 
   stay forever "on" after clicked.

ref: http://forum.arduino.cc/index.php?topic=163908.0
*******************************************************/

//zoomkat 7-03-12, combined client and server
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor and send an g to test client and
//see what the arduino client/server receives
//web page buttons make pin 5 high/low
//use the ' in html instead of " to prevent having to escape the "
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605


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

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //assign arduino mac address
//.//byte ip[] = {192, 168, 1, 102 }; // ip in lan assigned to arduino
byte ip[] = { 192, 168, 1, 177 };  // ip in lan assigned to arduino
//.//byte gateway[] = {192, 168, 1, 1 }; // internet access via router
//.//byte subnet[] = {255, 255, 255, 0 }; //subnet mask

//.//EthernetServer server(84); //server port arduino server will use
EthernetServer server(80); //server port arduino server will use
EthernetClient client;

char serverName[] = "web.comporium.net"; // (DNS) zoomkat's test web page server
//byte serverName[] = { 208, 104, 2, 86 }; // (IP) zoomkat web page server IP address

String readString; //used by server to capture GET request 

//////////////////////

// (08/17/13) Led pins - retained original numbering 
//   to minimize program changes.
#define p5    2   // D2
#define p6    3   // D3
#define p7   25   // D25 - using with ATmega1284.
#define p8   26   // D26

void setup()
{
  pinMode(p5, OUTPUT); //pin selected to control
  pinMode(p6, OUTPUT); //pin selected to control
  pinMode(p7, OUTPUT); //pin selected to control
  pinMode(p8, OUTPUT); //pin selected to control
  //pinMode(5, OUTPUT); //pin 5 selected to control
  
  //./Ethernet.begin(mac,ip,gateway,gateway,subnet); 
  Ethernet.begin(mac,ip); 
  server.begin();
  
  Serial.begin(57600); 
  Serial.println("server/client 1.0 test 7/03/12"); // keep track of what is loaded
  Serial.println("Send an g in serial monitor to test client"); // what to do to test client
}

void loop()
{
  // check for serial input
  if (Serial.available() > 0) {
    byte inChar;
    inChar = Serial.read();
    if(inChar == 'g') {
      sendGET(); // call client sendGET function
    }
  }  

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

   // ADDED (08/17/13) - display received chars.
   if( c >= ' ') Serial.print(c);  
   else {    // print control codes as #s.
     Serial.print(" ."); Serial.print( (int)c );  Serial.print("."); 
   }
           
        //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') {

   // ADDED (08/17/13) - indicate when a page is sent.
   Serial.println("\n...Sending HTML page...");
          
          ///////////////
          //.//Serial.print(readString); //print to serial monitor for debuging 

            //now output HTML data header
          if(readString.indexOf('?') >=0) { //don't send new page
            client.println(F("HTTP/1.1 204 Zoomkat"));
            client.println();
            client.println();  
          }
          else {   
            client.println(F("HTTP/1.1 200 OK")); //send new page on browser request
            client.println(F("Content-Type: text/html"));
            client.println();

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

            client.println(F("<H2>Zoomkat's simple Arduino 1.0 button</H2>"));

            // DIY buttons
            client.println(F("Pin5"));
            client.println(F("<a href=/?on2 target=inlineframe>ON</a>")); 
            client.println(F("<a href=/?off3 target=inlineframe>OFF</a>

")); 

            client.println(F("Pin6"));
            client.println(F("<a href=/?on4 target=inlineframe>ON</a>")); 
            client.println(F("<a href=/?off5 target=inlineframe>OFF</a>

")); 

            client.println(F("Pin7"));
            client.println(F("<a href=/?on6 target=inlineframe>ON</a>")); 
            client.println(F("<a href=/?off7 target=inlineframe>OFF</a>

")); 

            client.println(F("Pin8"));
            client.println(F("<a href=/?on8 target=inlineframe>ON</a>")); 
            client.println(F("<a href=/?off9 target=inlineframe>OFF</a>

"));  

            client.println(F("Pins"));
            client.println(F("&nbsp;<a href=/?off2468 target=inlineframe>ALL ON</a>")); 
            client.println(F("&nbsp;<a href=/?off3579 target=inlineframe>ALL OFF</a>

")); 
                  
          // mousedown buttons
          client.println(F("<input type=button value=ON onmousedown=location.href='/?on4;' target=inlineframe>")); 
          client.println(F("<input type=button value=OFF onmousedown=location.href='/?off5;' target=inlineframe>"));        
          client.println(F("&nbsp;<input type=button value='ALL OFF' onmousedown=location.href='/?off3579;' target=inlineframe>

"));        
                   
          // mousedown radio buttons
          client.println(F("<input type=radio onmousedown=location.href='/?on6;' target=inlineframe>ON</>")); 
          client.println(F("<input type=radio onmousedown=location.href='/?off7; target=inlineframe'>OFF</>")); 
          client.println(F("&nbsp;<input type=radio onmousedown=location.href='/?off3579;' target=inlineframe>ALL OFF</>

"));    
          
          // custom buttons
          client.print(F("<input type=submit value=ON target=inlineframe style=width:100px;height:45px onClick=location.href='/?on8;'>"));
          client.print(F("<input type=submit value=OFF target=inlineframe style=width:100px;height:45px onClick=location.href='/?off9;' target=inlineframe>"));
          client.print(F("&nbsp;<input type=submit value='ALL OFF' target=inlineframe style=width:100px;height:45px onClick=location.href='/?off3579;' target=inlineframe>"));
          
            client.println(F("<IFRAME name=inlineframe style='display:none'>"));          
            client.println(F("</IFRAME>"));
  
            client.println(F("</BODY>"));
            client.println(F("</HTML>"));
          }

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

Here is the rest of the sketch, which wouldn't fit in the previous post.

          ///////////////////// control arduino pin
          if(readString.indexOf('2') >0)//checks for 2
          {
            digitalWrite(p5, HIGH);    // set pin 5 high
            Serial.println("Led 5 On");
            Serial.println();
          }
          if(readString.indexOf('3') >0)//checks for 3
          {
            digitalWrite(p5, LOW);    // set pin 5 low
            Serial.println("Led 5 Off");
            Serial.println();
          }
          if(readString.indexOf('4') >0)//checks for 4
          {
            digitalWrite(p6, HIGH);    // set pin 6 high
            Serial.println("Led 6 On");
            Serial.println();
          }
          if(readString.indexOf('5') >0)//checks for 5
          {
            digitalWrite(p6, LOW);    // set pin 6 low
            Serial.println("Led 6 Off");
            Serial.println();
          }
          if(readString.indexOf('6') >0)//checks for 6
          {
            digitalWrite(p7, HIGH);    // set pin 7 high
            Serial.println("Led 7 On");
            Serial.println();
          }
          if(readString.indexOf('7') >0)//checks for 7
          {
            digitalWrite(p7, LOW);    // set pin 7 low
            Serial.println("Led 7 Off");
            Serial.println();
          }     
          if(readString.indexOf('8') >0)//checks for 8
          {
            digitalWrite(p8, HIGH);    // set pin 8 high
            Serial.println("Led 8 On");
            Serial.println();
          }
          if(readString.indexOf('9') >0)//checks for 9
          {
            digitalWrite(p8, LOW);    // set pin 8 low
            Serial.println("Led 8 Off");
            Serial.println();
          }         

          //clearing string for next read
          readString="";

        }
      }
    }
  }
} 

//////////////////////////
void sendGET() //client function to send and receive GET data from external server.
{
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    client.println("GET /~shb/arduino.txt HTTP/1.0");
    client.println();
  } 
  else {
    Serial.println("connection failed");
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read();
    Serial.print(c);
  }

  Serial.println();
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  client.stop();
}

Here are comm link results from running the sketch, viewed using Chrome on my PC. There is the original screen write, plus 3 refreshes due to 3 button presses. Very little traffic. All of that extraneous garbage from the IDE WebServer example is gone. Again, I'm displaying control codes here for debug purposes (.13. and .10.).

Kudos to zoomkat for discovering efficiency!

server/client 1.0 test 7/03/12
Send an g in serial monitor to test client
GET / HTTP/1.1 .13. .10.
...Sending HTML page...
GET /?on4; HTTP/1.1 .13. .10.
...Sending HTML page...
Led 6 On

GET /?off5; HTTP/1.1 .13. .10.
...Sending HTML page...
Led 6 Off

GET /?off2468 HTTP/1.1 .13. .10.
...Sending HTML page...
Led 5 On

Led 6 On

Led 7 On

Led 8 On

zoomkat_page.jpg

Basically, I want ability to display data and turn things on/off using buttons, plus ultimately, I'd like feedback on the page showing the results of the actions (eg, a button changes color to indicate an Led turned on, etc) - currently none of the sketches I've looked at do this.

A thing to consider with web page controls is that anyone else with control can change the component status at any time, and the status displayed on your page won't be current. There are browser scripting methods that have the browser constantly request a status much like a meta refresh. For testing, I'd just set an on or off status variable with each component, then just use another frame to request and display the current status variable.

Thanks, I'll look into that. When I ran out yesterday, it was to BarnesNoble to find a good book on modern HTML techniques, so I could learn a few things I've never used - like all the options for form-buttons. I had already spent [a lot of] time researching this stuff on the web, but I found it was too inefficient, due to too much crap to sort through. It's still much quicker to read through a well-written book with good organization.

I already had noticed the meta refresh request business. I had also played with creating a server page similar to that attached, but hadn't quite gotten the update refresh business proper. This is all for in-house use. I want to be able to access my home automation system controls using my Android tablet while sitting in the chair.

The below site has some good info.

Thanks, I've seen that site before, and tried some of the example server code. It works, but is similar to the IDE WebServer sketch, in that it transmits those large "garbage" blocks of data, plus has 2X or 4X repeats. Your web server code is still the hands-down winner for terse traffic.

I'll play around with it and my button ideas some more. I also tried the meta auto refresh business, and it works, but it seems I have to do an initial "manual" HTML page refresh to get it started.

This is all cool though. I integrated your server code into my AMI system - now with scheduled Xively postings, Tweets, RFM12 transmissions to remote nodes, and all controlled by the menuing system running on the ColorLCD - and it all seems to run fine together, :-). A mere 47KB of code and 6KB of SRAM usage on the ATmega1284.

The web pages obviously won't update during the other operations, eg Xively takes 6-8 sec currently, with data readback, so it would be nice to know when the server is blocked. Eg, it doesn't like receiving an HTML page request when it's doing a data read from Xively.

I also tried the meta auto refresh business, and it works, but it seems I have to do an initial "manual" HTML page refresh to get it started.

When the main page is downloaded, the frame is populated with the "data" page, which does not include a meta refresh line in it. This could be changed to the "datastart" for the 1 sec refresh, or the "datafast" for the fast refresh page.

That makes sense, thanks. I definitely cannot do a fast refresh, or even an automatic refresh, I think. I discovered if I try a server page request while the 1284/ethernet board is accessing data from xively, it hoses. I guess there are 2 simultaneous datastreams into the router, and the extraneous data from the page request mucks up the xively receiver code. [I should check the source code there].

I guess the best scheme would be to send a signal to the browser during a xively posting that locks it out from being able to make requests until it gets another go-ahead signal after the xively post is all finished. If that's even possible, LOL. All fun'n'games.

Ah, sweet success. z-k, I took your server logic scheme and modified it a bit, and now have it working the way I wanted. I am using buttons which change label names depending upon the state [1st three in the figure], and which are embedded in TABLE cells with display colors for Red=on and Green=off. The 4th button is used to trigger a command, beep the piezo, etc.

By changing your logic a bit, I am able to process the browser requests, and "then" update the HTML page. Simple enough. It always shows the current data, via button-color, and doesn't need auto-refreshing. You will also note the Digital pin display updates to the current data too, ie Leds 1,2,3 are on pins D25,D26,D27.

Best of all, your wonderful scheme wipes out all the extraneous garbage that the original IDE WebServer sketch was sending. The Android tablet browser still does 4X posts for each request op, but I see that 3 of them are simple refreshes. Chrome and IE8 on my PC only do a single post.

So, more kudos for Zoomkat! This is great.

Code follows, so you can see the logic changes. I am displaying control codes as .13. etc.

/***********************************************/
void loop()
{  
  server_testAMI();
  //server_testZK();
  //server_testIDE();
}
    
/* new AMI logic scheme.
***********************************************/
void server_testAMI()
{
  client = server.available();
  if( client ) {
    while( client.connected() ) {
      if( client.available() ) {
        char c = client.read();
        display_c( c ); 
 
        //read char by char HTTP request
        if( srvbuffer.length() < 100) srvbuffer += c; 
        
        // send new page, if HTTP request has ended
        if (c == '\n') {
          // if a command is received, process it,
          //   then send the HTML page.
          if( srvbuffer.indexOf('?') >=0) {  
            process_page_requests();    
            Serial.println("\n...Sending HTML page...");        
            send_HTMLpage();
          }
          // send page in response to browser "Refresh",
          //   without any requests attached.
          else {  
            Serial.println("\n...Refresh Only...");
            send_HTMLpage();
          }
          delay(1);
          client.stop();
          Serial.println("-server(client) disconnected\n");  
          srvbuffer="";  // clear string for next read.
        }
      } /* end of if( client.available() ) */ 
    } /* end of while( client.connect() ) */
  } /* end of if( client ) */
}

/* this is Zoomkat's original logic sequencing.
  "HTTP/1.1 204 Zoomkat" indicates 'server has fulfilled 
  the request but does not need to return an entity-body'.
***********************************************************/
void server_testZK()
{
  client = server.available();
  if( client ) {
    while( client.connected() ) {
      if( client.available() ) {
        char c = client.read();
        display_c( c ); 
 
        //read char by char HTTP request
        if( srvbuffer.length() < 100) srvbuffer += c; 

        // send new page, if HTTP request has ended
        if (c == '\n') {
          // if any page_request is received,
          //   then "don't" send HTML page.
          if( srvbuffer.indexOf('?') >=0) {  
            client.println(F("HTTP/1.1 204 Zoomkat"));
            client.println();
            client.println();  
            Serial.println("\n...don't send page...");
          }
          else {  // send page.
            send_HTMLpage();
          }
          delay(1);
          client.stop();
          Serial.println("-server(client) disconnected\n");  
          
          // process buttons presses, etc.
          process_page_requests();
          //clearing string for next read.
          srvbuffer=""; 
        }
      }
    }
  }
}

/* display chars as ASCII, plus control codes
   as .13. etc.
**********************************************/
void display_c( char c )
{
 if( c >= ' ')  Serial.print(c);  
 else {
   Serial.print(" ."); Serial.print( (int)c );  Serial.print(".");
 }
}

Follows is the SerialMonitor screen traffic for several button presses, etc.

Chrome and IE8 on PC (several button presses):

AMI Ethernet Server Test ...
-SRAM left: 14305
-server ready
GET /?cmd=1 HTTP/1.1 .13. .10.
-process requests ..Led1=on..

...Sending HTML page...
--show Vin
--show digital
--show analog
-server(client) disconnected

GET /?cmd=0 HTTP/1.1 .13. .10.
-process requests ..Led1=off..

...Sending HTML page...
--show Vin
--show digital
--show analog
-server(client) disconnected

GET /?cmd=3 HTTP/1.1 .13. .10.
-process requests ..Led2=on..

...Sending HTML page...
--show Vin
--show digital
--show analog
-server(client) disconnected

GET /?cmd=5 HTTP/1.1 .13. .10.
-process requests ..Led3=on..

...Sending HTML page...
--show Vin
--show digital
--show analog
-server(client) disconnected


Android Tablet (only 1 button press):

GET /?cmd=5 HTTP/1.1 .13. .10.
-process requests ..Led3=on..

...Sending HTML page...
--show Vin
--show digital
--show analog
-server(client) disconnected

GET /favicon.ico HTTP/1.1 .13. .10.
...Refresh Only...
--show Vin
--show digital
--show analog
-server(client) disconnected

GET /apple-touch-icon-precomposed.png HTTP/1.1 .13. .10.
...Refresh Only...
--show Vin
--show digital
--show analog
-server(client) disconnected

GET /apple-touch-icon.png HTTP/1.1 .13. .10.
...Refresh Only...
--show Vin
--show digital
--show analog
-server(client) disconnected

belated EDIT: fixed a comment in server_testAMI() just ahead of process_page_requests();

ami_server3b.jpg

oric_dan:
Ah, sweet success. z-k, I took your server logic scheme and modified it a bit, and now have it working the way I wanted. I am using buttons which change label names depending upon the state [1st three in the figure], and which are embedded in TABLE cells with display colors for Red=on and Green=off. The 4th button is used to trigger a command, beep the piezo, etc.

By changing your logic a bit, I am able to process the browser requests, and "then" update the HTML page. Simple enough. It always shows the current data, via button-color, and doesn't need auto-refreshing. You will also note the Digital pin display updates to the current data too, ie Leds 1,2,3 are on pins D25,D26,D27.

Best of all, your wonderful scheme wipes out all the extraneous garbage that the original IDE WebServer sketch was sending. The Android tablet browser still does 4X posts for each request op, but I see that 3 of them are simple refreshes. Chrome and IE8 on my PC only do a single post.

So, more kudos for Zoomkat! This is great.

Great persistence there Oric_Dan.

Any chance you could post the whole sketch so i could use that as the starting point for my customisations ?

regards

Craig

BTW, none of that was garbage. They were ALL legitimate requests for files. You just didn't know it. :wink:

Great persistence there Oric_Dan.

Persistence, whew, I'm about wiped out. 2 days ago I was in a complete funk, as I had no idea what was going on, but finally worked through it. Turns out the example I was using [not z-k's] had a subtle error in the way it was creating button-forms, and they were interacting [the guy had left out a bunch of self-closing tags " />", which I had not even heard of until 2 days ago, ;-)]. I've fixed and commented that now.

Thanks for the support Craig. Actually I do have plans to post the entire AMI-1284 Server sketch on another thread in a day or so. It's to the point now where I can add another control-button to the HTML page in about a minute.

I want to first add a message display window to the bottom of the page, and also check it on my Mega2560 board, and see if it will run at all on my UNO board. And also test it some more in my AMI home automation system, which has over 50KB of code, and also does xively, tweets, menuing on a ColorLCD, and controls a network of RFM12 radios. So far, it seems ok.

SurferTim:
BTW, none of that was garbage. They were ALL legitimate requests for files. You just didn't know it. :wink:

Yeah, I know, but it seems to be gone now, right? [probably not, :-)].

No, they are not gone, you are just dealing with them correctly now.

edit: zoomkat is the guy when it comes to dealing with file requests. You can credit him, and a karma boost for him if you haven't done that.

BTW Tim, do you have any enlightment to add in regards the problem I mentioned in reply #12 concerning a page request being received while the program is receiving data from xively?