2/3 Way Switch through software.

Hi,

Im relatively new to Arduino but not electrical circuits etc.

I have a Arduino set up hosting a simple webpage with 3 form buttons controlling 3 SPST relays controlling the mains.

I want to achieve a 2way(UK) / 3way(US) switch circuit but through software.

At the moment I have 3 Arduino outputs connected to the relays.

I want to add 3 latching switch inputs so when the switch change state the corresponding outputs do the opposite of what they're currently at regardless of what the html page is set to.

Much like a typical household 2/3 three way circuit, but I must use SPST relays and switches. And also the benefit of have software control it would be that the Arduino would always know if the circuit is off or on.

How ever I don't know how to achieve this, any ideas on code .etc?

I think I found a perfect example of this online but stupidly didn't save it!

save the current state in a bool variable. To change it just use the not operator (!);

eg

bool currentState;

void loop()
{

if(someCondition)
 {
  currentState = !currentState;
  digitalWrite(somePin, currentState);
 }
}

Thanks, I'll give it a try and see how I get on,

will this work with a latching switch?

In a 2 way or 3 way switch system (I don't understand the US/UK distinction you made by the way), you can't rely on the Arduino to track what's going on with simple variables. The Arduino might think the light is on, but someone could come along and use one of the other switches. The Arduino needs some positive feedback that the light is on or off. An LDR would be simpler than trying to detect current flow in mains wiring (and safer).

Paul

Just from what I read, what the UK would call a 2 way switch circuit the US would call 3 way.

I would like to achieve this through software completely, so the switch would actually be a digital input into the arduino rather than switching the mains circuit. I think this would be easier to achieve hardware wise and because I have to use a SPST relay and switch.

My programming knowledge is extremely limited but I have managed to get as far as what I've described in the OP.

I'll have ago using some if statements and bool variables and I post some code.

Strange! I would have expected 3 switches controlling the same light to be called a "3 way" on either side of the pond!

But now I'm confused over your application. I can see why you might want 2 physical switches and one web-based switch to control a light, but why 3 web-based switches controlling the same light? Or is each controlling a separate light and each light has one or more physical switches also?

Good idea to keep it simple by connecting the physical switches to the Arduino, I didn't think of that. Only problem is if the Arduino fails in some way, the physical switches won't work either.

Post your code if you get stuck.

Paul

PaulRB:
Only problem is if the Arduino fails in some way, the physical switches won't work either.

People seem to say that whenever this matter of light switches is brought up.

I find it puzzling. Given that your code is correct and you have constructed it robustly (with bypassing, adequate regulation and so on), why would you expect the Arduino to fail? It's not running Windoze after all.

As regards the OP, he has failed to properly characterise his problem, which is why we are left groping for useful suggestions. What does he want this to actually do? What are the input devices and what is the state (or transition) table?

Sorry I thought my OP was clear enough.

The Arduino currently has 3 outputs each controlling a relay.

I have a ethernet shield and am hosting a webpage with nothing but 3 buttons, each button switches one of the relays. i.e. button one switches relay 1, button two, switches relay 2 etc etc.

At the moment I have no physical input devices, just a simple webpage controlling the outputs.

What I would like to do is to have three inputs, each a latching switch and each controlling one of the outputs, i.e. input 1 switches output 1 etc etc.

So when you flick the switch or press the button on the webpage, the output switches to the opposite to what it currently is.
Exactly what happens in a typical lighting circuit with two switches for one light.

I did find a forum post (I can't remember whether on here or not) where they had two inputs controlling one outputs doing exactly what I just described.

TerryGould1991:
I have a ethernet shield and am hosting a webpage with nothing but 3 buttons, each button switches one of the relays. i.e. button one switches relay 1, button two, switches relay 2 etc etc.

So what you want is to hit the button once and the light goes on, hit it again and the light goes off. Is that correct?
[EDIT] Or do you want 'radio' buttons: Whichever switch you hit, the other lights go off.

I think the original 2/3 way distinction is useful and it helps understanding what the OP wants to do.

"2 way" = two switches controlling one light
"3 way" = to accomplish the above, you need to use switches with 3 terminals on them

Remember those definitions are written for household electricians who don't want to know what electrons are.

For the physical switches ("inputs") the Arduino needs to remember the state of the switch. Then it can compare that with the current state to identify when the switch was switched. For example:

// Pin 13 has an LED connected on most Arduino boards.
int led = 13;
//Put the switch between pin 2 and ground. 
int switch = 2;

//store the switch position and LED output state
bool switch_position;
bool led_state;

void setup() {                
  // initialize the digital pins
  pinMode(led, OUTPUT);     
  pinMode(switch, INPUT_PULLUP);  
  //find out the starting position of the switch
  switch_position = digitalRead(switch);
  //light off to begin with
  led_state = LOW;
  digitalWrite(led_state);
}

void loop() {
  if(switch_position != digitalRead(switch)) {
    led_state = !led_state;
    switch_position = !switch_position;
    digitalWrite(led, led_state);  
    delay(100);               // debouncing - ignore any further switching for 1/10th of a second
  }
}

(Untested :smiley: )

It would appear that what is wanted here is a toggle with a Web indication.

Press the Web button and the corresponding switch changes over; press the real pushbutton and it does the same. The Web version presumably will have some means for conveying the present on/ off state.

Here is a toggle (in the Loop code). Give it a try:

// Button toggle with extreme reliability!

const int led1Pin =  13;    // LED pin number
const int button1 =  10;
int led1State = LOW;        // initialise the LED
char bstate1 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(button1, INPUT);      
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (led1State == LOW) {
      led1State = HIGH;
    }
    else {
      led1State = LOW; 
    } 
    digitalWrite(led1Pin, led1State);
  } 
}

