Using a push button switch in an web page on an SD card

I'm trying to create an extremely simple web page that basically has a single button on it. When the button is pressed on the web page it will act the same as if I were to have physically pushed it.

I've been going through the tutorials in Startingelectronics Arduino Webserver Input and Output, but I am getting lost between learning programming with Aurduino and then trying to learn and integrate that with AJAX, HTML, and Javascipt... :astonished:

In his tutorials he has what I want in Tutorial #7, but unfortunately this tutorial is not using the SD card. I just don't have enough understanding to make the connection between doing this without the SD card to using the SD card. If anyone has done this then I would be very appreciate showing me how to do this.

I can post my code for both the Arduino program and the webpage, but I basically inserted my original working code into his "web server" program and the HTML is his original code since everything I have tried so far hasn't worked.

Single click controls on a web page are easy. Below is server code that uploads html and other files from the SD disk, and acts on input from the web pages to control servos. You can develop your desired web page on your desktop, then put it on your SD card.

//zoomkat 1/26/13
//SD server slider test code
//open serial monitor to see what the arduino receives
//address will look like http://192.168.1.102:84/servosld.htm when submited
//for use with W5100 based ethernet shields
//put the servosld.htm, slider.js, bluev_sl.gif,
//and bluev_bg.gif on the SD card
//files at http://web.comporium.net/~shb/servoslider.htm 
// http://web.comporium.net/~shb/pix/servosld.htm
// http://web.comporium.net/~shb/pix/slider.js
// http://web.comporium.net/~shb/pix/bluev_bg.gif
// http://web.comporium.net/~shb/pix/bluev_sl.gif


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

#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 
Servo myservoe, myservof, myservog;
String readString, pos;

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

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

void setup(){

  Serial.begin(9600);

  // disable w5100 while setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

  Ethernet.begin(mac, ip, gateway, gateway, subnet);

  //delay(2000);
  server.begin();
  Serial.println("Ready");
  
  myservoa.attach(2);  //the pin for the servoa control
  myservob.attach(3);  //the pin for the servob control
  myservoc.attach(5);  //the pin for the servoc control
  myservod.attach(6);  //the pin for the servod control 
  myservoe.attach(7);  //the pin for the servoa control
  myservof.attach(8);  //the pin for the servob control
  myservog.attach(9);  //the pin for the servoc control
  //myservoh.attach(10);  //the pin for the servod control 

}

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
         
         //select proper header for file to be sent to browser
           if(readString.indexOf("Submit") >=0) { //don't send new page
           client.println("HTTP/1.1 204 Zoomkat");
           client.println();
           client.println(); }
           
          //client.println("HTTP/1.1 200 OK"); //send new page
          if(readString.indexOf("servosld") >=0) {
          client.println("HTTP/1.1 200 OK"); //send new page          
          client.println("Content-Type: text/html");
          client.println(); }

          if(readString.indexOf("slider") >=0) {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: application/x-javascript");
          client.println(); }
          
          if(readString.indexOf("bluev") >=0) {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: image/gif");
          client.println(); }
          
          //select file to send to browser
          if(readString.indexOf("servosld") >=0) {
            File myFile = SD.open("SERVOSLD.HTM");
            if (myFile) {
              while (myFile.available()) {
                client.write(myFile.read());
              }
              myFile.close();
            }
          }

          if(readString.indexOf("slider") >=0) {
            File myFile = SD.open("slider.js");
            if (myFile) {
              while (myFile.available()) {
                client.write(myFile.read());
              }
              myFile.close();
            }
          }

          if(readString.indexOf("bluev_sl") >=0) {
            File myFile = SD.open("bluev_sl.gif");
            if (myFile) {
              while (myFile.available()) {
                client.write(myFile.read());
              }
              myFile.close();
            }
          }

          if(readString.indexOf("bluev_bg") >=0) {
            File myFile = SD.open("bluev_bg.gif");
            if (myFile) {
              while (myFile.available()) {
                client.write(myFile.read());
              }
              myFile.close();
            }
          }

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

          //process GET string request from client and and position servo
          
          pos = readString.substring(8, 12); //get the first four characters         
          //Serial.println(pos);
          int n = pos.toInt();  //convert readString into a number   
          Serial.println(n); 
          Serial.println();
          
          if(readString.indexOf("?0") >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf("?1") >0) myservob.writeMicroseconds(n);
          if(readString.indexOf("?2") >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf("?3") >0) myservod.writeMicroseconds(n);
          if(readString.indexOf("?4") >0) myservoe.writeMicroseconds(n);
          if(readString.indexOf("?5") >0) myservof.writeMicroseconds(n);
          if(readString.indexOf("?6") >0) myservog.writeMicroseconds(n);
          //only seven servo pins, so back to myservoa for testing
          if(readString.indexOf("?7") >0) myservoa.writeMicroseconds(n);

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

