How to load html buttons from external page to control arduino

Hi, i have the following code on a Arduino Uno Rev3. I have nearly run out of memory and would like to know if i can get better usage out of the Arduino’s memory if i create and recall an external html page (on SD card of arduino ethernet Shield or from my webspace) which contains the html buttons that i use to control different features of my sketch.

The sketch checks internal and external temperature of my cat’s house and allows me to set a temperature inside the house using a little fan heater activated by a relay.

It also has the feature to send me telegram messages about the state of the sensors or other things i want to monitor.

It would be nice to avoid the use of an IFRAME for updating in realtime the readings of different sensors (external temp, internal temp and humid, light sensor, relay state). It would be nice to be able to update in realtime only the changed values. I read it can be done with ajax but i don’t know how and i’ve seen some examples but seems complicated to me for what i’m actually doing.

Any suggestion is greatly apreciated, i’m trying to get performance and stability and memory.

Here the code in attachment.

aaa.ino (35.5 KB)

You can upload a large web page from the SD card and it will behave like a regular web page. You can have a static web page most anywhere, but the control links in the page need to have the full URL as the browser will not know the IP address of the arduino.

marcomaroso: It would be nice to avoid the use of an IFRAME for updating in realtime the readings of different sensors (external temp, internal temp and humid, light sensor, relay state). It would be nice to be able to update in realtime only the changed values. I read it can be done with ajax but i don't know how and i've seen some examples but seems complicated to me for what i'm actually doing.

If you want to do things like this, then you will need to come to grips with programming in JavaScript. There are a variety of frameworks and libraries that make this easier, notably JQuery. You'll need to put the arduino aside for a couple of days, fire up a web browser and an IDE, and start fiddling.

I have an example in the playground WebServerJson demonstrating the use of AngularJS and JSON data.

I have nearly run out of memory

Yet you waste what you have on Strings and floats where integers are usually used. Hour as a float? Get real.

PaulS: Yet you waste what you have on Strings and floats where integers are usually used. Hour as a float? Get real.

In other words what does that mean? I have used the macro F for strings in html code, i have reduced string usage where i thought i could ... if you think i didn't , please tell me where so I can be better.

The hour as a float is and copy and paste of a working example, I infact wondered why was float used in hour timing function! Should i declare as integer the hours, minutes, seconds, ms ?

zoomkat:
You can upload a large web page from the SD card and it will behave like a regular web page. You can have a static web page most anywhere, but the control links in the page need to have the full URL as the browser will not know the IP address of the arduino.

THanks,but will i have to give the full path with the remote ip address or local ip address? I think the local unless i’m telling arduino to fetch the page from a remote storage host. Am i wrong?

But will i have to write simple html code or do i have to write it as it is right now as follows (for example)?

client.print(F("<HTML><HEAD>"));
            client.println(F("<meta name='mobile-web-app-capable' content='yes' />"));
            client.println(F("<meta name='viewport' content='width=device-width, initial-scale=1.0' />"));
            client.print(F("<b>Marco's Cat's House Dashboard<b>
"));
            client.print(F("<table style='font-family:verdana; border-color: white; background-color: #ffffcc;' border='1' cellpadding='2' cellspacing='2'>"));
            
            client.println(F("<tr><td>"));
            client.print(F("<font size='1'>Temperatura Interna</font>
"));   
            client.println(F("<input type=button value='+' style=width:35px;height:35px onclick=location.href='/?+TempInt'>"));
            client.println(F("<input type=button value='-' style=width:35px;height:35px onclick=location.href='/?-TempInt'>"));
            client.println(F("<input type=button value='Rst' style=width:35px;height:35px onclick=location.href='/?rstSoglia'></td>"));

THanks,but will i have to give the full path with the remote ip address or local ip address? I think the local unless i’m telling arduino to fetch the page from a remote storage host. Am i wrong?

Below is some simple server code that demonstrates the embedding possibilities of URLs in web page code. Note that uploading directly from an F() macro can be very slow as apparently each character is sent individually.

//zoomkat 04-10-15
//simple button GET with iframe code
//open serial monitor to see what the arduino receives
//use the ' instead of " in html ilnes 
//address will look like http://192.168.1.102:84/ when submited
//for use with W5100 based ethernet shields

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

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //ethernet shield mac address
byte ip[] = { 
  192, 168, 1, 102 }; // arduino 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(4, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("server test no-ip 04-10-15"); // 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 

            //now output HTML data header
          if(readString.indexOf('?') >=0) { //don't send new page
            client.println("HTTP/1.1 204 Zoomkat\r\n\r\n");
          }
          else {
            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>Arduino GET test page</TITLE>");
            client.println("</HEAD>");
            client.println("<BODY>");

            client.println("<H1>Zoomkat's simple Arduino button</H1>");
            client.println("Arduino served LAN: <a href='/?on1' target='inlineframe'>ON</a>"); 
            client.println("<a href='/?off' target='inlineframe'>OFF</a>

"); 

            client.println("Remote served LAN: <a href='http://192.168.1.102:84/?on1' target='inlineframe'>ON</a>"); 
            client.println("<a href='http://192.168.1.102:84/?off' target='inlineframe'>OFF</a>

"); 

            client.println("Remote served no-ip: <a href='http://zoomkat.no-ip.org:84/?on1' target='inlineframe'>ON</a>"); 
            client.println("<a href='http://zoomkat.no-ip.org:84/?off' target='inlineframe'>OFF</a>"); 

            client.println("<IFRAME name=inlineframe style='display:none'>");          
            client.println("</IFRAME>");

            client.println("</BODY>");
            client.println("</HTML>");
          }

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

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

zoomkat:
Below is some simple server code that demonstrates the embedding possibilities of URLs in web page code. Note that uploading directly from an F() macro can be very slow as apparently each character is sent individually.

//zoomkat 04-10-15

//simple button GET with iframe code
//open serial monitor to see what the arduino receives
//use the ’ instead of " in html ilnes
//address will look like http://192.168.1.102:84/ when submited
//for use with W5100 based ethernet shields

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

byte mac = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //ethernet shield mac address
byte ip = {
  192, 168, 1, 102 }; // arduino 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(4, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

//enable serial data print
  Serial.begin(9600);
  Serial.println(“server test no-ip 04-10-15”); // 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

//now output HTML data header
          if(readString.indexOf(’?’) >=0) { //don’t send new page
            client.println(“HTTP/1.1 204 Zoomkat\r\n\r\n”);
          }
          else {
            client.println(“HTTP/1.1 200 OK”); //send new page
            client.println(“Content-Type: text/html”);
            client.println();

client.println("");
            client.println("");
            client.println(“Arduino GET test page”);
            client.println("");
            client.println("");

client.println(“

Zoomkat’s simple Arduino button

”);
            client.println(“Arduino served LAN: ON”);
            client.println("OFF

");

client.println(“Remote served LAN: ON”);
            client.println("OFF

");

client.println(“Remote served no-ip: ON”);
            client.println(“OFF”);

client.println("");

client.println("");
            client.println("");
          }

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

///////////////////// control arduino pin
          if(readString.indexOf(“on1”) >0)//checks for on
          {
            digitalWrite(4, HIGH);    // set pin 4 high
            Serial.println(“Led On”);
          }
          if(readString.indexOf(“off”) >0)//checks for off
          {
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println(“Led Off”);
          }
          //clearing string for next read
          readString="";
        }
      }
    }
  }
}

Thanks, so i tried what you posted and i understand.
I haven’t understood what i have to do id i want to access from remote or local network my arduino and give comands to it loading an interface of buttons from a page on a remote server (my own domain space).

How must the links look like in the remote buttons.html ?

		<tr>
			<td><b><b><font size="1">Temp.Esterna Minima</font>

			<input onclick="location.href='http://192.168.1.20/?+TempEstMin'" style="width:35px;height:35px" type="button" value="+" /> <input onclick="location.href='http://192.168.1.20/?-TempEstMin'" style="width:35px;height:35px" type="button" value="-" /> <input onclick="location.href='http://192.168.1.20/?rstTempEstMin'" style="width:35px;height:35px" type="button" value="Rst" /></b></b></td>
			<td><b><b><font size="1">Switch Riscaldamento</font>

			<input onclick="location.href='http://192.168.1.20/?mainOn'" style="width:35px;height:35px" type="button" value="On" /> <input onclick="location.href='http://192.168.1.20/?mainOff'" style="width:35px;height:35px" type="button" value="Off" /></b></b></td>
		</tr>

??

The below shouldl work on your LAN, but not from outside your LAN. For outside yourLAN you would need a static IP address or use one of the dynamic IP services (like bottom using no-ip) and port forwarding on your router that interfaces with the internet.

<input onclick="location.href='http://192.168.1.20/?+TempEstMin'
client.println("<a href='http://zoomkat.no-ip.org:84/?off' target='inlineframe'

Should i declare as integer the hours, minutes, seconds?

Yes, indeed, if your days include more than 255 hours, your hours include more than 255 minutes, and your minutes include more than 255 seconds.

PaulS: Yes, indeed, if your days include more than 255 hours, your hours include more than 255 minutes, and your minutes include more than 255 seconds.

I put it to integer and it stopped working showing strange charachters instead of numbers.

zoomkat:
The below shouldl work on your LAN, but not from outside your LAN. For outside yourLAN you would need a static IP address or use one of the dynamic IP services (like bottom using no-ip) and port forwarding on your router that interfaces with the internet.

<input onclick="location.href='http://192.168.1.20/?+TempEstMin'
client.println("<a href='http://zoomkat.no-ip.org:84/?off' target='inlineframe'

Thank you very much Zoomkat, i know that i need a static IP or a dns service to contact from outside.
I actually update my DNS at DtDns using this sketch of Arduino so i always have my IP updated everytime it changes.

What i haven’t understood is how to have my buttons retreived from the SD Card or from my website in the cloud. Let’s say we retreive the page from my website

I thought it could be possible to create an html page with my buttons and recall it in the arduino code …maybe as an IFRAME without border.

When i press a button on the page (let’s say the page is on my hosting (www.accessoriecaseperanimali.it/cathouse/buttons.html) the button gives the commands to the arduino.

i thought i could build the buttons.html page as follows :

<HTML><HEAD><meta name='mobile-web-app-capable' content='yes' />
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
<table style='font-family:verdana; border-color: white; background-color: #ffffcc;' border='1' cellpadding='2' cellspacing='2'><tr><td>
<font size='1'>Temp. Interna</font>
<input type=button value='+' style=width:30px;height:25px onclick=location.href='/?+TempInt'>
<input type=button value='-' style=width:30px;height:25px onclick=location.href='/?-TempInt'>
<input type=button value='R' style=width:30px;height:25px onclick=location.href='/?rstSoglia'></td>
<td><font size='1'>Allarme Temp.Int.
</font><input type=button value='+' style=width:30px;height:25px onclick=location.href='/?+TAllarme'>
<input type=button value='-' style=width:30px;height:25px onclick=location.href='/?-TAllarme'>
<input type=button value='R' style=width:30px;height:25px onclick=location.href='/?rstTAllarme'></td></tr>
<tr><td><font size='1'>Temp.Est. Min.
</font><input type=button value='+' style=width:30px;height:25px onclick=location.href='/?+TempEstMin'>
<input type=button value='-' style=width:30px;height:25px onclick=location.href='/?-TempEstMin'>
<input type=button value='R' style=width:30px;height:25px onclick=location.href='/?rstTempEstMin'></td>
<td><font size='1'>Switch Risc.
</font><input type=button value='On' style=width:30px;height:25px onclick=location.href='/?mainOn'>
<input type=button value='Off' style=width:30px;height:25px onclick=location.href='/?mainOff'></td></tr>
<tr><td><font size='1'>Sensore Luce
</font><input type=button value='On' style=width:30px;height:25px onclick=location.href='/?sensLuceOn'>
<input type=button value='Off' style=width:30px;height:25px onclick=location.href='/?sensLuceOff'></td>
<td><font size='1'>Sirena Allarme
</font><input type=button value='On' style=width:30px;height:25px onclick=location.href='/?SirenaOn'>
<input type=button value='Off' style=width:30px;height:25px onclick=location.href='/?SirenaOff'>
<input type=button value='R' style=width:30px;height:25px onclick=location.href='/?rstContAllarme'></td></tr>
<tr><td><font size='1'>Invio Messaggi
</font><input type=button value='On' style=width:30px;height:25px onclick=location.href='/?sendTempOn'>
<input type=button value='Off' style=width:30px;height:25px onclick=location.href='/?sendTempOff'></td>
<td><font size='1'>Extra
</font><input type=button value='R' style=width:30px;height:25px onclick=location.href='/?reset'>
<input type=button value='15&deg;' style=width:30px;height:25px onclick=location.href='/?on15'>
<input type=button value='19&deg;' style=width:30px;height:25px onclick=location.href='/?on19'></td></tr>
</table>

Is that correct or do i have to change the buttons links in the buttons.html page as follows ?

<input type=button value='15&deg;' style=width:30px;height:25px onclick=location.href='http://192.168.1.20/?on15'>

Will the arduino code look as this ? :

client.print(F("<iframe src='http://accessoriecasepergatti.it/cathouse/buttons.htm' width='300' height='300' frameBorder='0' scrolling='no' name='home'>"));
            client.println("<IFRAME name=home style='display:none'>");          
            client.println("</IFRAME>");

Thanks in advance

Is that correct or do i have to change the buttons links in the buttons.html page as follows ?

So what happens when you try it?