Delayed response from webservers action driven links

Hello, I have an ongoing project that I have been working on for the last few weeks. I now have a programming question since I am not getting the expected behavior from the system.

I created several links on a webpage using the Arduino Mega, Official Wifi Shield and Motor Shield. These links drive a 2 meter LED Strip and a 12V 200x BiPolar Stepper Motor.

I have a series of “if” statements and concluding the logic with an “else” statement as follows:

        if (currentLine.endsWith("GET /H") == 1 || currentLine.endsWith("Get /H") == 1) {

          scanner(127,127,127, 10); // Violet      //Dull White

        }
        
        if (currentLine.endsWith("GET /LS") == 1 || currentLine.endsWith("Get /LS") == 1){
          
         leftScanner(255, 0, 255, 10);
          
        }

        if (currentLine.endsWith("GET /L") == 1 ||02 currentLine.endsWith("Get /L") == 1) {
          colorFollow(strip.Color(127,0,127), 10); //Violet            
          strip.show();
        }

        if (currentLine.endsWith("GET /B")==1 || currentLine.endsWith("Get /B") == 1){

          blindsForward();  

          delay(500);
          stepperRelease();
          
        }

        if (currentLine.endsWith("GET /K")==1 || currentLine.endsWith("Get /K") == 1){

          blindsBackward();  
          blindsBackward();  
          blindsBackward();  
          blindsBackward();  
          blindsBackward();  
          blindsBackward();          
          blindsBackward();  
          blindsBackward();  
          blindsBackward();  
          blindsBackward();  
          blindsBackward();  
          blindsBackward(); 
          blindsBackward();  
          blindsBackward();
          delay(500);
          stepperRelease();
          
        }
        
        
          if (currentLine.endsWith("GET /O") == 1 || currentLine.endsWith("Get /O") == 1) {
          colorFollow(strip.Color(0,0,0), 10); //Off
          strip.show();
        }
        
        
        else {

            strip.begin();
            strip.show(); // Initialize all pixels to 'off'
        }

When I initially click the link to start the “swipe()” function (or any other function) I would get the action as expected. I usually obtain the expected results for an extended period of time so I am sure the code is correct.

However there are instances when I click lets say

            client.print("<FONT size = +7><a href=\"/H\"> Scanner</a></FONT>
");

and get the expected results, but when I click a link to another function lets say:

            client.print("<FONT size = +7><a href=\"/L\"> Swipe </a></FONT>
");

I will still get the action from the scanner() function, even though I see in my browser a url that ends in “/L”

I am not sure why this happens intermittently. At first I thought it was a power issue, but I ran the set up through the forums here to double check on what I did. I then thought it was a memory issue, but I have no way of testing it that I know of.

Any advice?

For those interested my entire code is attached below.

WifiWebLight_Stepper.ino (12.5 KB)

For those interested my entire code is attached below.

Where is your serial output? Does the client include the referer line that includes the previous GET command?

What do you mean by serial output, are you referring to the output from the serial monitor?

If that's the case, how can I acquire that since this is running via a WiFi shield and therefore no USB cable.

I have no idea what the "referrer" line" is means. Google-ing "referrer line Arduino" leads me to believe you are talking about calling the IP adress. If that is the case my line is as follows:

  IPAddress ip = WiFi.localIP();

Sorry if I don't know to much verbiage, I am fairly new to Arduino and programming in general.

Here is my serial monitor output:

Attempting to connect to Network named: EnGeniusE27B20
SSID: EnGeniusE27B20
IP Address: 192.168.0.123
signal strength (RSSI):-51 dBm
To see this page in action, open a browser to http://192.168.0.123
new client
GET / HTTP/1.1
Host: 192.168.0.123
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.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Accept-Language: en-US,en;q=0.8

client disonnected
new client
GET /favicon.ico HTTP/1.1
Host: 192.168.0.123
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Accept-Language: en-US,en;q=0.8

client disonnected
new client
GET /H HTTP/1.1
Host: 192.168.0.123
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.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Referer: http://192.168.0.123/
Accept-Language: en-US,en;q=0.8

client disonnected
new client
GET /favicon.ico HTTP/1.1
Host: 192.168.0.123
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Accept-Language: en-US,en;q=0.8

client disonnected

It seems like I must be connected via a cable to get this output, and this problem usually happens when I am not connected via a cable. This output was operating as expected so it does not reflect any lag that I was experiencing at an earlier time.

are you referring to the output from the serial monitor?

I am referring to the output TO the Serial Monitor application.

If that's the case, how can I acquire that since this is running via a WiFi shield and therefore no USB cable.

This implies that you think that because you have a radio that you don't need a dishwasher. They perform different purposes. They are not mutually exclusive.

I have no idea what the "referrer" line" is means.

Then I'm not sure that you are ready to be developing client/server applications. When a URL directs to another page, part of the data that the server sends is the URL of the page (the referrer) that the redirect came from.

Good, I was right on the assumption of the serial monitor output from the Arduino. From tutorials online, they all involve a USB cable.

Again, if this is a WiFi project, and all trials are done wireless, how can I gain wireless access to the Serial Monitors output?

Radio's communicate via electromagnetic radiation, dishwashers communicate with soap. I don't get your radio/dishwasher reference.

Serial monitor communication begins from the command:

Serial.begin(####);

Then I'm not sure that you are ready to be developing client/server applications.

Learning starts somewhere. It's a jigsaw puzzle more often then not, put together in bits and pieces.
I wouldn't have the need to ask questions such as these if I was ready to develop client/server applications.

When a URL directs to another page, part of the data that the server sends is the URL of the page (the referrer) that the redirect came from.

So there is a communication process, something along the lines of 192.168.0.123/L responding from 192.168.0.123/O ?

If there is a communication error happening between the "referrer" and the "direct", what can be a factor in its miscommunication?

My serial output was modified in the above post.

I am not getting the expected behavior from the system.

Perhaps a little more detail on your system and how you expect it to work. Is the arduino performing a client, server, or combination of both function? Does the arduino supply the web pages to the client (browser?)? From the serial monitor it appears that a browser (chrome?) is connecting to your arduino, so what method in your code are you using to collect the GET request data sent by the browser?

Needs fix:

if (currentLine.endsWith("GET /L") == 1 ||02 currentLine.endsWith("Get /L") == 1) {

Also, shouldn't that be startsWith?

Again, if this is a WiFi project, and all trials are done wireless, how can I gain wireless access to the Serial Monitors output?

You can't. But, for debugging purposes, why do you want to work blind?

Radio's communicate via electromagnetic radiation, dishwashers communicate with soap. I don't get your radio/dishwasher reference.

You seem to think that because the end project is to be wireless that you can't use wires (the USB cable) during the development process. Get over it.

Chagrin thanks for reviewing the file I attached, it was a typo from staring at the computer

The complete code (which currently operates as expected) will be posted in a reply due to a limit in characters.

I have an Arduino Mega, on top that is the official WiFi Shield, and on top that is the official Motor Shield. I have a 2 meter strip of individually addressable RGB LEDs connected to 5V and Gnd on the Arduino. It is being powered by a 4.5V wall-wart on the other end of the strip. I also have a 12V 200x Stepper Motor connected to pin 6 on the Arduino. The Motor Shield’s power jumper is severed, I am powering the stepper motor through the shields screw terminals with 12V. I am also powering the Arduino (and the WiFi Shield attached on top) with a 12V wall-wart.

The WiFi Shield has the default connectNoEncryption coding found in the examples folder. From the coding attached, yes, the Arduino provides the webpage. It has the default WifiWebServer code integrated in it.

what method in your code are you using to collect the GET request data sent by the browser?

I am using the URL generated from this bit of code:

            client.print("<FONT size = +7><a href=\"/B\"> Blinds: Forwards </a></FONT>
");

You can see from the complete code I have also included the headers.

For the most part, I get the expected results from the above code. I.e, stepper motor moves one direction (to open my blinds) as well as the other direction (to close the blinds) and I am able to run though lighting sequences I set up as function during my testing (lighting) phase. (since the 2 meter light is running across the top of my blinds)

My program is up and running for possibly a few days, no problems. Blinds open, blinds close, lights scan side to side and light up in a sequence to brighten the whole room.

And then one day I came home and tried to turn on the lights, and the blinds closed. I remember that closing the blinds was the last command I clicked prior to turning on the lights.

I am confused as to what can cause a problem such as this.

PaulS I never got under it in the first place, why would I get over it? You’re assuming I didn’t debug prior to going wireless. Someone with the inability to see wouldn’t do that; a moron would.
My question asked how one would debug (or acquire an error file) once no longer connected to the Arduino. Lets say, given a circumstance I am getting “expected results” consistently yet one day, I notice erratic or illogical behavior. Another words, where’s my Dr. Watson file? Does the WiFi shield log error messages to the SD card on board? Logging a error message would be a step in the right direction.

To cover “erratic” or “illogical” behavior I am referring to clicking on the link to drive the blinds forward, and receiving those results; yet after clicking on a different link, lets say to turn the lights on, I notice the last command (for instance, driving the blinds forward) has executed as opposed to the latter.

Once resetting the Arduino, this solves the problem. However, I would hate to reset a board frequently. As of right now the results are functioning with no problem. I will try to find a way to log any further errors in the instance that they reappear.

/*
  WiFi Web Server LED Strip and Stepper Motor
 
 A simple web server that lets you enable sequences from a LED Strip
 and con  trol a stepper Motor for blindss via the web.
 This sketch will print the IP address of your WiFi Shield (once connected)
 to the Serial monitor. From there, you can open that address in a web browser
 to turn on and off the components.
 
 If the IP address of your shield is yourAddress:
 http://yourAddress/H turns the LED to scanner
 http://yourAddress/L turns it to swipe
 Follow this pattern to create new links
 
 This example is written for a network using no encryption. For 
 WEP or WPA, change the Wifi.begin() call accordingly.
 
 Circuit:
 * WiFi shield attached
 * LED attached to pin 6 and Gnd and 5V
 * Motor Shield is attached
 *Stepper Motor conected to terminal blocks
 
 created 21 June 2013
 by James Hayek
 */

#include <SPI.h>
#include <WiFi.h>
#include <Adafruit_NeoPixel.h>

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)

Adafruit_NeoPixel strip = Adafruit_NeoPixel(120, 6, NEO_GRB + NEO_KHZ800);

char ssid[] = "EnGeniusE27B20";      //  your network SSID (name) 
//char pass[] = "secretPassword";   // your network password
//int keyIndex = 0;                 // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
WiFiServer server(80);

int delaylegnth = 25;
     

void setup() {

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  pinMode(6, OUTPUT);      // set the LED pin mode
  Serial.begin(9600);



  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    while(true);        // don't continue
  } 

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:    
    status = WiFi.begin(ssid);
    // wait 5 seconds for connection:
    delay(5000);
  } 
  server.begin();                           // start the web server on port 80
  printWifiStatus();                        // you're connected now, so print out the status


    //Stepper Motor Code

  //establish motor direction toggle pins
  pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards???
  pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards???  

  //establish motor brake pins
  pinMode(9, OUTPUT); //brake (disable) CH A
  pinMode(8, OUTPUT); //brake (disable) CH B


}


void loop() {
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {  
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:    
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("<FONT size = +7><a href=\"/LS\"> New Scanner</a></FONT>
");
            client.print("<FONT size = +7><a href=\"/H\"> Scanner</a></FONT>
");
            client.print("<FONT size = +7><a href=\"/L\"> Swipe </a></FONT>
");
            client.print("<FONT size = +7><a href=\"/O\"> Lights: Off </a></FONT>
");
            client.print("<FONT size = +7><a href=\"/B\"> Blinds: Forwards </a></FONT>
");
            client.print("<FONT size = +7><a href=\"/K\"> Blinds: Backwards </a></FONT>
");


            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;         
          } 
          else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        }     
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L or ...":

        if (currentLine.endsWith("GET /H") == 1 || currentLine.endsWith("Get /H") == 1) {

          scanner(127,127,127, 10); // Violet      //Dull White

        }
        
        if (currentLine.endsWith("GET /LS") == 1 || currentLine.endsWith("Get /LS") == 1){
          
         leftScanner(255, 0, 255, 10);
          
        }

        if (currentLine.endsWith("GET /L") == 1 || currentLine.endsWith("Get /L") == 1) {
          colorFollow(strip.Color(127,0,127), 10); //Violet            
          strip.show();
        }

        if (currentLine.endsWith("GET /B")==1 || currentLine.endsWith("Get /B") == 1){

          blindsForward();  

          delay(500);
          stepperRelease();
          
        }

        if (currentLine.endsWith("GET /K")==1 || currentLine.endsWith("Get /K") == 1){

          blindsBackward();  
          
          delay(500);
          stepperRelease();
          
        }
        
        
          if (currentLine.endsWith("GET /O") == 1 || currentLine.endsWith("Get /O") == 1) {
          colorFollow(strip.Color(0,0,0), 10); //Off
          strip.show();
        }
        
        
        else {

            strip.begin();
            strip.show(); // Initialize all pixels to 'off'        // Wanted to block this out to see if there is any difference with the lights flickering. (And Arduino making a buzzing sound)
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

And these are the functions coded below the two main loops. (void setup() and void loop())

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}


void colorFollow(uint32_t c, uint8_t wait) { 
  for(uint16_t k=0; k<strip.numPixels(); k++) 
  {
    strip.setPixelColor(k, c); 
    strip.show();
    delay(wait);    
  }
}


// "Larson scanner" = Cylon/KITT bouncing light effect
void scanner(uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
  int i, j, pos, dir;

  pos = 0;
  dir = 1;

  for(i=0; i<((strip.numPixels()-1) * 4); i++) {
    // Draw 5 pixels centered on pos.  setPixelColor() will clip
    // any pixels off the ends of the strip, no worries there.
    // we'll make the colors dimmer at the edges for a nice pulse
    // look
    strip.setPixelColor(pos - 2, strip.Color(r/4, g/4, b/4));
    strip.setPixelColor(pos - 1, strip.Color(r/2, g/2, b/2));
    strip.setPixelColor(pos, strip.Color(r, g, b));
    strip.setPixelColor(pos + 1, strip.Color(r/2, g/2, b/2));
    strip.setPixelColor(pos + 2, strip.Color(r/4, g/4, b/4));

    strip.show();
    delay(wait);
    // If we wanted to be sneaky we could erase just the tail end
    // pixel, but it's much easier just to erase the whole thing
    // and draw a new one next time.
    for(j=-2; j<= 2; j++) 
      strip.setPixelColor(pos+j, strip.Color(0,0,0));
    // Bounce off ends of strip
    pos += dir;
    if(pos < 0) {
      pos = 1;
      dir = -dir;
    } 
    else if(pos >= strip.numPixels()) {
      pos = strip.numPixels() - 2;
      dir = -dir;
    }
  }
}



// "Larson scanner" = Cylon/KITT bouncing light effect      //Modification
void leftScanner(uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
  int i, j, pos, dir;

  pos = 61;
  dir = 1;

  for(i=61; i<((((strip.numPixels())/2)-1) * 4); i++) {
    // Draw 5 pixels centered on pos.  setPixelColor() will clip
    // any pixels off the ends of the strip, no worries there.
    // we'll make the colors dimmer at the edges for a nice pulse
    // look
    strip.setPixelColor(pos - 2, strip.Color(r/4, g/4, b/4));
    strip.setPixelColor(pos - 1, strip.Color(r/2, g/2, b/2));
    strip.setPixelColor(pos, strip.Color(r, g, b));
    strip.setPixelColor(pos + 1, strip.Color(r/2, g/2, b/2));
    strip.setPixelColor(pos + 2, strip.Color(r/4, g/4, b/4));

    strip.show();
    delay(wait);
    // If we wanted to be sneaky we could erase just the tail end
    // pixel, but it's much easier just to erase the whole thing
    // and draw a new one next time.
    for(j=-2; j<= 2; j++) 
      strip.setPixelColor(pos+j, strip.Color(0,0,0));
    // Bounce off ends of strip
    pos += dir;
    if(pos < 0) {
      pos = 1;
      dir = -dir;
    } 
    else if(pos >= strip.numPixels()) {
      pos = strip.numPixels() - 2;
      dir = -dir;
    }
  }
}



void blindsForward(){

 for (int increment = 0; increment < 56; increment++ ){
  digitalWrite(9, LOW);  //ENABLE CH A
  digitalWrite(8, HIGH); //DISABLE CH B

  digitalWrite(12, HIGH);   //Sets direction of CH A
  analogWrite(3, 255);   //Moves CH A
  
  delay(delaylegnth);
  
  digitalWrite(9, HIGH);  //DISABLE CH A
  digitalWrite(8, LOW); //ENABLE CH B

  digitalWrite(13, LOW);   //Sets direction of CH B
  analogWrite(11, 255);   //Moves CH B
  
  delay(delaylegnth);
  
  digitalWrite(9, LOW);  //ENABLE CH A
  digitalWrite(8, HIGH); //DISABLE CH B

  digitalWrite(12, LOW);   //Sets direction of CH A
  analogWrite(3, 255);   //Moves CH A
  
  delay(delaylegnth);
    
  digitalWrite(9, HIGH);  //DISABLE CH A
  digitalWrite(8, LOW); //ENABLE CH B

  digitalWrite(13, HIGH);   //Sets direction of CH B
  analogWrite(11, 255);   //Moves CH B
  
  delay(delaylegnth);

}
}


void stepperRelease(){

  digitalWrite(9, LOW);  //ENABLE CH A
  digitalWrite(8, HIGH);  //DISABLE CH B

  digitalWrite(12, LOW);   //Sets direction of CH A
  analogWrite(3, 0);   //Moves CH A

  delay(delaylegnth);

  digitalWrite(9, HIGH); //DISABLE CH A
  digitalWrite(8, LOW); //ENABLE CH B

  digitalWrite(13, LOW);   //Sets direction of CH B
  analogWrite(11, 0);   //Moves CH B

  delay(delaylegnth);

  digitalWrite(9, LOW);  //ENABLE CH A
  digitalWrite(8, HIGH); //DISABLE CH B

  digitalWrite(12, HIGH);   //Sets direction of CH A
  analogWrite(3, 0);   //Moves CH A

  delay(delaylegnth);

  digitalWrite(9, HIGH);  //DISABLE CH A                  
  digitalWrite(8, LOW);  //ENABLE CH B                     

  digitalWrite(13, HIGH);  //Sets direction of CH B
  analogWrite(11, 0);   //Moves CH B

  delay(delaylegnth); 


}


void blindsBackward(){                                       //This is done by revesing the sequence of the foward direction

 for (int increment_2 = 0; increment_2 < 56; increment_2++ ){
  digitalWrite(9, HIGH);  //ENABLE CH A
  digitalWrite(8, LOW); //DISABLE CH B

  digitalWrite(12, LOW);   //Sets direction of CH A
  analogWrite(3, 255);   //Moves CH A
   
  delay(delaylegnth);
  
  digitalWrite(9, LOW);  //DISABLE CH A
  digitalWrite(8, HIGH); //ENABLE CH B

  digitalWrite(13, HIGH);   //Sets direction of CH B
  analogWrite(11, 255);   //Moves CH B
  
  delay(delaylegnth);
  
  digitalWrite(9, HIGH);  //ENABLE CH A
  digitalWrite(8, LOW); //DISABLE CH B

  digitalWrite(12, HIGH);   //Sets direction of CH A
  analogWrite(3, 255);   //Moves CH A
  
  delay(delaylegnth);
    
  digitalWrite(9, LOW);  //DISABLE CH A
  digitalWrite(8, HIGH); //ENABLE CH B

  digitalWrite(13, LOW);   //Sets direction of CH B
  analogWrite(11, 255);   //Moves CH B
  
  delay(delaylegnth);

}
}

You seem to be assuming that it is not possible to connect a USB cable to the Arduino that experiences the problem. Is that really the case?

Since you have an Ethernet interface you have the capability to send trace/error messages elsewhere, albeit at the risk of complicating your sketch and changing the problem.

If your Ethernet shield includes an SD card then you could change your sketch to write trace/error messages to that. You could either remove the SD card to view the messages, or provide a way to access them via the Ethernet interface.

You could also store a limited amount of trace/error information in RAM or EEPROM.

There are lots of methods to get trace/error information off the Arduino. You just need to design when/how it is captured and output to suit the method you choose to implement.

You seem to be assuming that it is not possible to connect a USB cable to the Arduino that experiences the problem. Is that really the case?

Yes, I did not know up until now that I can connect a USB cable to the device and open the serial monitor to gather data.

If your Ethernet shield includes an SD card then you could change your sketch to write trace/error messages to that. You could either remove the SD card to view the messages, or provide a way to access them via the Ethernet interface.

Yup, it does. I will look into re-routing error messages to the SD card. Thanks. I'm assuming I can do this by writing it to the card as opposed (or in conjunction with) to the serial monitor.

There are lots of methods to get trace/error information off the Arduino. You just need to design when/how it is captured and output to suit the method you choose to implement.

Thank you, I will now read up on that.

This may not be the bug you're after, but it looks like a problem:

       if (currentLine.endsWith("GET /LS") == 1 || currentLine.endsWith("Get /LS") == 1){
               ...
        }

        if (currentLine.endsWith("GET /L") == 1 ||02 currentLine.endsWith("Get /L") == 1) {
             ...
        }

An input ending with "GET /LS" will fall into the first case, and then also fall into the second case. Which may not be what you want.

Shouldn't that whole sequence be a chain of if-else if tests, so that only one is executed?

-br

Yes, those lines do seem a bit strange. I initially wrote them without the or gate and intermittently encountered the problem. As per a recommendation from a patron at a bar I work at, he suggested using an or or and gate to catch any instances or event that would trigger a wrong execution of code.

I can’t remember if the error occurred since the new implementation of the “if” statement.

Shouldn’t that whole sequence be a chain of if-else if tests, so that only one is executed?

Yes, I only want one to be executed at a time. Isn’t that what’s happening? I will look into the differences of a series of “if’s” and a complete set of “if else”

Looks like I’m going to have to read up on writing to the SD card, and logging any output (trace/error information) as per PeterH’s recommendations. Either that or plug in the USB cable to see if I can get info from the serial monitor.

JamesHayek:
Either that or plug in the USB cable

I'm not sure whether you're being sarcastic here, but using serial trace output via USB is so massively more convenient than all the other options that if this is available to you, using it is a no-brainer.

Not sarcastic at all, I was in a prior post to someone who basically told me I shouldn't be doing this project but to you and everyone else I am being sincere. (and even to him after our initial flame war)

I never knew one could plug in the USB cable, launch the Arduino IDE and open the Serial Monitor to gather data from an (initially unplugged) Arduino running the code.

Knowing that I might not even log any error messages to the SD card, but it would still be a good topic for me to read and review.

Some simple server test code that might be of interest. This uses the F() macro on the static strings in the code to reduce memory space usage, and the .indexOf() String function to identify if desired character strings are contained in the client GET request.

//zoomkat 7-6-13
//simple button GET for servo and pin 5
//for use with IDE 1.0 or later
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html, or use ' instead of " 
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//includes F() macro to save memory space

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // 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

String readString; 

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

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  myservo.write(90); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control
  //enable serial data print 
  Serial.begin(9600); 
  Serial.println(F("server servo/pin 5 test 1.0")); // 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 

          client.println(F("HTTP/1.1 200 OK")); //send new page
          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("<H1>Zoomkat's simple Arduino button</H1>"));
          
          client.println(F("<a href=\"/?on\">ON</a>")); 
          client.println(F("<a href=\"/?off\">OFF</a>")); 

          client.println(F("</BODY>"));
          client.println(F("</HTML>"));
 
          delay(1);
          //stopping client
          client.stop();

          // control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            myservo.write(40);
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println(F("Led On"));
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            myservo.write(140);
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println(F("Led Off"));
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

JamesHayek:
gather data from an (initially unplugged) Arduino running the code.

Opening the serial port would usually cause the Arduino to reset, so the conventional approach would be to connect the USB lead at the outset and open the serial monitor or you other preferred serial client (I'd suggest RealTerm) and start capturing the trace output - then do whatever is needed for the problem to occur. Connecting the USB lead or opening the serial port during the execution of your sketch would be problematic.

I like the F() macro, I will play around and implement that.

Opening the serial port would usually cause the Arduino to reset

I actually noticed that and thought it was something in the coding. I plugged the USB cable into the Arduino and computer, launch the IDE and Serial Monitor. Arduino resets every time.

What do you mean by ' connect the usb lead at the "outset" ' ?

downloaded RealTerm, reading up on it now.