Ethernet: Web page pulling info from arduino without reloading?

Can you use javascript or other browser scripting language to manage to pull information from the arduino perhaps via UDP or in some other way in order to dynamically update the info on your page without reloading???
Thanks in advanced for your help!
:slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile:

in order to dynamically update the info on your page

Dynamically update what info? If the info came from the Arduino in the first place, there is no way to get more data without asking the Arduino from it.

Well in my current setup , the arduino redirects to a php page and posts two variables which the php interprets. What i wanted to do was have a javascript send a UDP packet to the arduino, to which the arduino responds with another UDP packet containing the updated values. The page updates every second.

You may just need simple meta refresh code like below to have auto updated data.

// for W5100 ethernet shield
// the IP address will be dependent on your local network/router
// port 80 is default for HTTP, but can be changed as needed
// use IP address like http://192.168.1.102/ in your brouser

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

int x=0;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 102 };
Server server(80);

void setup()
{
  // start the server
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop()
{
  // listen for incoming clients
  Client client = server.available();
  if (client) {
     while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // see if HTTP request has ended with blank line
        if (c == '\n') {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          
          //meta-refresh page every 2 seconds
          x=x+1;
          client.print("<HEAD>");
          client.print("<meta http-equiv=\"refresh\" content=\"2\">");
          client.print("<TITLE />Zoomkat's meta-refresh test</title>");
          client.print("</head>");
          client.print("page refresh number ");
          client.println(x);
          client.println("
");
          client.println("
");
                             
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(analogRead(analogChannel));
            client.println("
");
            }
          break;
           }
        }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}

simeondorelov:
Well in my current setup , the arduino redirects to a php page and posts two variables which the php interprets. What i wanted to do was have a javascript send a UDP packet to the arduino, to which the arduino responds with another UDP packet containing the updated values. The page updates every second.

Interesting. I have been thinking along the exact same lines.

In order to be able to make the webpage much nicer looking, I would like to host the webpage on a server, and just populate some variables with live data from the arduino.
I thought it might be done by including an Iframe with a reloading page (meta refresh), which gets data from the arduino. Or maybe use the php include function.
-Still haven't found a good way to show live values from an arduino without having to reload the whole page periodically.

simeondorelov >> would you share your php code, and arduino sketch? -maybe we could make it work together! :.

My arduino is hooked up to an ethernet shield, a DHT22 temperature and humidity sensor and a piezo buzzer.
The sensor: http://www.sparkfun.com/products/10167

The page that the Arduino hosts is:

<html>
<body>
<form method="post" action="http://www.simeondorelov.com/" name="f">
<input type="hidden" name="t" value="temperature" />
<input type="hidden" name="h" value="humidity" />
</form>
<script type='text/javascript'>document.f.submit();</script>
</body>
</html>

This is the actual sketch:
It also features an LCD screen for debugging purposes.

#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Ethernet.h>
#include <DHT22.h>


byte mac[] = {  
  0x90, 0xA2, 0xDA, 0x00, 0x42, 0x3C };
byte ip[] = { 
  192,168,2,11 };
byte gateway[] = {
  192,168,2,1};	
byte subnet[] = { 
  255, 255, 255, 0 };

Server server(888);

LiquidCrystal_I2C lcd (0x27,16,2);
DHT22 s1(6);

float temperature = 0.0;
float humidity = 0;

void setup() {

  Ethernet.begin(mac, ip);
  server.begin();

  pinMode(9,OUTPUT);
  
  lcd.init();
  lcd.backlight();
  lcd.clear();
  delay(1000);
}

bool alarm=false;

void loop() { 
  
  s1.readData();
  lcd.clear();
  temperature = s1.getTemperatureC();
  lcd.setCursor(3,0);
  lcd.print("T: ");
  lcd.print(temperature);
  lcd.print(" C");
  humidity = s1.getHumidity();
  lcd.setCursor(2,1);
  lcd.print("RH: ");
  lcd.print(humidity);
  lcd.print(" %");
  if(alarm)
  {
  if(temperature>30||temperature<18)tone(9,800,100);
  else if(temperature>27||temperature<21){tone(9,800,100);delay(100);}
  else if(temperature>25.5||temperature<22.5){tone(9,800,100); delay(200);}
  }
  listenForClients();
  delay(100);
}

void listenForClients() {
  Client client = server.available();
  if (client) {
    tone(9,800,100);
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<html>");
          client.print("<body>");
          client.print("<form method=\"post\" action=\"http://www.simeondorelov.com/\" name=\"f\">");
          client.print("<input type=\"hidden\" name=\"t\" value=\"");
          client.print(temperature);
          client.println("\" />");
          client.print("<input type=\"hidden\" name=\"h\" value=\"");
          client.print(humidity);
          client.println("\" />");
          client.println("</form>");
          client.println("<script type='text/javascript'>document.f.submit();</script>");
          client.print("</body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);[color=black][color=black][/color][/color]
    client.stop();
  }
}

I am currently using my hosting service to run this page.
It uses RGraph which is a Javascript charts library, to represent the data.
Link: http://www.rgraph.net/

The Arduinos address is: http://78.83.16.143:888 And the domain of the site is: http://www.simeondorelov.com It s live right now.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php 
	if ($_POST["t"]==NULL) 
		{
			if ($_POST["t"]==NULL)echo '<meta http-equiv="refresh" content="0; url=http://78.83.16.143:888">';
		}
?>
<title>Air Condition</title>
<script src="RGraph.common.core.js"></script>
<script src="RGraph.meter.js"></script>
<script>
        window.onload = function ()
        {
			
            var temp = new RGraph.Meter('temp', 18, 30, <?php echo $_POST["t"]; ?>);
            
            var grad1 = temp.context.createLinearGradient(25,0,375,0);
            grad1.addColorStop(0, 'blue');
            grad1.addColorStop(1, 'red');
            
            temp.Set('chart.labels.position', 'inside');
            temp.Set('chart.title', 'Temperature');
            temp.Set('chart.title.vpos', 0.5);
            temp.Set('chart.title.color', 'black');
			temp.Set('chart.red.start', 0);
			temp.Set('chart.red.end', 0);
			temp.Set('chart.yellow.start', 0);
			temp.Set('chart.yellow.end', 0);
            temp.Set('chart.green.color', grad1);
			temp.Set('chart.green.start', 18);
			temp.Set('chart.green.end', 30);
            temp.Set('chart.border', false);
            temp.Set('chart.needle.linewidth', 5);
            temp.Set('chart.needle.tail', true);
            temp.Set('chart.tickmarks.big.num', 0);
            temp.Set('chart.tickmarks.small.num', 0);
            temp.Set('chart.segment.radius.start', 100);
            temp.Set('chart.needle.radius', 80);
            temp.Set('chart.needle.linewidth', 2);
            temp.Set('chart.linewidth.segments', 15);
            temp.Set('chart.strokestyle', 'white');
            temp.Draw();
			
			var rh = new RGraph.Meter('rh', 0, 100, <?php echo $_POST["h"]; ?>);
			
			var grad2 = rh.context.createLinearGradient(50,0,400,0);
            grad2.addColorStop(0, 'white');
            grad2.addColorStop(1, 'blue');
                     
            rh.Set('chart.labels.position', 'inside');
            rh.Set('chart.title', 'Humidity');
            rh.Set('chart.title.vpos', 0.5);
            rh.Set('chart.title.color', 'black');
			rh.Set('chart.red.start', -5);
			rh.Set('chart.red.end', -5);
			rh.Set('chart.yellow.start', -5);
			rh.Set('chart.yellow.end', -5);
			rh.Set('chart.green.color', grad2);
			rh.Set('chart.green.start', 0);
			rh.Set('chart.green.end', 100);
            rh.Set('chart.border', false);
            rh.Set('chart.needle.linewidth', 5);
            rh.Set('chart.needle.tail', true);
            rh.Set('chart.tickmarks.big.num', 0);
            rh.Set('chart.tickmarks.small.num', 0);
            rh.Set('chart.segment.radius.start', 100);
            rh.Set('chart.needle.radius', 80);
            rh.Set('chart.needle.linewidth', 2);
            rh.Set('chart.linewidth.segments', 15);
            rh.Set('chart.strokestyle', 'white');
            rh.Draw();
		}
</script>
</head>

<body>
<center><div>
<h1 style="color:#333">Air Condition</h1>


<div><canvas id="temp" width="400" height="250">[No canvas support]</canvas>
<?php echo $_POST["t"]; ?> °C</div>

<div><canvas id="rh" width="400" height="250">[No canvas support]</canvas>
<?php echo $_POST["h"]; ?> %</div>

<a href="http://78.83.16.143:888">
<input type="button" value="Refresh" src="http://78.83.16.143:888" /></a>
</div>
</center>
</body>
</html>

Using an Iframe is not a bad idea, in fact it works just fine and is very simple to implement, however I don`t like it because the updates are not seamless. it takes a second to reload the page, during which the frame is blank!

I updated the arduino and my server to refresh automatically via Iframe.
I`m still looking for a better option, but for now...

Here`s the sketch:

#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Ethernet.h>
#include <DHT22.h>

byte mac[] = {  
  0x90, 0xA2, 0xDA, 0x00, 0x42, 0x3C };
byte ip[] = { 
  192,168,2,11 };
byte gateway[] = {
  192,168,2,1};	
byte subnet[] = { 
  255, 255, 255, 0 };


Server server(888);

LiquidCrystal_I2C lcd (0x27,16,2);
DHT22 s1(6);

float temperature = 0.0;
float humidity = 0;

int clients=0;

void setup() {

  Ethernet.begin(mac, ip);
  server.begin();

  pinMode(9,OUTPUT);
  Serial.begin(9600);
  
  lcd.init();
  lcd.backlight();
  lcd.clear();
  delay(1000);
}

bool alarm=false;

void loop() { 
  
  s1.readData();
  lcd.clear();
  temperature = s1.getTemperatureC();
  lcd.setCursor(3,0);
  lcd.print("T: ");
  lcd.print(temperature);
  lcd.print(" C");
  humidity = s1.getHumidity();
  lcd.setCursor(2,1);
  lcd.print("RH: ");
  lcd.print(humidity);
  lcd.print(" %");
  if(Serial.available())
  {
    Serial.flush();
    Serial.println(clients);
  }
  if(alarm)
  {
  if(temperature>30||temperature<18)tone(9,800,100);
  else if(temperature>27||temperature<21){tone(9,800,100);delay(100);}
  else if(temperature>25.5||temperature<22.5){tone(9,800,100); delay(200);}
  }
  listenForClients();
  delay(100);
}
bool r=false;
void listenForClients() {
  Client client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if(c=='

This is the index of the server(index.php):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php 
	if($_POST["t"]==NULL)echo '<meta http-equiv="refresh" content="0; url=http://78.83.16.143:888">';
	if($_REQUEST["r"]==1)
		{
			if($_POST["t"]==NULL)echo '<meta http-equiv="refresh" content="0; url=http://78.83.16.143:888?r=$">';
			else echo '<meta http-equiv="refresh" content="2; url=http://78.83.16.143:888?r=$">';
		}
?>
<title>Air Condition</title>
<script src="RGraph.common.core.js"></script>
<script src="RGraph.meter.js"></script>
<script>
        window.onload = function ()
        {
			
            var temp = new RGraph.Meter('temp', 18, 30, <?php echo $_POST["t"]; ?>);
            
            var grad1 = temp.context.createLinearGradient(25,0,375,0);
            grad1.addColorStop(0, 'blue');
            grad1.addColorStop(1, 'red');
            
            temp.Set('chart.labels.position', 'inside');
            temp.Set('chart.title', 'Temperature');
            temp.Set('chart.title.vpos', 0.5);
            temp.Set('chart.title.color', 'black');
			temp.Set('chart.red.start', 0);
			temp.Set('chart.red.end', 0);
			temp.Set('chart.yellow.start', 0);
			temp.Set('chart.yellow.end', 0);
            temp.Set('chart.green.color', grad1);
			temp.Set('chart.green.start', 18);
			temp.Set('chart.green.end', 30);
            temp.Set('chart.border', false);
            temp.Set('chart.needle.linewidth', 5);
            temp.Set('chart.needle.tail', true);
            temp.Set('chart.tickmarks.big.num', 0);
            temp.Set('chart.tickmarks.small.num', 0);
            temp.Set('chart.segment.radius.start', 100);
            temp.Set('chart.needle.radius', 80);
            temp.Set('chart.needle.linewidth', 2);
            temp.Set('chart.linewidth.segments', 15);
            temp.Set('chart.strokestyle', 'white');
            temp.Draw();
			
			var rh = new RGraph.Meter('rh', 0, 100, <?php echo $_POST["h"]; ?>);
			
			var grad2 = rh.context.createLinearGradient(50,0,400,0);
            grad2.addColorStop(0, 'white');
            grad2.addColorStop(1, 'blue');
                     
            rh.Set('chart.labels.position', 'inside');
            rh.Set('chart.title', 'Humidity');
            rh.Set('chart.title.vpos', 0.5);
            rh.Set('chart.title.color', 'black');
			rh.Set('chart.red.start', -5);
			rh.Set('chart.red.end', -5);
			rh.Set('chart.yellow.start', -5);
			rh.Set('chart.yellow.end', -5);
			rh.Set('chart.green.color', grad2);
			rh.Set('chart.green.start', 0);
			rh.Set('chart.green.end', 100);
            rh.Set('chart.border', false);
            rh.Set('chart.needle.linewidth', 5);
            rh.Set('chart.needle.tail', true);
            rh.Set('chart.tickmarks.big.num', 0);
            rh.Set('chart.tickmarks.small.num', 0);
            rh.Set('chart.segment.radius.start', 100);
            rh.Set('chart.needle.radius', 80);
            rh.Set('chart.needle.linewidth', 2);
            rh.Set('chart.linewidth.segments', 15);
            rh.Set('chart.strokestyle', 'white');
            rh.Draw();
		}
</script>
</head>

<body>
<center><div>
<h1 style="color:#333">Air Condition</h1>


<div><canvas id="temp" width="400" height="250">[No canvas support]</canvas>
<?php echo $_POST["t"]; ?> °C</div>

<div><canvas id="rh" width="400" height="250">[No canvas support]</canvas>
<?php echo $_POST["h"]; ?> %</div>
<?php
	if($_REQUEST["r"]!=1)echo '
<a href="http://78.83.16.143:888"><input type="button" value="Refresh" src="http://78.83.16.143:888" /></a>

			   <a href="ar.html"><input type="button" value="Auto Refresh" src="ar.html" /></a>';
?>
</div>
</center>
</body>
</html>

And this is the Auto Refresh page (ar.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Air Condition</title>
</head>

<body>
<center>
<iframe height="670" width="600" src="http://78.83.16.143:888?r=$" style="border:none">
</iframe>

<a href="index.php"><input type="button" value="Stop" src="index.html" /></a>
</center>
</body>
</html>

)r++;
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("");
          client.print("");
          client.print("<form method="post" action="http://www.simeondorelov.com/\" name="f">");
          client.print("<input type="hidden" name="t" value="");
          client.print(temperature);
          client.println("" />");
          client.print("<input type="hidden" name="h" value="");
          client.print(humidity);
          client.println("" />");
    if(r)client.print("<input type="hidden" name="r" value="1" />");
          client.println("");
          client.println("");
          client.print("");
          client.println("");
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    if(!r)
    {
      clients++;
      tone(9,800,100);
    }
    r=false;
    delay(1);
    client.stop();
  }
}


This is the index of the server(index.php):

§DISCOURSE_HOISTED_CODE_1§


And this is the Auto Refresh page (ar.html):

§DISCOURSE_HOISTED_CODE_2§

simeondorelov:
Well in my current setup , the arduino redirects to a php page and posts two variables which the php interprets. What i wanted to do was have a javascript send a UDP packet to the arduino, to which the arduino responds with another UDP packet containing the updated values. The page updates every second.

Not sure why you'd want to try getting User Datagram Protocol going, when HTTP over TCP/IP is already implemented. The tech you're looking for, I think, is AJAX, or something closely resembling that.

The thing is im not really good at web design and scripting and dont really know how to do it over TCP/IP, but if you do please share.

If you're already serving pages, then you're already doing HTTP over TCP/IP. I don't care much for excessive JavaScript myself, I just know that AJAX is in heavy use on the WWW to do exactly what you're describing. So why mess with UDP when the TCP/IP stack is right there, implemented, and a webserver too?

Simple iframe page obtaining info from my arduino (I'll leave the arduino on line for a while). To test, copy the code, paste in notepad, save on desktop as arduino.htm, then double click. You will probably get a warning about running a web page from the desktop, just click allow. This down loads the meta refresh page from my arduino and displays it in the frame box. The BOOM! shows how data input to the box can be easily switched to another source. Click the arduino/boom selections over the box to switch input.

<HTML>
<HEAD>
<TITLE>Zoomkat's arduino test</TITLE>
</HEAD>
Zoomkat's arduino meta refresh test 9/13/11






Get data from arduino:



|<a href="http://zoomkat.no-ip.com:84/" target="DataBox" title="'SSC-32 

version'">Arduino</a>|


<a href="http://www.yourhtmlsource.com/examples/inlineframes3.html" target="DataBox" 

title="'Someone set us up the bomb'">BOOM!</a>|


 
<iframe src="http://zoomkat.no-ip.com:84/" width="30%" height="200" name="DataBox">
</iframe>



</HTML>

justjed:
... I just know that AJAX is in heavy use on the WWW to do exactly what you're describing...

Aahhh, yes.
searched around a bit, and found some interesting jQuery script, that will do what we are looking for.
I hope it will be a lot smoother than the old iFrame approach, which I also find a bit clunky! :wink:

Although my approach is a bit different.
I would not host the webpage on the arduino, and redirect to a php page on a server. Rather, I would create a php page on my server, and have it fetch the live values from the arduino.
That way, I assume to keep it as light as possible on the arduino side, and will be able to make all the fancy stuff happening server-side.

With the above approach, I managed to hack together something that seems to work:
index.php

<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
 $(document).ready(function() {
 	 $("#responsecontainer").load("response.php");
   var refreshId = setInterval(function() {
      $("#responsecontainer").load('response.php?randval='+ Math.random());
   }, 5000);
   $.ajaxSetup({ cache: false });
});
</script>
</head>
<body>

<div id="responsecontainer">
</div>
</body>

response.php

<?php
$remote = fopen("http://api.thingspeak.com/channels/9/field/1/last.txt?append=%20%C2%B0C", "r");
fpassthru($remote);
?>

From this page:
http://www.brightcherry.co.uk/scribbles/2009/02/26/jquery-auto-refresh-div-every-x-seconds/

And modified it, so it will take a value from an external webpage, and show it:
http://tycoontalk.freelancer.com/php-forum/9065-using-php-embed-one-webpage-into.html

I have a little test running on my webserver (privately hosted, so may be a bit slow):
http://keis.dyndns.dk/jq/
In my test, I fetch the latest value every 5 seconds from the ThingSpeak 'Dynamic Light Level' chart on the ThingSpeak.com front page.

Some more links i looked through:
http://en.kioskea.net/faq/1449-php-5-using-an-external-url-with-the-function-include

spumanti:
searched around a bit, and found some interesting jQuery script, that will do what we are looking for.
I hope it will be a lot smoother than the old iFrame approach, which I also find a bit clunky! :wink:

Although my approach is a bit different.
I would not host the webpage on the arduino, and redirect to a php page on a server. Rather, I would create a php page on my server, and have it fetch the live values from the arduino.
That way, I assume to keep it as light as possible on the arduino side, and will be able to make all the fancy stuff happening server-side.

That is how I would approach it. Of course, I've been running Apache on my home box for years, so it's not a big thing for me.

searched around a bit, and found some interesting jQuery script, that will do what we are looking for.
I hope it will be a lot smoother than the old iFrame approach, which I also find a bit clunky!

The old iframe probably can operate solely from an arduino with an ethernet shield. The new fancy approach appears to involve external servers running on PCs or better and a third party site to get a java component. Getting complicated. :wink:

zoomkat:
The old iframe probably can operate solely from an arduino with an ethernet shield. The new fancy approach appears to involve external servers running on PCs or better and a third party site to get a java component. Getting complicated. :wink:

AJAX uses JavaScript. I suppose on the server side, there is some packaged up JSP stuff to speak XML, but for simple stuff, or even complex stuff, you could use PHP, or Perl, or even Haskell if you wanted. jQuery, IIRC, isn't specifically an AJAX thing, though I haven't looked for a while, so I wouldn't be surprised if that's been added. However, the idea of AJAX could be implemented for simpler operations without bringing in a bunch of pre-packaged libraries. The main thing jQuery brings is a set of methods for reading and operating on items in the DOM at the browser. (And probably lots of other stuff too. I just know about it -- haven't tried to use it.)

zoomkat:
...The new fancy approach appears to involve external servers running on PCs or better and a third party site to get a java component. Getting complicated. :wink:

I agree, it does get complicated. :sweat_smile:
And If I was making a standalone arduino ethernet server, I would probably just use the meta-refresh method directly in the arduino sketch.

Like justjed I also have a box at home, capable of hosting php, which makes the jquery approach a lot easier. (now I just have to figure out what i want do do with it - that is the most difficult part of the project!!) :stuck_out_tongue:

I was trying the same thing but i was only able to send data to the arduino without reloading.
I made a tutorial about it maybe you can use the code.
her is the link http://kobey.be/tutorial.html#tab1

Have you considered using web sockets?

There is an SHA library for Arduino out there, so in theory it should be possible.

I used php, javascript, ajax, cURL across two servers to solve this challenge.