Arduino Uno webserver switches output off when..

Hello Everyone,
This is one of my first posts so go easy on me! I have been playing around with the Uno connected to an w5100 ethernet sheild to control my hot water heater remotely via a webserver.
Now I have managed to get my head round most things with a bit of cut and paste and a bit of my own logic etc but there is this one thing that I can not sort out.
It all works fine apart from that when I switch the output on (Will be a relay but is an LED at the moment) and leave the webpage all is fine. It stays on until I revisit the page and then the LED flashes once and then goes off. If you leave the output off and then come back to the page it stays off. It is just when it is surposed to stay on that it does not.

Any ideas???

Cheers

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

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x9C, 0xCD };  // MAC address from Ethernet shield sticker under board
IPAddress ip(192,168,2,20);  // IP address, may need to change depending on network
byte gateway[] = { 192, 168, 2, 1 };  //Routers IP Address to which your shield is connected.
byte subnet[] = { 255, 255, 255, 0 };  //It will be as it is in most of the cases
EthernetServer server(80);  //create a server at port 80

String readString;
int HW_relay = 0;   // state of hot water relay, off by default at start/reset/power on

void setup(){
  
  //pins selected to control
  pinMode(3, OUTPUT); 
    

  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //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') {

          Serial.println(readString); //print to serial monitor 
          
          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>Home Automation Hub</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          
          client.println("<meta name='viewport' content='width=device-width'; initial-scale=1.0; maximum-scale=1.0;>");  //size page for mobile devices
                  
          //Control buttons for output pin 3          
          client.println("<h1>Hot Water</h1>");
          client.print("<input type=submit value=ON style=width:100px;height:45px onClick=location.href='/?on2'>");               
          client.print("&nbsp;&nbsp;<input type=submit value=OFF style=width:100px;height:45px onClick=location.href='/?off3'>");
          
         //////Check for button press and switch output on or off/////
           
         if(readString.indexOf('2') >0)  //see if ON button was clicked and switch relay if 2 found          
            { 
              digitalWrite(3, HIGH);
              client.println("&nbsp;&nbsp;<font color='green'>ON</font");  //show status on
            }
              else
          //if(readString.indexOf('3') >0)  //see if OFF button was clicked and switch relay if 3 found
            {
              digitalWrite(3, LOW);
              client.println("&nbsp;&nbsp;<font color='red'>OFF</font");  //show status off
            }
            
          ///////////
                       
          client.println("</BODY>");
          client.println("</HTML>");
 
          delay(1);
          //stopping client
          client.stop();                 
             
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

If there is not a '2' in the GET string, the LED is turned off. If you uncomment the second readString.indexOf, it probably won't turn off. It is common for the web browser to request a file called favicon.ico after it loads the webpage. That would cause the LED to turn on (webpage request) and then off (favicon request).

         if(readString.indexOf('2') >0)  //see if ON button was clicked and switch relay if 2 found          
            { 
              digitalWrite(3, HIGH);
              client.println("&nbsp;&nbsp;<font color='green'>ON</font");  //show status on
            }
              else
          //if(readString.indexOf('3') >0)  //see if OFF button was clicked and switch relay if 3 found
            {
              digitalWrite(3, LOW);
              client.println("&nbsp;&nbsp;<font color='red'>OFF</font");  //show status off
            }

Hi,
Thanks for the reply. Forgot that was commented out. I was playing around to try and get it to work, I did that when i put in the else command. It still works the same with the line not commented and the else got rid of.

Interesting about the favicon.

Any other ideas?

In your code you need to change the String search from a single character (which may be in several places in the returned header) to a multi character String like below.

if(readString.indexOf('2') >0)

to

if(readString.indexOf("on2") >0)

Thanks Zoomkat,

Yes I intend to have more than just one relay in the end doing different things so I was thinking of changing the search to look for more to save errors later.

Its all working apart from that darn output going high when I leave the relay off then navigate away from the server onto another site, return to the Arduino and it sets the output to on if it was off!

Any further ideas anyone? I will have to investigate the favicon thing...

Cheers everyone!

Well, almost have it working the way I want but when you first navigate to the server it would be great to see the current state of the outputs before any buttons are pressed. So far I have tried to call the state of the outputs and display them but I end up with two on's or two off's displayed! Another one I tried it end up having to press either button twice!
Its getting late and I have totally fried my brain....

Anyway, here is the sort of working sketch it just does not display the state on initial page load.

Any ideas anyone??

Cheers

Crumpy

PS Thought I would implement the extra char in the string, thanks for reminding me Zoomkat!

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

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x9C, 0xCD };  // MAC address from Ethernet shield sticker under board
IPAddress ip(192,168,2,20);  // IP address, may need to change depending on network
byte gateway[] = { 192, 168, 2, 1 };  //Routers IP Address to which your shield is connected.
byte subnet[] = { 255, 255, 255, 0 };  //It will be as it is in most of the cases
EthernetServer server(80);  //create a server at port 80