Thanks zoomkat.

From the webpage I was able to fumble around and get a checkbox and button to turn on a light, but for some reason when I change the pins from an LED to a motor then then the webpage part stops working. I know the code is being ran because I can see the text in the serial monitor when I push the button.

This is the relevant code I have for the Arudino:

void SetLEDs(void)
{
    // LED 1 (pin 6)
    if (StrContains(HTTP_req, "LED1=1")) {
        LED_state[0] = 1;  // save LED state
        digitalWrite(redScan, HIGH);
        Serial.println("This is high for Checkbox");
    }
    else if (StrContains(HTTP_req, "LED1=0")) {
        LED_state[0] = 0;  // save LED state
        digitalWrite(redScan, LOW);
        Serial.println("This is low for Checkbox");
    }
 
    // LED 3 (pin 8)
    if (StrContains(HTTP_req, "LED3=1")) {
        LED_state[2] = 1;  // save LED state
        digitalWrite(redScan, HIGH);
        Serial.println("This is high for checkbox");
    }
    else if (StrContains(HTTP_req, "LED3=0")) {
        LED_state[2] = 0;  // save LED state
        digitalWrite(redScan, LOW);
        Serial.println("This is low for checkbox");
    }
}

And this is the code I have for the webpage:

<!DOCTYPE html>
<html>
    <head>
        <title>Test</title>
        <script>
		strLED1 = "";
		strLED3 = "";
		var LED3_state = 0;
		function GetArduinoIO()
		{
			nocache = "&nocache=" + Math.random() * 1000000;
			var request = new XMLHttpRequest();
			request.onreadystatechange = function()
			{
				if (this.readyState == 4) {
					if (this.status == 200) {
						if (this.responseXML != null) {
							// XML file received - contains analog values, switch values and LED states
							var count;
							// get analog inputs
							var num_an = this.responseXML.getElementsByTagName('analog').length;
							for (count = 0; count < num_an; count++) {
								document.getElementsByClassName("analog")[count].innerHTML =
									this.responseXML.getElementsByTagName('analog')[count].childNodes[0].nodeValue;
							}
							// get switch inputs
							var num_an = this.responseXML.getElementsByTagName('switch').length;
							for (count = 0; count < num_an; count++) {
								document.getElementsByClassName("switches")[count].innerHTML =
									this.responseXML.getElementsByTagName('switch')[count].childNodes[0].nodeValue;
							}
							// LED 1
							if (this.responseXML.getElementsByTagName('LED')[0].childNodes[0].nodeValue === "checked") {
								document.LED_form.LED1.checked = true;
							}
							else {
								document.LED_form.LED1.checked = false;
							}
							// LED 3
							if (this.responseXML.getElementsByTagName('LED')[2].childNodes[0].nodeValue === "on") {
								document.getElementById("LED3").innerHTML = "LED 3 is ON (D8)";
								LED3_state = 1;
							}
							else {
								document.getElementById("LED3").innerHTML = "LED 3 is OFF (D8)";
								LED3_state = 0;
							}
						}
					}
				}
			}
			// send HTTP GET request with LEDs to switch on/off if any
			request.open("GET", "ajax_inputs" + strLED1 + strLED3 + nocache, true);
			request.send(null);
			setTimeout('GetArduinoIO()', 1000);
			strLED1 = "";
			strLED3 = "";
		}
		// service LEDs when checkbox checked/unchecked
		function GetCheck()
		{
			if (LED_form.LED1.checked) {
				strLED1 = "&LED1=1";
			}
			else {
				strLED1 = "&LED1=0";
			}
		}
		function GetButton1()
		{
			if (LED3_state === 1) {
				LED3_state = 0;
				strLED3 = "&LED3=0";
			}
			else {
				LED3_state = 1;
				strLED3 = "&LED3=1";
			}
		}
	</script>
	<style>
		.IO_box {
			float: left;
			margin: 0 20px 20px 0;
			border: 1px solid blue;
			padding: 0 5px 0 5px;
			width: 120px;
		}
		h1 {
			font-size: 120%;
			color: blue;
			margin: 0 0 10px 0;
		}
		h2 {
			font-size: 85%;
			color: #5734E6;
			margin: 5px 0 5px 0;
		}
		p, form, button {
			font-size: 80%;
			color: #252525;
		}
	</style>
    </head>
    <body onload="GetArduinoIO()">
        <h1>Test 2</h1>
		<div class="IO_box">
			<h2>LEDs Using Checkboxes</h2>
			<form id="check_LEDs" name="LED_form">
				<input type="checkbox" name="LED1" value="0" onclick="GetCheck()" />LED 1 (D6)


			</form>
		</div>
		<div class="IO_box">
			<h2>LEDs Using Buttons</h2>
			<button type="button" id="LED3" onclick="GetButton1()">LED 3 is OFF (D8)</button>


		</div>
    </body>