Paul__B:
It would appear that what is wanted here is a toggle with a Web indication.

Press the Web button and the corresponding switch changes over; press the real pushbutton and it does the same. The Web version presumably will have some means for conveying the present on/ off state.

My understanding from reading the requirements is close to this. However, instead of pushbuttons, it sounds like he wants to use toggle switches. It sounds like one use case might be this:

  • Initial conditions: relay is off, toggle switch is down
  • web page button is pressed: relay turns on
  • web page button is pressed: relay turns off
  • toggle switch is flipped up: relay turns on
  • web page button is pressed: relay turns off
  • toggle switch is flipped down: relay turns on
  • web page button is pressed: relay turns off
  • web page button is pressed: relay turns on
  • toggle switch is flipped up: relay turns off

Basically, pressing the web button toggles the relay, and changing the switch state toggles the relay. This is almost the same as Paul's provided example, except that his example would require the switch to be turned on then turned off to toggle the output. In this case, sometimes flipping the switch up turns on the relay, sometimes it turns it off -- it all depends on the previous state of the relay. Just like a hallway light controlled by a switch on either end: sometimes flipping a switch up turns it on, and sometimes it turns it off -- it all depends on the position of the switch at the other end of the hall.

The change to do the above use case is simple. In Paul's code is a state machine to debounce the mechanical switch contacts (an important consideration!) the butndown() function only returns true when the button has been up long enough to be stable (case 2, where butnstate is set to 1.) To make it work with a latching switch, it also needs to return true when the button has been down long enough to be stable (case 3, just after butnstate is set to 0.)

Basically, any time the switch has reached a stable state different from the previous stable state, toggle the output.

MorganS:
"3 way" = to accomplish the above, you need to use switches with 3 terminals on them

Remember those definitions are written for household electricians who don't want to know what electrons are.

Precisely. The US terminology comes from the number of connections on the switch, not the number of switches in the circuit or the number of positions on the switch (they are always two positions.)

A 2-way switch has two screw terminals. It is an SPST switch. It is used as a standard single switch.

A 3-way switch has three screw terminals. It is an SPDT switch. It is used in pairs where two switches are to control one load.

A 4-way switch has four screws. It is a DPDT switch internally wired as a reversing switch, where the two redundant connections are not brought out (the two common DPDT terminals are one pair of screws, the two NC contacts are brought out as the other pair of screws, and the NO contacts are internally wired to the NC contacts in a crossover manner.) This switch is used with a pair of 3-way switches when three or more switches are to control one load.

The UK naming conventions refer to the number of switches, while the US naming conventions refer to the number of terminals.

ShapeShifter has it exactly correct!

For the moment I am just going to use a LED, a simple momentary button (to replicate the webpage) and a latching switch so when I have it working correctly I can add it my existing web server code and get want I want.

The closest thing I have seen so far is Paul__B's code, which I just a simple toggle.

What I would like to add is another input which is a latching switch. When the switch is switched the led is switched to the opposite of what is already is.

Is there a simple command to make an output to switch to the opposite state, i.e. if its on go off?

What I think I have to do is add some case's regarding the latching switch
Something like:

If latching switch has changed AND output is on, then:
output off.

If latching switch has changed AND output is off, then:
output on.

So I guess thats created another question can you use AND within if statements?

ShapeShifter had what I want exactly correct:

Initial conditions: relay is off, toggle switch is down
web page button is pressed: relay turns on
web page button is pressed: relay turns off
toggle switch is flipped up: relay turns on
web page button is pressed: relay turns off
toggle switch is flipped down: relay turns on
web page button is pressed: relay turns off
web page button is pressed: relay turns on
toggle switch is flipped up: relay turns off

TerryGould1991:
The closest thing I have seen so far is Paul__B's code, which I just a simple toggle.

Yes, it's very close. It should work just fine for your first button.

What I would like to add is another input which is a latching switch. When the switch is switched the led is switched to the opposite of what is already is.

A second copy of Paul's code will work for that, with the simple change I made above so that it returns true when it is stable in either position. It's tempting to just read the switch input directly, but you really do need "debouncing" logic like Paul's code provides. When you flip that toggle switch, the contacts open and close several times: it's too fast for you to notice it, but the Arduino is fast enough to be confused by it. It could toggle your output several times and you'd never know if it would settle on or off.

Is there a simple command to make an output to switch to the opposite state, i.e. if its on go off?

The logical NOT operator: !

It turns true to false and false to true; 0 to 1 and 1 to 0; HIGH to LOW and LOW to HIGH.

relayState = !relayState;

DigitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN));

That last one reads the relay out pin state (assuming RELAY_PIN is defined as a pin number) complements it, and writes it out. It directly toggles the output pin without having to remember its state.

What I think I have to do is add some case's regarding the latching switch
Something like:

If latching switch has changed AND output is on, then:
output off.

If latching switch has changed AND output is off, then:
output on.

So I guess thats created another question can you use AND within if statements?

Yes, it's the logical AND operator: &&

if (switchChanged && (relayState == HIGH))
  // turn output off

ShapeShifter:
My understanding from reading the requirements is close to this. However, instead of pushbuttons, it sounds like he wants to use toggle switches. It sounds like one use case might be this:

  • Initial conditions: relay is off, toggle switch is down
  • web page button is pressed: relay turns on
  • web page button is pressed: relay turns off
  • toggle switch is flipped up: relay turns on
  • web page button is pressed: relay turns off
  • toggle switch is flipped down: relay turns on
  • web page button is pressed: relay turns off
  • web page button is pressed: relay turns on
  • toggle switch is flipped up: relay turns off

Basically, pressing the web button toggles the relay, and changing the switch state toggles the relay. This is almost the same as Paul's provided example, except that his example would require the switch to be turned on then turned off to toggle the output. In this case, sometimes flipping the switch up turns on the relay, sometimes it turns it off -- it all depends on the previous state of the relay. Just like a hallway light controlled by a switch on either end: sometimes flipping a switch up turns it on, and sometimes it turns it off -- it all depends on the position of the switch at the other end of the hall.

The change to do the above use case is simple. In Paul's code is a state machine to debounce the mechanical switch contacts (an important consideration!) the butndown() function only returns true when the button has been up long enough to be stable (case 2, where butnstate is set to 1.) To make it work with a latching switch, it also needs to return true when the button has been down long enough to be stable (case 3, just after butnstate is set to 0.)

Basically, any time the switch has reached a stable state different from the previous stable state, toggle the output.
Precisely. The US terminology comes from the number of connections on the switch, not the number of switches in the circuit or the number of positions on the switch (they are always two positions.)

A 2-way switch has two screw terminals. It is an SPST switch. It is used as a standard single switch.

A 3-way switch has three screw terminals. It is an SPDT switch. It is used in pairs where two switches are to control one load.

A 4-way switch has four screws. It is a DPDT switch internally wired as a reversing switch, where the two redundant connections are not brought out (the two common DPDT terminals are one pair of screws, the two NC contacts are brought out as the other pair of screws, and the NO contacts are internally wired to the NC contacts in a crossover manner.) This switch is used with a pair of 3-way switches when three or more switches are to control one load.

The UK naming conventions refer to the number of switches, while the US naming conventions refer to the number of terminals.

In the UK, what you call a 4 way switch is called a crossover switch. Both the others are referred to by the number of ways the switch can be ON, so a SPST is a one way switch and a SPDT is a two way switch. The circuit, as a whole, is called by the number of switches. A three way circuit would be two two way switches and a crossover switch.

ShapeShifter:
The change to do the above use case is simple. In Paul's code is a state machine to debounce the mechanical switch contacts (an important consideration!) the butndown() function only returns true when the button has been up long enough to be stable (case 2, where butnstate is set to 1.) To make it work with a latching switch, it also needs to return true when the button has been down long enough to be stable (case 3, just after butnstate is set to 0.)

Yep. You got it. You can make different versions of the function to choose what you want; it is deliberately versatile and modular.

You can look for switch down, switch up, or either. You can use two versions of the same code together, one to look for switch down, one to look for switch up. Or one version with a number - 0, 1 or 2 as the exit status.

The important thing is that it is inline, not "blocking".

Paul__B:
Yep. You got it. You can make different versions of the function to choose what you want; it is deliberately versatile and modular.

I have a similar debounce routine that I reuse for everything. It returns an enumerated type to indicate active, idle, or noChange. Active or idle are returned when the input becomes stable in a new state, and noChange otherwise. That way, one version of the code works in any situation: it's up to the caller to decide if it will look for idle, active, or both. It works well: I've reused it a lot, and haven't had to make changes for a while now.

I've even used it to debounce "logical" inputs: I had a project where I had to receive messages from another processor which sent them periodically and often. Certain bits in the fixed format message controlled certain functions: but I should only act on that function until I see the same bit set three times in a row: this was a perfect application for the debounce routine. Worked great.

Right so I've been away for a while so only just got back into this.

I've been struggling merging Paul__B's code into my existing code, my plan was to just get the two programs working in the same sketch separately then get the two working together but when I try to merge the two nothing works.

I've read Demo of merging the code from two sketches - Programming Questions - Arduino Forum and various others but because there's code before the setup this is confusing me and I also think its because the two functions aren't happening at the same time, which I don't know how to do.

This is where you discover how small my coding knowledge is!

Could you help me to either merge the two codes or find a better solution to add a physical latching switch that toggles the output?

Here is my attempt at merging the two:

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

// **** From Ethernet V2 ****
// Ethernet library configuration
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  //physical mac address
byte ip[] = { 192, 168, 1, 123 };                     // ip in lan
byte gateway[] = { 192, 168, 1, 1 };                  // internet access via router
EthernetServer server(80);                            //server port

// HMTL processing variables
String readString = "";             //string to get incoming data
char c;
char buffer[10];
int dataLength =0;

// Buffer containing processed hmtl data
char data[50];
char datamotor[5];
int  index=3;
int LEDpin =    4;
int LEDval=0;

// **** From Buttontoggle ****
const int led1Pin =  13;
const int button1 =  10;
int led1State = LOW;
char bstate1 = 0;
unsigned long bcount1 = 0;

boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}



// **** Setup function From EthernetV2 ****
void setup()
{
    Ethernet.begin(mac, ip, gateway);
    Serial.begin(9600);
    pinMode(LEDpin, OUTPUT);
    
    pinMode(led1Pin, OUTPUT);      
    pinMode(button1, INPUT);      
    digitalWrite(button1,HIGH);
}


void loop() {
 ethernet();
 buttontoggle();
}