String readString;

// constants won't change. They're used here to set pin numbers:
const int HW_relay = 3;  //Hot water relay set on pin 3

// variables will change
int HW_relay_state = 0;  // state of hot water relay, off by default at start/reset/power on

void setup(){
  
  //pins selected to control
  pinMode(HW_relay, OUTPUT); //Hot water pin set as output
    

  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //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') {

          Serial.println(readString); //print to serial monitor 
          
          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>Home Automation Hub</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<meta name='viewport' content='width=device-width'; initial-scale=1.0; maximum-scale=1.0;>");  //size page for mobile devices
                  
          //Control buttons for Hot Water relay on output pin 3          
          client.println("<h1>Hot Water</h1>");
          client.print("<input type=submit value=ON style=width:100px;height:45px onClick=location.href='/?on2'>");               
          client.print("&nbsp;&nbsp;<input type=submit value=OFF style=width:100px;height:45px onClick=location.href='/?off3'>");
          
          
         //////Check for button press and switch outputs on or off/////
           
         if(readString.indexOf('on2') >0)  //see if ON button was clicked and switch relay on if 2 found          
            { 
              digitalWrite(HW_relay, HIGH);
              client.println("&nbsp;&nbsp;<font color='green'>ON</font");  //show status on
            }
         if(readString.indexOf('off3') >0)
            {
              digitalWrite(HW_relay, LOW);
              client.println("&nbsp;&nbsp;<font color='red'>OFF</font");  //show status off
            }
            
          ///////////
                       
          client.println("</BODY>");
          client.println("</HTML>");
 
          delay(1);
          //stopping client
          client.stop();                 
             
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

I evaluate the request string (character array) for more than just those characters. I insure the page requested is correct among other parameters.
http://playground.arduino.cc/Code/WebServerST

For your other question, I would try this.

         //////Check for button press and switch outputs on or off/////
           
         if(readString.indexOf("on2") >0)  //see if ON button was clicked and switch relay on if 2 found          
            { 
              digitalWrite(HW_relay, HIGH);
              client.println("&nbsp;&nbsp;<font color='green'>ON</font");  //show status on
            }
         else if(readString.indexOf("off3") >0)
            {
              digitalWrite(HW_relay, LOW);
              client.println("&nbsp;&nbsp;<font color='red'>OFF</font");  //show status off
            }
         else if(digitalRead(HW_relay) == LOW)  // check the pin for LOW state
            {
              client.println("&nbsp;&nbsp;<font color='red'>OFF</font");  //show status off
            }
         else
            {
              client.println("&nbsp;&nbsp;<font color='green'>ON</font");  //show status on
            }

Hey Tim,

Thanks for that, should have been able to see that. :blush: Well, we get so tied up in the brain sometimes....

Just needed another set of eyes. Karma given.

Works like a charm now thank you. :slight_smile: