real-time data from arduino sensors to mobile web browser using ethernet shield

I'm looking for a way to get real-time sensor data to a mobile browser using the ethernet shield in a LAN environment. Right now I'm using AJAX to request the data just like this tutorial

but I can only get the data every half second or else the browser will crash. Is there another way to get the sensor data faster? Any info would be appreciated. thanks.

Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Your other post deleted.

  • Moderator

Since the whole idea of Ajax is that it sends only the characters it needs to update the browser page, that presumably means a very small amount of transmission to your browser so yeah I guess it's strange that it's "crashing" (whatever that means....)

Have you tried other browsers?

The below is some web page test code that updates fairly quickly.

// zoomkat's meta refresh data frame test page 5/25/13
// use http://192.168.1.102:84 in your brouser for main page
// http://192.168.1.102:84/data static data page
// http://192.168.1.102:84/datastart meta refresh data page
// for use with W5100 based ethernet shields
// set the refresh rate to 0 for fastest update
// use STOP for single data updates

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

const int analogInPin0 = A0;
const int analogInPin1 = A1;
const int analogInPin2 = A2;
const int analogInPin3 = A3;
const int analogInPin4 = A4;
const int analogInPin5 = A5;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical 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
unsigned long int x=0; //set refresh counter to 0
String readString; 

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

void setup(){
  Serial.begin(9600);
    // disable SD SPI if memory card in the uSD slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();
  Serial.println("meta refresh data frame test 5/25/13"); // so I can keep track of what is loaded
}

void loop(){
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
         if (readString.length() < 100) {
          readString += c; 
         } 
        //check if HTTP request has ended
        if (c == '\n') {

          //check get atring received
          Serial.println(readString);

          //output HTML data header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          //generate data page
          if(readString.indexOf("data") >0) {  //checks for "data" page
            x=x+1; //page upload counter
            client.print("<HTML><HEAD>");
            //meta-refresh page every 1 seconds if "datastart" page
            if(readString.indexOf("datastart") >0) client.print("<meta http-equiv='refresh' content='1'>"); 
            //meta-refresh 0 for fast data
            if(readString.indexOf("datafast") >0) client.print("<meta http-equiv='refresh' content='0'>"); 
            client.print("<title>Zoomkat's meta-refresh test</title></head><BODY>
");
            client.print("page refresh number: ");
            client.print(x); //current refresh count
            client.print("

");
            
              //output the value of each analog input pin
            client.print("analog input0 is: ");
            client.print(analogRead(analogInPin0));
            
            client.print("
analog input1 is: ");
            client.print(analogRead(analogInPin1));
                        
            client.print("
analog input2 is: ");
            client.print(analogRead(analogInPin2));
            
            client.print("
analog input3 is: ");
            client.print(analogRead(analogInPin3));
                                    
            client.print("
analog input4 is: ");
            client.print(analogRead(analogInPin4));
            
            client.print("
analog input5 is: ");
            client.print(analogRead(analogInPin5));
            client.println("
</BODY></HTML>");
           }
          //generate main page with iframe
          else
          {
            client.print("<HTML><HEAD><TITLE>Zoomkat's frame refresh test</TITLE></HEAD>");
            client.print("Zoomkat's Arduino frame meta refresh test 5/25/13");
            client.print("

Arduino analog input data frame:
");
            client.print("&nbsp;&nbsp;<a href='http://192.168.1.102:84/datastart' target='DataBox' title=''yy''>META-REFRESH</a>");
            client.print("&nbsp;&nbsp;&nbsp;&nbsp;<a href='http://192.168.1.102:84/data' target='DataBox' title=''xx''>SINGLE-STOP</a>");
            client.print("&nbsp;&nbsp;&nbsp;&nbsp;<a href='http://192.168.1.102:84/datafast' target='DataBox' title=''zz''>FAST-DATA</a>
");
            client.print("<iframe src='http://192.168.1.102:84/data' width='350' height='250' name='DataBox'>");
            client.print("</iframe>
</HTML>");
          }
          delay(1);
          //stopping client
          client.stop();
          //clearing string for next read
          readString="";
        }
      }
    }
  }
}

JimboZA:
Since the whole idea of Ajax is that it sends only the characters it needs to update the browser page, that presumably means a very small amount of transmission to your browser so yeah I guess it's strange that it's "crashing" (whatever that means....)

Have you tried other browsers?

Thats right I am only trying to update the number of times a button is pushed so it is is a small amount of data. I think the problem is the http connection gets "rebuilt" every time it requests new data and that is what is giving me the slow and inconsistent results. So I'm trying to find away to use websockets or something of that nature. If you have any suggestions on that let me know.

The problem with using another browser is I am building an app that needs to be compiled with phonegap (for mobile phones) so I don't have any control over the browser. And by crash I mean my phone restarts when I set the ajax call to fast.

Any info would be appreciated.

Thanks zoomkat. I need the data to get to the browser faster than half a second. I'll try it out and see how it works.

I think the problem is the http connection gets "rebuilt" every time it requests new data and that is what is giving me the slow and inconsistent results. So I'm trying to find away to use websockets or something of that nature. If you have any suggestions on that let me know.

Hi thebatsignal,

your suspect on loosing time closing the connection every single AJAX request could make sense. In the code presented in the tutorial you mention, the call to client.stop() actually closes the socket server-side, and prevents the client from keeping the connection open, as browsers usually do when sending AJAX requests to web servers (this technique is also known as "Persistent Connection", see RFC2616 par. 8.1).

But beware, if you don't close the connection, you must consume the client request completely, i.e. you must parse the HTTP headers, look for the "Content-Length" header and see its value: it indicates howmany bytes must be read in the HTTP message body after the end of headers.

As far as I know, the Apache web server keeps the connection open for a given time, usually 5 seconds, before closing it assuming a client timeout. I have used this technique in a web server I have implemented recently and this helps very much in the direction of persistent connection.

The official Arduino Ethernet library is very very simple, small and effective, but has its own limitations. If you need more sophisticated functionality than sending a simple page by a sequence of client.println(), it comes to a little cost.

HTH,
eca

I have another option for you.

I too wanted a fast method to have data from the Arduino to web browser.
So, initiatlly I too used the method most people end up doing, that is, set up your Arduino as a small internet server.
For me, it has limitations in terms of how I wanted to develop a system over time.

Next I made it so that the Arduino simply sent data to my host server using HTTP POST format.
That works and I can store data in my SQL database easily too which I use for trends.
But, again, the problem with this is that it needs regular and continuous POST commands from the Arduino.

So, my next stop was to look at using a publisher/subscriber model.
And what I did then was to make my Arduino routines work such that after I filter the analog values I maintain various flags for each analog. One of them is a 'change of value' or COV bit. That allows me to send the data of any analog only if it has changed in value by a given amount.

So, then I send that data to a site called PubNub, no, it's not your local place of worshipping the liquid amber, it's a site that is set up for using a publisher subscriber model which means the ability to have next to real time data available from a source to a destination.

I did a few rough tests a while back and had notice the time difference I would get between data sent via standard polling methods, where the Arduino sends to host server and client requests from host server, to the method of Arduino sends to PubNub and client is subscribed to your PubNub channel.

With any polling or timed based technique, you will always need to wait the time period of your poll period.
Try to make the poll period faster and you run into problems in other aspects of your system, and you simply end up trying to send loads of data that may be unnecessary.

With a system where you use change of state or value you reduce this unnecessary overhead. Then by using a publisher subscriber model the turn around time from input into the data broker to you getting it as a subscriber is counted in a few hundreds of milliseconds.

When I see a data change on the Arduino by indication of a LED, I will have that data on my browser screen in typically 250mS, regardless of where I am in the world as long as the DSL connection I have is soild.

The upshot is that your browser app is very light weight, no need for AJAX, as used traditionally. Also, your Arduino is not a web server and hence trying to service an unpredictable amount of incoming HTTP requests, rather, it sends out the data, and only when there is a need. What you have then is very fast data from the sensor to the screen, anywhere in the world and any number of clients. Millions of clients if you wish, with no impact on your little Arduino.

PubNub have APIs for working with many systems, Arduino included.


Paul