void ethernet() {
 EthernetClient client = server.available();
  if (client)
  {
     while (client.connected())
     {
        while (client.available())  // Receive client data
        {
          Serial.print(".");
          c = client.read();   //read char by char HTTP request
          readString +=c;
 
          if( readString.equals("GET"))
          {
            Serial.println("");
            Serial.println("GET caught, skipping request and printing HTML");
            break;
          }

          if( readString.equals("POST"))
          {
            Serial.println("");
            Serial.println("POST caught, skipping header and acquiring DATA");
            for(int i=0; i<320; i++)
            {
              c = client.read();
              //Serial.print(c); // UNCOMMENT FOR DEBUG
            }
            //Searches for "Length: "
            while(c  != 'L')
            {              
              c = client.read();
              //Serial.print(c); // UNCOMMENT FOR DEBUG
            }
            // Skip "Length: "
            for (int i=0; i<7; i++)
            {
              c = client.read();
              //Serial.print(c); // UNCOMMENT FOR DEBUG
            }
            
            // Read the data package length
            readString="";
            c = client.read();
            
            while(c != '\n')
            {
              readString += c;
              //Serial.print(c);
              c = client.read();   
            }
            
            // convert data read from String to int
            readString.toCharArray(buffer, readString.length());
            dataLength = atoi(buffer);
            Serial.println("");
            Serial.print("dataLength: ");
            Serial.println(dataLength);
            
            // gets DATA
            client.read(); // skips additional newline
            client.read();
            for (int i=0; i<dataLength; i++)
            {
              data[i] = client.read();
            }
            
            Serial.println("");
            Serial.print("data: ");
            Serial.println(data);
            readString ="";
            
             // Handle data
            // Sort cases depending on the first 2 characters
            
            char tempbuff[3];
            tempbuff[0] = data[0];
            tempbuff[1] = data[1];
            switch (atoi(tempbuff)) //convert to int
            {
              case 1:
              Serial.println("In case 1");
              if (LEDval == 0)
              {LEDval =1;}
              else
              {LEDval=0;}
              digitalWrite(LEDpin, LEDval);
              Serial.print("LED status: ");
              Serial.println(LEDval);              
              break;             
            }
            Serial.println("Out of switch");
          }        
        }
       
        // ***************************************************************HTML CODE**********************************************
        client.println(" <!DOCTYPE html>");
        client.println("<html xmlns= \"http://www.w3.org/1999/xhtml\">");
        client.println("<title>Domutek Power Automation</title>");
        client.println("<style type=\"text/css\">\n"
          "<!--\n"
          ".body {\n"
  " background-color: #00F;}\n"
          " -->\n"
          "</style>");
        
            client.println("</head>");
            client.println("<body class=\"body\">");
            client.println("<font color=black><h1 align=center>Terry Gould Test</font></h1>");
            client.println("<hr />");
            client.println("<dd><dd><dd>");
            
            if(LEDval == 1)
              {client.println("<img src=\"http://img688.imageshack.us/img688/4420/greencw.png\" width=20 height=20 />");}
            if(LEDval == 0)
              {client.println("<img src=\"http://img507.imageshack.us/img507/8505/blackko.png\" width=20 height=20 />");}
              
            client.println("<dd><dd><dd>");
            client.println("<form name=input method=post>");
            client.println("<input type=hidden name=01 />");
            client.println("<input type=submit value=\"      LED      \"  />");
            client.println("</form> 
");
            
            client.println("</body>");
            client.println("</html>");      
            Serial.println("__________");
            delay(100);       
            client.stop();     
     }
  }
   
  // Reinitializing variables
  readString ="";          // Reinitialize String
  for (int i=0; i<10; i++)
    {buffer[i] = '\0';}
  for (int i=0; i<50; i++)
    {data[i] = '\0';}
  for (int i=0; i<5; i++)
    {datamotor[i] = '\0';}
  dataLength =0;
  index = 3; 
}

//*******************************************
void buttontoggle() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (led1State == LOW) {
      led1State = HIGH;
    }
    else {
      led1State = LOW; 
    } 
    digitalWrite(led1Pin, led1State);
  } 
}

and here is my ethernet control code which works fine:

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

// Ethernet library configuration
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  //physical mac address
byte ip[] = { 192, 168, 1, 123 };                     // ip in lan
byte gateway[] = { 192, 168, 1, 1 };                  // internet access via router
EthernetServer server(80);                            //server port

// HMTL processing variables
String readString = "";
char c;
char buffer[10];
int dataLength =0;

// Buffer containing processed hmtl data
char data[50];
char datamotor[5];
int  index=3;
int LEDpin =    4;
int LEDval=0;
int lengthRead;
int dataRead;
int i = 3;
int x = 0;
int dataProc = 0;
int colourPass = 0;
int thingy = 0;

// Setup function
void setup()
  {Ethernet.begin(mac, ip, gateway);
    Serial.begin(9600);
    
    // Arduino controls initialization
    pinMode(LEDpin, OUTPUT);
    
}

// Loop function
void loop()
{EthernetClient client = server.available();
  if (client)
  {while (client.connected())
     {while (client.available())
      {lengthRead = 0;
        dataRead = 0;
        c = client.read();   //read char by char HTTP request
        readString +=c;
        if( readString.equals("GET"))
        {delay(10);
          break;}

        if( readString.equals("POST"))
        {while(!lengthRead)
          {c = client.read();
            if (c == 10)
            {while(c != 13) //for each new line, create a string to process
              {c = client.read();
                readString += c;

                if (readString.substring(8)=="L") //When the line has Content-Length: in it
                {while (c != 13) //Keep reading until EOL otherwise it only pulls in Content-L
                  {c = client.read();
                    readString += c;}
                  String a="";
                  a = readString.substring(16,readString.length()); //a = data length

                    a.toCharArray(buffer, a.length());
                  dataLength = atoi(buffer);
                  lengthRead = 1;}
              }
              readString="";}
          }
          
          readString ="";
          while(!dataRead) //Determine that youve hit the last line of the POST header before the data.
          {c = client.read();
            //Serial.print(c);
            if (c==10)
            {c = client.read();
              if (c==13)
              {c = client.read(); //read last NewLine
                dataRead = 1; }
            } 
          }
          
          for (int i=0; i<dataLength; i++)
            {data[i] = client.read();}
         
          readString ="";
               
   // Handle data
            char tempbuff[3];
            tempbuff[0] = data[0];
            tempbuff[1] = data[1];
            switch (atoi(tempbuff)) //convert to int
            {case 1:
               Serial.println("In case 1");
               if (LEDval == 0)
               {LEDval =1;}
               else
               {LEDval=0;}
               digitalWrite(LEDpin, LEDval);
               Serial.print("LED status: ");
               Serial.println(LEDval);              
               break;
}
            
            Serial.println("Out of switch");}        
        }
        
        // ***************************************************************HTML CODE**********************************************
        client.println(" <!DOCTYPE html>");
        
        client.println("<style type=\"text/css\">\n"
          "<!--\n"
            ".body {\n"
    " background-color: #00F;}\n"
         " -->\n"
        "</style>");
        
        client.println("</head>");

      client.println("<body class=\"body\">");
      
          client.println("<font color=black><h1 align=center>Terry Gould Test</font></h1>");
          client.println("<hr />");
            
            client.println("<dd><dd><dd>");
            
            if(LEDval == 1)
              {client.println("<img src=\"http://img688.imageshack.us/img688/4420/greencw.png\" width=20 height=20 />");}
              
              if(LEDval == 0)
              {client.println("<img src=\"http://img507.imageshack.us/img507/8505/blackko.png\" width=20 height=20 />");}
              
               client.println("<dd><dd><dd>");
            
            client.println("<form name=input method=post>");
              client.println("<input type=hidden name=01 />");
              client.println("<input type=submit value=\"      LED      \"  />");
            client.println("</form> 
");
            
          client.println("</body>");
        client.println("</html>");
       
        Serial.println("__________");
        delay(100);
        
        client.stop();}
  }
 
  // Reinitializing variables
  readString ="";          // Reinitialize String
  for (int i=0; i<10; i++)
    {buffer[i] = '\0';}
  for (int i=0; i<50; i++)
    {data[i] = '\0';}
  for (int i=0; i<5; i++)
    {datamotor[i] = '\0';}
  dataLength =0;
  index = 3;
 
}