</html>

Below is some combined client/server test code that has some different types of control buttons.

//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 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
EthernetClient client;
char serverName[] = "checkip.dyndns.com"; // (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 

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

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  pinMode(6, OUTPUT); //pin selected to control
  pinMode(7, OUTPUT); //pin selected to control
  pinMode(8, OUTPUT); //pin selected to control

  //pinMode(5, OUTPUT); //pin 5 selected to control
  Ethernet.begin(mac,ip,gateway,gateway,subnet); 
  server.begin();
  Serial.begin(9600); 
  Serial.println(F("server/client 1.0 test 7/03/12")); // keep track of what is loaded
  Serial.println(F("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();

        //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.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("<H1>Zoomkat's simple Arduino 1.0 button</H1>"));

            // 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();

          ///////////////////// control arduino pin
          if(readString.indexOf('2') >0)//checks for 2
          {
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println("Led 5 On");
            Serial.println();
          }
          if(readString.indexOf('3') >0)//checks for 3
          {
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Led 5 Off");
            Serial.println();
          }
          if(readString.indexOf('4') >0)//checks for 4
          {
            digitalWrite(6, HIGH);    // set pin 6 high
            Serial.println("Led 6 On");
            Serial.println();
          }
          if(readString.indexOf('5') >0)//checks for 5
          {
            digitalWrite(6, LOW);    // set pin 6 low
            Serial.println("Led 6 Off");
            Serial.println();
          }
          if(readString.indexOf('6') >0)//checks for 6
          {
            digitalWrite(7, HIGH);    // set pin 7 high
            Serial.println("Led 7 On");
            Serial.println();
          }
          if(readString.indexOf('7') >0)//checks for 7
          {
            digitalWrite(7, LOW);    // set pin 7 low
            Serial.println("Led 7 Off");
            Serial.println();
          }     
          if(readString.indexOf('8') >0)//checks for 8
          {
            digitalWrite(8, HIGH);    // set pin 8 high
            Serial.println("Led 8 On");
            Serial.println();
          }
          if(readString.indexOf('9') >0)//checks for 9
          {
            digitalWrite(8, 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(F("connected"));
    client.println(F("GET / HTTP/1.1"));
    client.println(F("Host: checkip.dyndns.com"));
    client.println(F("Connection: close"));
    client.println();
  } 
  else {
    Serial.println(F("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(F("disconnecting."));
  Serial.println(F("=================="));
  Serial.println();
  client.stop();

}

Thanks again for the code.

With your latest code, I was able to get motors spinning, and servos twisting! :smiley: