Desde que escribí el artículo del Arduino controlando el riego en el patio de casa se ha convertido en uno de los apuntes más visitados, y de los que más preguntas y confusión han generado, especialmente en lo referente a servir los datos de nuestra estación Arduino en una página web y desde ella dar órdenes a la placa.
Voy a tratar de explicar como y porqué lo tengo yo instalado sin enrollarme demasiado.

Página de control Arduino

En la imagen una captura de pantalla de la página de control de mi CCCP (Centro de Control Centralizado Patiota, un poco de pitorreo siempre viene bien) desde donde puedo consultar el estado del patio y dar algunas órdenes (regar, pulverizar, alimentar peces y encender luz del patio – Interruptor 3).
Esta página contiene NO está generada por Arduino si no por mi propio ordenador (servidor web GNU-Linux) que es el que sirve los datos, realiza el control de visitas/autentificación, genera archivos de registro/log y estadísticas (temperatura, humedad, etc… ), compone la página y todo su código correspondiente (css/javascript/php), y permite dar órdenes sencillas al Arduino (p. ejem: riega 10 segundos) pulsando un botón pero siempre después de realizar comprobaciones de autentificación y funcionamiento (p. ejem: antes de ordenar a Arduino que riegue hay que comprobar que no está ya regando, o pulverizando o que por error no le hemos dicho “riega durante 3 días”).

Inconvenientes

Todo este trabajo si bien podría (teóricamente, aunque esto no es estrictamente cierto) hacerlo Arduino es del todo desaconsejable por varios motivos:
1/ Arduino carece de la potencia necesaria para atender un volumen bajo-muy bajo de visitas. Si trabajáis con la tarjeta Ethernet notaréis en seguida como sube la temperatura de esta en cuanto le solicitáis que haga algo muy sencillo.
2/ La estabilidad de Arduino cuando tienen que atender muchas visitas se resiente y la placa se resetea si el volumen de trabajo aumenta.
3/ Hacer que Arduino sirva todo el código HTML de la página de control, además del enorme volumen de trabajo que le supondría sería impracticable cada vez que quisiéramos realizar un cambio mínimo en la página. Imagina tener que cambiar algún detalle del código HTML tener que descolgar el Arduino del patio, conectarlo a tu ordenador, subir a la placa el nuevo código, probarlo, volver la placa a su sitio. Una verdadera locura.

Arduino sirviendo JSON/Javascript

Por todo lo dicho parece deseable que Arduino sirviese la mayor cantidad de datos con el menor volumen de trabajo posible y así delegar en otro ordenador “de verdad” todo el proceso consiguiente de autentificar, filtrar, procesar, calcular, programar, etc…

Para este fin el formato Javascript-JSON es ideal, es muy ligero e interpretable fácilmente desde cualquier página web con JAVASCRIPT. Un esquema básico de un objeto JSON sería por ejemplo:{"temperatura": "23.2", "uptime": "124312312"}
Vamos a montar una mini-estación meteorológica que nos diga la temperatura y el tiempo que lleva en ejecución Arduino y que sea accesible desde internet.

NotaEl artículo presupone que ya sabes montar y hacer funcionar un servidor Web Apache en tu propia máquina y hacerlo accesible desde el exterior.

Esquema Arduino

Construye este esquema básico con un sensor de temperatura LR35.

Ethernet y sensor LR35Ethernet y sensor LR35

Código Arduino

Conecta Arduino y carga el siguiente código (aquí en formato TXT):#include <SPI.h>
#include <Ethernet.h>
EthernetServer servidor(80); // puerto de conexión
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //mac address
byte ip[] = { 192, 168, 1, 205 }; // ip de tu Arduino en la red
byte gateway[] = { 192, 168, 1, 1 }; // ip de tu router
byte subnet[] = { 255, 255, 255, 0 }; // subnet
String json,solicitud;
float temperatura;
int tempPin = 0;
void setup() {
Ethernet.begin(mac, ip, gateway, subnet);
servidor.begin();
}
void loop() {
temperatura = analogRead(tempPin);
temperatura = (5.0 * temperatura * 100 ) / 1024;
Serial.print(tempC);
Serial.print(" grados Celsius\n");
EthernetClient cliente = servidor.available();
if (cliente.available()) {
char c = cliente.read();
if ( solicitud.length() < 100 ) { solicitud += c; }
if ( c == '\n' ) {
json = "{\"";
json += "temperatura\": \"" + (String)temperatura + "\", ";
json += "uptime\": \"" + (String)millis() + "\" ";
json += "}\n";
cliente.println("HTTP/1.1 200 OK"); // enviamos cabeceras
cliente.println("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
cliente.println("Content-Type: text/javascript");
cliente.println("Access-Control-Allow-Origin: *");
cliente.println();
cliente.println(json); //imprimimos datos
delay(100); // esperamos un poco
cliente.stop(); //cerramos la conexión
}
}
if ( !cliente.connected() ) { cliente.stop(); }
}

Ahora puedes conectar Arduino por cable ethernet al router de casa. Si todos los datos de conexión son correctos en unos segundos Arduino estará accesible en la ip 192.168.1.205, apunta un navegador web a esa direcciónhttp://192.168.1.205
En navegador debería aparecer algo como { "temperatura" : "23.4", "uptime" : "123234"}
Si esto es así pasa al siguiente apartado, sino comprueba las líneas del código donde se define ip[] y gateway[], tendrás que adaptarlas a tu propia situación de casa.

Conectar con Arduino

Ahora que ya está Arduino on-line y sirviendo datos creamos una página sencilla que conecte con él, recoga los datos y los muestre en un documento web en tiempo real. Esta página será la que se muestre públicamente, restringa el acceso de usuario, realice cálculos de riego, estadísticas, programaciones horarias, etc… de este modo descargamos a Arduino de trabajo extra y facilitamos la tarea de realizar actualizaciones, cambios o mejoras en la web sin tener que andar instalando/desinstalando nuestra placa.
Crea un documento HTML llamado (conexion-arduino.html) con el siguiente contenido (aquí en formato TXT):<!DOCTYPE html>
<html>
<head>
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
<meta charset="utf-8" />
<title>Demo Arduino Ethernet</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
function cargarDatos() {
// En la linea siguiente cambia la IP por la que esté usando tu arduino
$.getJSON("http://192.168.1.205").done( function(datos){
$("#tempVal").text(datos.temperatura);
$("#uptimeVal").text(datos.uptime);
});
}
</script>
</head><body onLoad="cargarDatos();">
<div>
<h2>Temperatura: <span id="tempVal"></span></h2>
<h4>Uptime: <span id="uptimeVal"></span></h4>
</div>
</body>

Listo, ya solo os queda completar la información que sirve vuestra placa Arduino con todos los sensores y datos de funcionamiento. Procurad que sea lo más completa posible de modo que desde vuestro ordenador sepáis todo lo que ocurre en vuestro Arduino sin tener que acceder a él conectándolo vía USB.
Por su parte la página podéis lógicamente completarla a vuestro gusto, incorporar alguna hoja de estilos, algún método de autentificación (obviamente no es muy recomendable que cualquiera que entre a vuestra página pueda ponerse a regar), podéis incorporar aplicaciones PHP que automaticen tareas y mejoren la usabilidad (si no indico tiempo de riego asígnale un valor por defecto de 30 segundos, si le indico -por error- un riego de 7500 segundos limítalo a 120). Etcétera, a gusto del consumidor. Suerte.