Web Server Issues

Afternoon Everone,

I’ve been wracking my brain and buring out google but cant find out how to resolve my issue - I hope you can help.

I’ve setup a web server to drive a number of relays and a Stepper motor. it all seemed to work without issue until I added in a loop for my Stepper motor.

When I press a button on the website the commands related to that button should execute and run through once (except the stepper loop which runs for X number of steps). After this it should wait for a different button to be pressed before taking action again. The issue I’m having is that on pressing the button it runs through the action 3 times. I HAVE NO IDEA WHY.

Please help.

NB - I’ve cut out most of the HTML as it didnt fit in this post. I left the buttons.

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

int long Distance = 0L;                                  // used to count stepper motor steps, in the 100,000 range

const int Warning = 8;                                   // relay for warning system
const int DoorDir = 6;                                   // Stepper motor Direction - Low=in High=Out
const int DoorPulse = 5;                                // Stepper motor pulse
const int PlatformUp = 3;                              // relay 1 for linear actuator H bridge - action retract 
const int PlatformDown = 2;                         // relay 2 for linear actuator H bridge - action extend platform)

char ssid[] = "XXXXXXX";                        
char pass[] = "XXXXXXX";                        
int keyIndex = 0;                                        

int status = WL_IDLE_STATUS;
WiFiServer server(80);

void setup() {
  pinMode(Warning, OUTPUT);
  pinMode(DoorDir, OUTPUT);
  pinMode(DoorPulse, OUTPUT);
  pinMode(PlatformUp, OUTPUT);
  pinMode(PlatformDown, OUTPUT);
  digitalWrite(DoorDir, LOW);
  digitalWrite(DoorPulse, LOW);
  Serial.begin(9600);                                                        // initialize serial communication

  if (WiFi.status() == WL_NO_SHIELD) {                         // check for presence of the wifishield:
    Serial.println("WiFi shield not found");
    while (true);                                                              // don't continue
  }
                                                                                    // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect: ");
    Serial.println(ssid);                                                    // print the network name (SSID                            status = WiFi.begin(ssid, pass);
    delay(10000);
    }
 
    server.begin();                                                         // start the web server on port 80
    printWifiStatus();                                                     // now connected, so print out the status
    }

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.println("<p>");
            client.println("<FORM>");
            client.println("<INPUT type=button value=OPEN-TARANIS onClick=window.location='/L\'>");
            client.println("<INPUT type=button value=CLOSE-TARANIS onClick=window.location='/H\'>");
            client.println("</FORM>");
            client.println("</html>");
            client.println();
            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 "/H" or "/L":
        if (currentLine.endsWith("/H")) {
          digitalWrite(Warning, HIGH);                    // turn the warning system (HIGH is the voltage level)
          delay(1000);                                            // wait for 2 seconds
          digitalWrite(DoorDir, LOW);                      // Ensure stepper is driving out
          while (Distance < 5000L) {                       // this while loop controls the stepper motor steps
            digitalWrite(DoorPulse, HIGH);                // create a pulse for the stepper driver
            delayMicroseconds (100);
            digitalWrite(DoorPulse, LOW);
            delayMicroseconds (100);
            Distance = Distance + 1;                        // record this step
            Serial.print(Distance);
            delayMicroseconds(100);
          }
          digitalWrite(PlatformUp, HIGH);                 // Extend secondary linear (LA2) - platform raises
          delay(1000);                                             // Extend for 20second (timing needs to be confirmed)
          digitalWrite(PlatformUp, LOW);                  // stop linear actuator
          delay(1000);                                             // delay prior to warning system shutdown
          digitalWrite(Warning, LOW);                      // Warning System Shutdown
          delay(1000);
          Distance = 0;                                           //reset the distance counter
        }

        if (currentLine.endsWith("/L")) {
          digitalWrite(Warning, LOW);                     // The following items are the reverse of the process outlined above
          delay(1000);
          digitalWrite(PlatformDown, HIGH);
          delay(1000);
          digitalWrite(PlatformDown, LOW);
          delay(100);
          digitalWrite(DoorDir, HIGH);
          while (Distance < 5000L) {                      // this while loop opens the door and controls the stepper motor movement. divide number by 2000 for cm
            digitalWrite(DoorPulse, HIGH);
            delayMicroseconds (100);
            digitalWrite(DoorPulse, LOW);
            delayMicroseconds (100);
            Distance = Distance + 1;                      // record this step
            Serial.print(Distance);
            delayMicroseconds(100);
          }
          digitalWrite(Warning, LOW);
          delay(1000);
          Distance = 0;                                         //reset the distance counter
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

void printWifiStatus() {

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

  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}

Try putting some Serial.println() lines at strategic decision points within your code. Print the values of variables (like currentLine) that are used to make the decisions driving the execution sequence. Do the printed values match your exectations?

Also, does your application ABSOLUTELY require a web page interface? If not, consider a blynk interface instead.

Hey Gfvalvo,

Thanks for the reply. The code executes as i expect it to with the only exception being that if it see's /H at the end of the string it seems to take that action 3 times. i cant see any reason why.

I wasnt familiar with Blynk but I'm looking at that now - this is my first real project outside of tutorials etc.

I would like to figure out why this is happening though even if only so I dont make the same mistake again!

Thanks

James

So, what do the diagnostic Serial.println() statements that I suggested adding show? What are the values of your decision-making variables at the decision points? Is the program really receiving multiple ‘/H’ lines or does it just think it is? The program is not very large, you should be able to completely instrument it to see exact what it “sees”.

What does the serial monitor show? Do you realize the web browser could be requesting favicon.ico after each request send?

edit: You may be running out of SRAM if there is more html than you are posting. I don't see where you are using the F() macro to conserve SRAM.

Also, I highly recommend dropping the String data type. Use a character array instead. The String type has always crashed my sketches.