JSON WEB SERVER html

Hi everyone,

First of all, I want to apologize if this is not the correct place to post, and secondly as you notice my english it is not so good.

I hope you could help me. I want to show in a web page the values of my sensors. By now I am playing with a little example.

The system is composed by an arduino UNO and an Ethernet shield. Both work as a server. I made a "web page" in html:

("SERVER.txt"):

Servidor Web Arduino

(F1.txt):

name:

temperature:

humidity:

address:

sleepCycle:

asynchronus:

I want to explain this, I create as files as sensors. If I have 4 sensors there are 4 files F1.txt,F2.txt,F3.txt,F4.txt. Itl would be sense with the sketch.

It is supposed that if a push the button, a http get request is sent to my board. And then it replies with a json object:
(this structure is saved as a file )
{
"name": "fio1"
"variables":{
"address": "0x01",
"temperature": "24",
"humidity": "85",
"asynchronus": "0",
"sleepCycle": "20"
}
}

And I think when it is send to the browser it will work... I show you my super-sketch:

// LIBRERIAS

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

#include <SD.h> // ocupa 5KB

char fio[3];
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x49, 0xFD };
byte ip[] = { 192, 168, 1, 2 }; //aula de informática {172,31,55,44} // laboratorio { 192, 168, 112, 31 }
byte gateway[] = { 192, 168, 1, 1};
Server server(80); // Puerto 80, HTTP

// VARIABLES GLOBALES

//Ethernet Shield uses pins 10,11,12,13.
#define bufferMax 128
int bufferSize;
char buffer[bufferMax];

// SD
File myFile;

#define ssPin 10
#define chipSelect 4

void setup() {

Ethernet.begin(mac, ip, gateway);
server.begin();
Serial.begin(9600); // inicia comunicación serie
pinMode(ssPin,OUTPUT);

if (!SD.begin(chipSelect)) { // inicia la tarjeta SD
Serial.println("initialization failed!");
return;
}
}

void loop() {

listenForClient();
}

void listenForClient() {

Client client = server.available(); // espera a que haya datos disponilbles
if ( client ) {
waitForRequest(client);
int fioNumber = parseReceivedRequest(client);
if (fioNumber != 0)
sendGetResponse(fioNumber, client);
}
client.stop();
}

void waitForRequest(Client client) {
bufferSize = 0;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n')
break;
else
if (bufferSize < bufferMax)
buffer[bufferSize++] = c;
else
break;
}
}
Serial.print(buffer);
}

int parseReceivedRequest(Client client) { // Petición recibida del tipo: "GET &fio1 HTTP/1.1"
char* qm, * space;
fio[0]=0;
// strncpy does not automatically add terminating zero, but strncat does! So start with blank string and concatenate.
if ( qm = strstr(buffer, "&fio") ) { //apuntará a &
qm += 4; // sumando 5 apunta al valor deseado ( 4 letras --> "&", "f", "i", "o")
space = strstr(qm, " ") + 1;
strncat(fio, qm, space-qm-5);
return atoi(fio);
} else if ( qm = strstr(buffer, " ") ) {
webPrint(client);
return 0;
} else
return 0;
}

void sendGetResponse(int fioNumber, Client client) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/plain");
char filename[8];
sprintf (filename, "F%d.jsn", fioNumber);
filePrint(filename, client);
client.println(" ");
}

void webPrint (Client client) {
filePrint("SERVER.TXT", client);
char filename[6];
int fiolength = 1, i = 1;
for ( i = 1; i <= fiolength; i++ ) {
sprintf (filename, "F%d.txt", i);
filePrint (filename, client);
}
client.println("");
client.println("");
}
// fuente: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1295739118
void filePrint (char filename[10], Client client){
char a;
if (myFile = SD.open(filename, FILE_READ)) {
while ( myFile.available() ) {
a = (char)myFile.read();
client.print(a);
Serial.print(a);
}
myFile.close(); // CERRAR FICHERO
}
}

basically I wait for http request, I write http:\192.168.1.2 in the browser... so I received "GET /HTTP1.1" as there is not information I print the web page. Then I wait for clicking the button, so it will appear an GET fio1 /HTTP1.1. I parse this last one, and response to it. I search on the micro SD card for a file called fio1 and then print this information that is the json structure and nothing happens. The goal was when the structure arrives to the client the script execute itself and fill the gap I wrote as <div ahref ... .... but... Maybe I make a mistake writing the html or the script or the http json response is not the correct one...

I am sorry it is sort of big... xD. Well, my questions are:

I do not have idea of html or http, just the few things I´ve read. And it is a mess. So I am not know if the html is well proposed. Or if I can response the http get request as I did just printing on the client, ...

I hope you could help me! Just read this is remarkable.

thank you !

I'm no pro but, here's an idea that may simplify the matter. You want the arduino to become the server? I think that's kinda much for the little guy. Why not send the sensor readings to the PC and "processing" can send them to the webpage that is hosted by that PC. By send I mean write into a file and the Website will refresh the read on the file at a few secs interval. Hope this helps a little, if not sorry for me posting.

Hi,

thanks for your answer. The next step it will be to use a server, as you said. But I was asked to do this more or less... Just show the information. There is other examples, like ajaxwebserver I found it here ->http://djgj.sub.jp/TETRASTYLE/arduino/Ajax_WebServer.txt

As you can see, the html it is not complicated. And json is supposed to do easier. But anyway thank you for your answer.

byes!

As I understand it, you have a local web page that provides all the decorative stuff and just executes an HTTP request to the Arduino to retrieve some data. The page then processes the results and uses that to populate the page.

The basic approach seems OK. I haven't look at the detail of your JSON handling, but your JSON fragment is incorrect: the field names should not be quoted.

I suggest you get that sorted out by hard-coding your JSON string in the page and then use your existing logic to exec it into a variable; then you can print out whatever fields of that variable interest you.

I want to show in a web page the values of my sensors.

The below is a more conventional and possibly easier method to display values in a web page.

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

zoomkat:
The below is a more conventional and possibly easier method to display values in a web page.

Yeah, but that way the Arduino has to generate the whole page and whatever resources it needs to display.

The AJAX route originally proposed is a far more elegant solution. The Arduino only has to provide the data, and the rest of the page comes from somewhere else. It also means you can update the data without doing page turnarounds and just works better all round.

Yeah, but that way the Arduino has to generate the whole page and whatever resources it needs to display.

If you actually do some testing, my code can generate the bare minimum data from the arduino that your project will need, probably less from what I see in the posted JSON stuff.

The AJAX route originally proposed is a far more elegant solution. The Arduino only has to provide the data, and the rest of the page comes from somewhere else. It also means you can update the data without doing page turnarounds and just works better all round.

More elegant? You can do pretty much what you describe with simple HTML. Doesn't AJAX require a folder on a server with supporting files the browser has to download for it to work? I made some web page sliders one time to control servos and I think it was an AJAX setup.

The AJAX route originally proposed is a far more elegant solution.

Very elegant! But how does it work for you?

I do not have idea of html or http, just the few things I´ve read.

May I suggest using an iFrame for the Arduino data. You can embed another document into a page. Here is some more reading:

Simple iframe html that keeps input to the web page in a box. To test, copy the code, paste in notepad, save on the desktop as test.htm. Bouble click the test.htm file (OK/yes the warnings about running the page from the desktop) to open it in your browser. You can then toggle between the two inputs to the iframe box without refreshing the main page.

<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>

zoomkat:
More elegant? You can do pretty much what you describe with simple HTML. Doesn't AJAX require a folder on a server with supporting files the browser has to download for it to work? I made some web page sliders one time to control servos and I think it was an AJAX setup.

Well, that depends if you want the web page to consist of a few lines of text in the default style, or to provide a visually attractive interactive user interface. By treating the Arduino as a source of data pulled into the page as required, and keeping the bulk of the page elsewhere, you are free to use all the ordinary web site authoring tools and techniques, style sheets, scripts, graphics and so on. If you want to host it locally, it would make sense to implement it as an HTML Application. But there's nothing to stop you hosting it on a web site somewhere else if you want it to be accessible remotely.

If you want to host it locally, it would make sense to implement it as an HTML Application.

How else would your arduino provide data for your JSON/AJAX web page other than thru serving up the data via the http process? I've seen arduino code for telnet and udp but that would seem to be very complicated and unpractical in a web setup. One can make whiz-bang (and totally annoying) web pages using files/images stored on a big web server, but this really does not have anything to do with the arduino itself serving basic data to be displayed within the page.

zoomkat:

If you want to host it locally, it would make sense to implement it as an HTML Application.

How else would your arduino provide data for your JSON/AJAX web page other than thru serving up the data via the http process? I've seen arduino code for telnet and udp but that would seem to be very complicated and unpractical in a web setup. One can make whiz-bang (and totally annoying) web pages using files/images stored on a big web server, but this really does not have anything to do with the arduino itself serving basic data to be displayed within the page.

I think we're talking at cross purposes.

In your example, the Arduino publishes some HTML which is displayed in the browser. This means that either what is displayed is formatted very crudely, or your Arduino has to serve out a rich HTML page and whatever resources it needs to render properly. The Arduino isn't a good platform for serving out rich HTML documents, style sheets, scripts and all that. All you really want from the Arduino is the data itself, whether encoded in XML, JSON, CSV or whatever. For an AJAX application, JSON is a perfectly sensible way to encode the data.

Implementing this as an AJAX application that gets data from the Arduino simply gives you a better solution than serving your whole page from the Arduino.

