Help with Ajax on Arduino

I'm trying to use the Arduino with wifi shield to serve up a webpage that will display the Arduino analog input values. I'm trying to use AJAX so I can update just the values on the page rather than sending a whole new page each time a value changes. I know very little about the Arduino and less about AJAX - but I'm slowly making progress.

I've got the webserver demo running, and I can refresh the whole page with new values in it using the Meta refresh tag. Now I'm trying to update the code to use AJAX instead of the Meta refresh tag.

I'm following this tutorial on AJAX: Ajax Tutorial - XMLHttpRequest

I'm having luck right up to the last step. It appears the AJAX request for new data wishes to execute a PHP script on the server (Arduino) side. So I suppose I have two questions:

  1. How can I put the necessary php file on the Arduino? I only know how to load the sketch itself. Can the php script somehow be incorporated directly into the sketch - or does it have to reside in a directory on the Arduino alongside the sketch? (yes - question one would seem to be a bunch of questions).
  2. Is there a way for AJAX to request data directly from the sketch running on the Arduino? That would seem simpler since the Arduino will ultimately be sending the answer back over wifi. Why drag another script into it?

Thanks very much for any help you can offer.

I don't know much about the Arduino web-server, but I do know quite a lot about internet related technologies and about AJAX. If you want to run php on an Arduino platform then you would need a binary that will execute on the Arduino platform. Source is available for PHP but if it hasn't already been adapted for use on an Arduino, then I'm afraid you are looking at a pretty big job to make it function.

PHP is just used to execute a script on the web-server to allow you to create dynamic responses, you could just as easily use a CGI script written in C that returns what you want.

The X in AJAX stands for XML, however the response doesn't have to be in XML, I now use JSON for my server responses, the reasoning for this is JSON is much more compact than XML and can be interpret by the client as a Javascript object, its also a lot leaner than XML.

The AJAX request is just a HTTP get or post request.

Hope this helps.

Thanks very much - but I'm still a little lost (I'm no expert on either Ajax or Arduino yet). Rather than the Ajax request executing any script on the Arduino, would it not be possible to respond to the Ajax request directly in the Arduino app I'm using as the webserver. I would think both the request and the response have to go through that app anyway - right?

Perhaps Ajax has a form of request that's more like "call this function" rather than "execute this external script"?

Incidentally - I'm not sold on any particular architecture. I'm just looking to use the Arduino to serve up a webpage and update values in it based on values it reads on its inputs.

Thanks again.

As I said, I'm not familiar with the Arduino Web-Server.

AJAX is a way of allowing your clients to make Asynchronus requests to the web-server and the server to send responses to the client in the background without requiring a complete refresh of the page.

Does your application need to make use of AJAX or can you simply use http GET requests? A get request is just the URL of the web-server with a specific page and optionally some paramaters.

The choice of platform depends on scale and the number of clients, if you are going to have quite a few clients then I would suggest that Arduino is not the right platform to host the web-server, however if its just a 1 to 1, and you aren't requesting to much, then it should be fine.

There are other techniques for performing the same type of access as that acheived with AJAX, you can get a similiar effect just using a hidden iFRAME in your document and a script to change the source document, however I haven't used this method.

SPlatten:
As I said, I'm not familiar with the Arduino Web-Server.

Understood - but I'm trying to ask a more generic question (poorly I think). I have the source for the webserver. I'm able to send specific data through it to the client. What I'm wondering is whether there's an Ajax "request" command that can call upon a function in the Arduino code rather than forcing an external php script to run (I don't even know if it's possible to have a separate file of any sort on the Arduino - I only know how to load the app).

If Ajax is able to send such a request, I should be able to implement that into the webserver source myself.

AJAX is a way of allowing your clients to make Asynchronus requests to the web-server and the server to send responses to the client in the background without requiring a complete refresh of the page.

Understood. That's exactly my objective. But it appears to require that I run a php script on the Arduino in addition to the Arduino app. Is it even possible to load a separate file on the Arduino?

Does your application need to make use of AJAX or can you simply use http GET requests? A get request is just the URL of the web-server with a specific page and optionally some paramaters.

I'm happy to use whatever works. It sounds like I need to learn about these GET requests. They'll let me update specific portions of the page without refreshing the entire web-page?

The choice of platform depends on scale and the number of clients, if you are going to have quite a few clients then I would suggest that Arduino is not the right platform to host the web-server, however if its just a 1 to 1, and you aren't requesting to much, then it should be fine.

It's just 1 to 1. The Arduino will be mounted on my powered paraglider and reading a number of sensors. I just want to see those sensor values on my iPhone.

There are other techniques for performing the same type of access as that acheived with AJAX, you can get a similiar effect just using a hidden iFRAME in your document and a script to change the source document, however I haven't used this method.

Thanks. It sounds like http GET might be an interesting avenue to investigate first.

Ok, if you have the web-server source, then you don't need PHP.

The AJAX request is just the same as any other client request, you just handle it and respond to it in the same way you would for a page request, the only difference is in the content. For a normal page you would return a text document, for AJAX you return either XML or JSON.

So for example your request could be http://IP of Arduino/?req=1

req is just a name I've given to the parameter but it could be whatever you like, the value 1 is anything you want too.

Notice in the URL there is no mention of anyfile, it isn't required since you are going to handle the response in the web-server. Normally if you were using PHP, then it is the PHP file that would respond to the client request.

A GET request is the type of request you make when you type an address into a web-browser, the alternative is a POST which is normally used for sending larger amounts of data from the client to the server.

GET's are limited in length to the maxium size allowed for a URL, normally 255 bytes.

Thanks very much. I think that's taking me down the right path. But I am now only able to keep one eye open. I'll try to study what you've said in the morning.

A simple approach might be to put an embedded frame in your main page that contains the meta refresh arduino information.

The problem I have with using the Meta Refresh approach is that the system fails as soon as it gets one bad download. If my understanding is correct, the Ajax approach will continue requesting data even if it fails on one or more tries.

If you want retries then you will have to implement that yourself in script. I have some scripts I wrote a year or so ago that allow you to queue and monitor message transactions, these are all coded in Javascript.

The MS ActiveX Ajax object is a pretty simple beast.

The problem I have with using the Meta Refresh approach is that the system fails as soon as it gets one bad download.

I opened the below meta refresh arduino page with an instance of IE and let run for several days. The arduino appeared to serve up ~150k+ pages without a hang.

// arduino IDE 1.0
// 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:84 in your brouser
// or http://zoomkat.no-ip.com:84 with dynamic IP service
// use the \ slash to escape the " in the html
// meta refresh set for 2 seconds

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

int x=0; //set refresh counter to 0
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,102); // ip in lan
EthernetServer server(84); //server is using port 84

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

void loop()
{
  // listen for incoming clients
  EthernetClient 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; //page upload counter
          client.println("<HTML>");
          client.print("<HEAD>");
          client.print("<meta http-equiv=\"refresh\" content=\"2\">");
          client.print("<TITLE />Zoomkat's meta-refresh test</title>");
          client.print("</head>");
          client.println("<BODY>");
          client.print("Zoomkat's meta-refresh test IDE 1.0");
          client.println("
");
                    
          client.print("page refresh number ");
          client.println(x); //current refresh count
          client.println("
");
          client.println("
");
          
          client.print("Zoomkat's arduino analog input values:");
          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;
          client.println("</BODY>");
          client.println("</HTML>");
         }
        }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}

The MS ActiveX Ajax object is a pretty simple beast.

I don’t suppose you can point me to an example sketch? I’m really just trying use my Arduino/YellowJacket to update values in a browser page. I’d like those values to come from variables in my Arduino sketch (which I’d get from my analog and digital inputs).

I hope this is not out of line, but I figured I’d attach my current sketch files here so you can see what I have. This one can display values from the sketch, but it uses the Meta refresh approach where I think I’d like to use the Ajax approach.

MyWebServerDemo5.ino (2.65 KB)

webserver.c (5.86 KB)

The MS ActiveX object is created on the client in script, your client would need to be running on a MS Windows host in order to create the ActiveX object...which is one very good reason for exploring the IFRAME method further, the second method isn't limited to MS Window clients and should world for other platforms.

Hmmm... I appreciate the advice, but I feel like I'm getting in deeper and deeper. I've gone half way down too many roads at this point. I did a little looking at iFrames last night, but I can tell I'd have to do a good bit more learning about how to integrate that work with the Arduino and WiFi. I was kind of hoping that what I'm trying to do might be common enough that someone would have existing sample code. I had hoped my efforts would be concentrated more on the sensor side.

But alas - I will keep poking at this thing.

First thing is you would have to detect (in the sketch) that there is an ajax-request instead of the first page request. and if so just output the data instead of the whole page (don't know how the ethernet thingy works but normal would be to just change the url slightly)

You can even use jquery given that you have internet access on whatever device you are using to access the arduino (google cdn jquery)

  1. Figure out how to detect wether to return page or ajax-data
  2. Add jquery if you want (script tag in the sketch html output pointing to google cdn jquery)
  3. Replace part of the page using jquery or normal ajax-request. Probably easier replacing just html instead of parsing json -- with jquery that would just be $.update something something

This might be easier trying it on a pc first though..

watching amish ppl on tv.. odd

Btw, pursuing the php on arduino route any further will not help you...

Hmmm... jquery is new to me. You say I'd have to have internet access on the iphone to be able to use that approach? Unfortunately the iphone will be talking wirelessly to the Arduino, but does not have a data plan.

You say that php is not the way to go. This is because it requires a php script in addition to the Arduino sketch on the arduino? I certainly agree that running a separate script is not the ticket. I was beginning to think I could do Ajax requests, but answer them directly from the Arduino sketch.

I'll Google jquery and see what I can make of it.

Thanks.

You don't have to use jquery or have internet on your iphone, would make it slightly easier, but not necessary.

A quick google search for ajax request resulted in this: http://www.w3schools.com/ajax/default.asp

Which is as far as I can understand is what you want.

Below is simple iframe code you can try. You can add the meta refresh page I previously posted as another page to be diaplayed in the iframe box. Copy the below code, paste in notepad, and save on your desktop as test.htm (double click to run, selecting ok for any security warnings about running html from the desktop).

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




Get data from arduino:


|<a href="http://web.comporium.net/~shb/arduino.txt" target="DataBox" title="'arduino test'">Arduino</a>|
<a href="http://web.comporium.net/~shb/pix/slider1.jpg" target="DataBox" 
title="'Show a pix'">PIX!</a>|


<iframe src="http://web.comporium.net/~shb/arduino.txt" width="30%" height="200" name="DataBox">
</iframe>


</HTML>

Here's an Ajax arduino example you'll find helpful.

Jquery is just a JavaScript framework that makes it easier to code for cross broswer issues. It does have an Ajax function but you can use regular js Ajax call.