Implementing this as an AJAX application that gets data from the Arduino simply gives you a better solution than serving your whole page from the Arduino.

I never said anything about serving a "whole page" from the arduino, just the desired data. Below is link for getting the minimum no frills basic data from the arduino. The AJAX, html, or other methods of the display page construction would be up to the page developer and what they think will best suite the end viewer.

The Arduino isn't a good platform for serving out rich HTML documents, style sheets, scripts and all that.

It's perfectly capable of referring to style sheets, scripts, etc. that are stored elsewhere, and letting the browser fetch all the right files.

PeterH:
As I understand it, you have a local web page that provides all the decorative stuff and just executes an HTTP request to the Arduino to retrieve some data. The page then processes the results and uses that to populate the page.

The basic approach seems OK. I haven't look at the detail of your JSON handling, but your JSON fragment is incorrect: the field names should not be quoted.

I suggest you get that sorted out by hard-coding your JSON string in the page and then use your existing logic to exec it into a variable; then you can print out whatever fields of that variable interest you.

Hi Peter,

thank you for your answer. You understood it quite well. I correted the json file, thanks. And I did as you said, separately, I write html web server. And It worked, but...

Servidor Web Arduino

  • name:
  • temperature:
  • humidity:
  • address:
  • sleepCycle:
  • asynchronus:
  • but...when I post on the card ... well... on browser, I open the console that show the code ... (in chrome F12) and it said that it couldn´t find temperature (which is part of variables...) well I simplified the structure... { name = "fio1, temperature="34"... etc} ... but Is it json? xD Anyway, if I enter the IP address of my arduino it shows

    fio1 (as a button)

    name: undefined
    temperature: undefined
    humidity: undefined
    address: undefined
    sleepCycle: undefined
    asynchronus: undefined

    undefined¿? I searched through the web but... I am lost.
    Could it be that the it is not response?
    Did I send a bad response?

    void sendGetResponse(int fioNumber, Client client) {
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/plain");
    client.println("Connection: close");
    client.println(" ");
    char filename[8];
    sprintf (filename, "F%d.jsn", fioNumber);
    filePrint(filename, client);
    client.flush();
    }

    I directly write the jsonfile (client.print ...)

    Thank you for your time, I really appreciate it.

    greetings!

zoomkat:

I want to show in a web page the values of my sensors.

The below is a more conventional and possibly easier method to display values in a web page.
...

Hi Zoomkat,

thank you for your time. I already know it, but I was asked to use JSON. I already did something similar... Toys + Me = Fun.

byes!!

The JSON looks right to me.

To eliminate some of the complexity while you get the basic JSON-string-to-script-variable part working, try this:

<script>
  var json = {  name: "fio1"  };
  alert("json=[" + json + "]");
  alert("json.name=[" + json.name + "]");
</script>

That should pop up a message dialog saying json=[Object object], and json.name=[fio1], or something similar.

If not, then check for script errors when it runs.

PeterH:
The JSON looks right to me.

To eliminate some of the complexity while you get the basic JSON-string-to-script-variable part working, try this:

<script>

var json = {  name: "fio1"  };
  alert("json=[" + json + "]");
  alert("json.name=[" + json.name + "]");




That should pop up a message dialog saying json=[Object object], and json.name=[fio1], or something similar.

If not, then check for script errors when it runs.

Hi PeterH,

I already did it on the example, and it shows " object Object" and it works:

name: fio1
temperature: 24
humidity: 85
address: 0x01
sleepCycle: 20
asynchronus: 0

but when I tried on the board, it said undefined ... maybe I explained myself badly. Sorry. Or I ´m not understand you xD

Anyway thank for reading my posts, I appreciate it.

Greetings!!

This test code is intended to go in a HTML document on your PC, not involving the Arduino at all.

You should see a message dialog showing you the value of json and json.name. Do you see both of them? Does json.name show the correct value "fio1"?

PeterH:
This test code is intended to go in a HTML document on your PC, not involving the Arduino at all.

You should see a message dialog showing you the value of json and json.name. Do you see both of them? Does json.name show the correct value "fio1"?

Hi PeterH,

... Yes,sorry, my english it is no so good, well I pasted the code example I used it on my PC and it worked. But, my question was about the arduino... As you see I deleted the open(get... etc, status, ... and I simply write the json strutcture. It worked, an alert window appeared saying "object Object" and filling the gaps, name: fio1, temperature: 32 etc. That means that the example worked, the example I pasted on the post. So, with that, I added the status, get, etc... but the alert window shows nothing and the gaps are filled with "undefined" but if I use the json structure { name: fio1, temperature: 34...} If I use {name: fio1, variables: { temperature: "32", humidity: "86"... etc}} it says something as unable to get temperature ...

sorry for my english

thanks