La idea del proyecto es modificar el estado de salidas digitales desde cualquier dispositivo móvil, a través de internet , desde cualquier lugar, utilizando el shield de Ethernet W5100 sobre Arduino Uno corriendo en modo WebCliente contra un servidor de Hosting gratuito .
No se trata de un acceso via LAN, sino via WAN, es decir con conectividad a Internet desde cualquier dispositivo movil. Un usuario utilizará su navegador preferido y se conectará a un sitio que aloja una WebPage donde efectuará las modificaciones de 4 salidas. Nuestro WebClient Arduino se conectará también a dicho sitio a intervalos regulares de tiempo y solicitará por medio de consulta GET el estado de las salidas las cuales serán modificadas en el sitio remoto y confirmadas al sitio. De esta manera el usuario al actualizar la página sabrá si dichas modificaciones efectivamente se han realizado.
Conceptos Básicos WebClient
En la figura se muestra un WebClient, que en nuestro caso será Arduino Uno con el Shield Wiznet5100, el cual genera peticiones PHP al Servidor alojado en un Hosting gratuito, en mi caso utilicé Hostinger , el cual responderá a nuestro WebClient con un código HTML donde irá «incrustada» la respuesta. La siguiente figura muestra la intervención del usuario
Problemas que vamos a evitar en modo Cliente
La aplicación sobre Arduino será del tipo WebClient y no Server, dado que en modo WebClient no vamos a depender de las direcciones IP públicas que se modifican cada determinado tiempo si tuviésemos el modo Server en Arduino. En modo Servidor, nuestro Router le asigna una dirección IP a Arduino para poder distinguirlo dentro de nuestra red local . El Router le asigna una dirección de IP de manera dinámica por medio del servicio de DHCP, esto quiere decir que la IP de Arduino se va a modificar cada determinado tiempo, por lo que será necesario decirle al Router que dicha IP se mantenga fija ya que en nuestro sketch de arduino debemos indicarla. DHCP asigna la IP de acuerdo a la dirección física MAC de la placa que suele venir identificada sobre la W5100, caso contrario se puede usar cualquiera. Se puede también asignar a nuestro arduino un IP fija pero como los demás dispositivos conectados al Router en una red local (celulares, Pc’s, etc) son de IP dinámica, pueden colisionar en algún momento con otras IP dejar de funcionar. Dependiendo del Router, se puede configurar que DHCP siempre asigne la misma IP a una dirección MAC determinada y aunque no es el objetivo en este trabajo, generalmente es la opción DHCP Settings y MAC assignment. Hasta aquí podremos usar siempre nuestro sistema pero de forma local, es decir vía LAN, si queremos acceder a nuestro sistema desde fuera como internet WAN habrá que abrir un puerto adicional en el Router para redireccionar el tráfico de datos desde internet hacia la IP de Arduino. Esta función depende también del router y generalmente está en Port Forwarding. Tipicamente son el puerto 80 y otro también como el 5400. El otro problema ahora a resolver es que para acceder desde fuera necesitamos la IP pública del router, y esta es dinámica. Las opciones que disponemos son contratar una IP fija lo cual es muy costoso, o utilizar un servicio pago de servidor DNS, esto es asignar un mismo nombre por ejemplo www.misistema.com a la IP pública del router cambie o no. Este servicio siempre «linquea» la IP modificada o no, con el nombre DNS.
Mi Alternativa
Para evitar todos los problemas anteriores utilizamos el modo Cliente, o WebClient donde la W5100 siempre se conectará contra un servidor o Hosting gratuito cuya dirección nunca cambia. Nuestro Hosting será nuestro Server quien responderá a los requerimientos de Arduino. Nuestro Server debe alojar una página Php o HTML, dependiendo de la aplicación. Html es estática, es decir que el contenido no se modifica. Php es dinámico y permite mostrar contenidos que se modifican en nuestro sitio y procesar con código Php dichos contenidos. Por ejemplo una página Html puede contener un formulario para ingresos de datos y una vez ingresados el procesamiento será vía un servidor Php como por ejemplo Apache. Toda petición a un servidor se internet, siempre es respondida en lenguaje Html que es el lenguaje de internet para poder ejecutarse desde nuestro navegador. Entonces la idea es que un usuario ingrese al sitio o hosting gratuito donde se le presentará un contenido Php, en este caso, dado que la información que se presenta no es siempre la misma, se muestra la información actualizada de las salidas y esto es cambiante. Allí el usuario puede modificar el estado de las salidas, las cuales se graban de manera permanente en un archivo de texto, que aloja en una cadena, el estado de las mismas (activada, desactivada) con una indicación adicional de “NO REALIZADO”. Esto no significa que inmediatamente dicha modificación se realice en el WebClient, nuestro Arduino.El cliente se conectará al sitio cada determinado intervalo de tiempo y enviará una solicitud del tipo GET donde requiere el estado de las salidas. Dicha petición se procesa vía Php leyendo el archivo y devolviendo una cadena de texto de las salidas hacia el Cliente junto con la indicación. El cliente al recibir la cadena del estado de salidas y la indicación de “NO REALIZADO” asumirá que habrá que modificar las salidas en su sistema de actuador ( reles, leds, etc). Una vez realizado se vuelve a conectar con otra petición GET a modo de confirmación físico de dicho cambio. La página Php al recibir esta nueva petición modificará el archivo de salidas con la indicación “REALIZADO – Fecha-hora-día”. Cuando el usuario ingrese más tarde a la página podrá observar si su cambio de salidas esta realizado o no realizado aún. De esta manera tenemos un sistema no-sincronizado pero útil.
Cadenas de texto recibidas por el WebClient
La cadena guardada en el archivo del sitio .txt será de la forma:
(a) sal1=1sal2=1sal3=1sal4=0NO REALIZADO Cada vez que el usuario efectúe un cambio
(b) sal1=0sal2=1sal3=1sal4=0REALIZADO-2016-01-07 | 02:4:21 |Cada vez que el cliente realice el cambio
El Webclient, nuestro Arduino al leer la cadena entonces sabe lo que debe hacer , o no hacer que es el caso de la cadena (b), o debe modificar y notificar el cambio realizado en el caso de la cadena (a).
Implementación de Páginas en el Hosting
A continuación se colocan las páginas en PHP que se van a utilizar en el proyecto y como se van llamando desde nuestro navegador al Hosting.
El hosting creado fue en http://www.hostinger.com.ar/ y el sitio www.guscir.hol.es . No entraremos en detalle de cómo generarse un sitio gratuito ya que hay excelentes tutoriales en internet y realmente es muy fácil. Lo importante es que gratuitamente tenemos casi todo para administrar un sitio, incluido servidores Php como Apache y MySql para crear nuestras bases de datos en el sitio, además de otros servicios como cuentas de Mail. No es el objetivo enseñar Php , para aquel que no lo conoce existen muchos tutoriales en la red, pero debo incluir las páginas para aquel que conoce de Php y páginas dinámicas y desea modificar, o implementar sus propios diseños.
Salidas.php
Página principal del sitio donde va a acceder el usuario desde cualquier dispositivo, mediante http://www.guscir.hol.es/salidas.php. Allí se puede ver una interface come esta:
La estética la dejo para otro momento ya que no es importante colocar maquetado, estilos, colores, etc. No obstante he agregado un archivo estilo.css para dar algo de color a la tabla de estas 4 salidas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
<html> // Con Hostinger acceder como http://www.guscir.hol.es/salidas.php <head> <link rel=stylesheet type="text/css" href=estilo.css> </head> <body> <?php $ar=fopen("archivocontrol.txt","r") or die("No se pudo abrir el archivo"); //$linea=""; Otra manera while (!feof($ar)) { // $linea=$linea.fgets($ar)."<br>"; // va concatenando linea a linea y agrega un salto a cada linea //echo $linea; $linea=fgets($ar); //echo $linea; } fclose($ar); // En $linea tengo el estado de las salidas en una cadena debo procesarla $estado1= substr($linea,5,1); //echo $estado1; $estado2= substr($linea,11,1); //echo $estado2; $estado3= substr($linea,17,1); //echo $estado3; $estado4= substr($linea,23,1); //echo $estado4; $idcambio=0; $cambio="No realizado"; $cantidad= strlen($linea); //echo $cantidad; if($cantidad>24) // hay datos de confirmacion { $confirma=substr($linea,24,1); //echo $confirma; if($confirma=="R") // Cambio realizado actualizado por el cliente {$cambio="Cambio realizado"; $idcambio=1; $fecha= substr($linea,34); // capta la fecha y hora del cambio efectuado por el cliente } } ?> <p><h3>CONTROL DE SALIDAS</h3></p> <form name="salidas" method="post" action="ArchivoControl.php"> <table border=1 bordercolor=blue > <tr> <?php if ($estado1==1) { echo "<td class=col><h4>SALIDA_1</h4><input type=\"checkbox\" name=\"sal1\" value=\"1\" checked ></td>"; } else{ echo "<td class=col><h4>SALIDA_1</h4><input type=\"checkbox\" name=\"sal1\" value=\"1\" ></td>"; } if ($estado2==1) { echo "<td class=col><h4>SALIDA_2</h4><input type=\"checkbox\" name=\"sal2\" value=\"1\" checked ></td>"; } else{ echo "<td class=col><h4>SALIDA_2</h4><input type=\"checkbox\" name=\"sal2\" value=\"1\" ></td>"; } if ($estado3==1) { echo "<td class=col><h4>SALIDA_3</h4><input type=\"checkbox\" name=\"sal3\" value=\"1\" checked ></td>"; } else{ echo "<td class=col><h4>SALIDA_3</h4><input type=\"checkbox\" name=\"sal3\" value=\"1\" ></td>"; } if ($estado4==1) { echo "<td class=col><h4>SALIDA-4</h4><input type=\"checkbox\" name=\"sal4\" value=\"1\" checked ></td>"; } else{ echo "<td class=col><h4>SALIDA_4</h4><input type=\"checkbox\" name=\"sal4\" value=\"1\" ></td>"; } ?> </tr> <tr></tr><tr></tr> </table> <br> <?php if($idcambio==0) { echo $cambio; } else{ echo $cambio." ".$fecha; } ?> <br> <br> <input type="submit" name="botonModificar" value="Aceptar"> <br><br> </form> <form name="estadoActual" method="post" action="LecturaArchivo.php"> <input type="submit" name="botonLeer" value="LeerEstado"> </form> </body> </html> |
Lo que hace este código Php es leer el archivocontrol.txt (como ya hemos mencionado) donde se aloja la cadena y en función de esta, va a mostrar los checkbox’s tildados o no, de acuerdo a lo que dicte la cadena. Esta es la razón de ser una página Php y no HTML, ya que su contenido cambia según la cadena de texto del archivo. Esto permite que los cambios realizados sean reflejados en la misma página. También analiza si en la cadena aparece el “No realizado” o el “Realizado concatenado con la fecha y hora”. Se pueden modificar los CheckBox de cada salida y luego clickear en el botón Aceptar. Al hacer esto como toda esta tabla está insertada dentro de una estructura <Form> llama a la página ArchivoControl.php y le pasará los nuevos estados de las salidas medante el método POST.
<form name=»salidas» method=»post» action=»ArchivoControl.php»>
…….. Código
</form>
ArchivoControl.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
ArchivoControl.php <html> <head> </head> <body> <?php $estado1=0; $estado2=0; $estado3=0; $estado4=0; if (isset($_REQUEST['sal1'])) { $estado1=$_REQUEST['sal1']; } if (isset($_REQUEST['sal2'])) { $estado2=$_REQUEST['sal2']; } if (isset($_REQUEST['sal3'])) { $estado3=$_REQUEST['sal3']; } if (isset($_REQUEST['sal4'])) { $estado4=$_REQUEST['sal4']; } $cadena="sal1=".$estado1."sal2=".$estado2."sal3=".$estado3."sal4=".$estado4."NO REALIZADO"; // El servidor adjunta NO REALIZADO para que el cliente sepa que es una nueva modificacion en las salidas //echo $cadena; $ar=fopen("archivocontrol.txt","w") or die("Problemas en la creacion"); fputs($ar,$cadena); //fputs($ar,"br"); fclose($ar); echo " "; echo " "; echo "Los datos se cargaron correctamente."; echo " "; echo " "; ?> Volver |
Esta página ArchivosControl.php simplemente detecta las variables pasadas por método POST desde la página anterior y saber cuáles salidas se han tildado, o destildado y de esta manera rescribir el archivocontrol.txt , para actualizar la cadena nueva concatenado ahora con “NO REALIZADO” ya que la cadena ha cambiado y el Webclient (Arduino), debe saber de esta manera, al hacer su consulta, que debe efectuar sus modificaciones.
El botón LeerEstado es redundante y no haría falta pero lo que hace es llamar a otra página LecturaArchivo.php
<form name=»estadoActual» method=»post» action=»LecturaArchivo.php»>
<input type=»submit» name=»botonLeer» value=»LeerEstado»>
</form>
LecturaArchivo.php
Esta página lo que hace ( ya dije que redundante) es leer el archivo y presentar en otro formato la información de las salidas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
LecturaArchivo.php <html> <head> </head> <body> <?php $ar=fopen("archivocontrol.txt","r") or die("No se pudo abrir el archivo"); while (!feof($ar)) { $linea=fgets($ar); } fclose($ar); //echo $linea; echo ''; echo ''; $estado1= substr($linea,5,1); //echo $estado1; $estado2= substr($linea,11,1); //echo $estado2; $estado3= substr($linea,17,1); //echo $estado3; $estado4= substr($linea,23,1); //echo $estado4; $est1="Desactivada"; $est2="Desactivada"; $est3="Desactivada"; $est4="Desactivada"; if($estado1==1) {$est1="Activada";} if($estado2==1) {$est2="Activada";} if($estado3==1) {$est3="Activada";} if($estado4==1) {$est4="Activada";} ?> |
requerimiento.php
Esta página no está accesible al usuario y es la página que va a consultar el WebClient (Arduino) mediante peticiones del tipo GET.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
</head> <body> <?php // http://www.guscir.hol.es/requerimiento.php?consulta=2 se llama de esta manera // No necesariamente habra que pedir con una variable, puede que solo el servidor responda sin necesidad de pasarle una variable, según sea la necesidad // http://www.guscir.hol.es/requerimiento.php $ar=fopen("archivocontrol.txt","r") or die("No se pudo abrir el archivo"); while (!feof($ar)) { $linea=fgets($ar); } fclose($ar); if(!empty($_GET['consulta']) && $_GET['consulta']==1) // El cliente pide consulta de las salidas, su estado { echo $linea; } if(!empty($_GET['consulta']) && $_GET['consulta']==2) // El cliente quiere logear algo o confirmar algo en el server, en este caso validar el cambio de las salidas // en el cliente de acuerdo al nuevo estado de las salidas. Aqui podemos mandar un Mail o actualizar un objeto o elemento en la pagina // para que al entrar nuevamente el usuario se de cuenta que su cambio se realizó, en este caso el cliente reflejo el cambio de las salidas { $linea=substr($linea,0,24); // Captura el estado de las salidas para filtrar el NO REALIZADO $ar=fopen("archivocontrol.txt","w") or die("Problemas en la creacion"); date_default_timezone_set('America/Argentina/Cordoba'); // Actualiza a zona horaria America ya que sino devuelve hora España $time = date("Y-m-d | h:N:s |", time() ) ; fputs($ar,$linea."REALIZADO"."-".$time); // Reescribe archivo con la indicación de realizado //fputs($ar,"br"); fclose($ar); echo "okey"; } ?> |
Peticiones WebClient
El cliente accederá a esta página mediante:
http://www.guscir.hol.es/requerimiento.php?consulta=1
Si observamos bien, el parámetro que pasa el WebClient a la página es consulta con un valor de 1, en este caso.Consulta=1, le indicará a la página Php que solo debe leer el archivo archivocontrol.txt para extraer la cadena de salida.
1 2 3 4 |
if(!empty($_GET['consulta']) && $_GET['consulta']==1) // El cliente pide consulta de las salidas, su estado { echo $linea; // RENVIA LA CADENA COMO RESPUESTA } |
La cadena de respuesta puede ser del tipo (a) o (b) como ya vimos. La página envía la cadena como respuesta mediante el comando echo””. En el caso de recibir la (a), de NO REALIZADO, el Cliente procesa la cadena y actúa sobre sus pines de salida y luego confirma con:
http://www.guscir.hol.es/requerimiento.php?consulta=2
es decir coloca el valor 2 en consulta. Con esto la página Php lo que hace es modificar la cadena del archivo archivocontrol.txt para concatenarle el REALIZADO más la fecha y hora. Y devuelve un “okey” al Cliente. De esta manera cuando el cliente vuelva a consultar con consulta=1 y la cadena de respuesta sea:
sal1=1sal2=1sal3=0sal4=0REALIZADO-2016-01-07 | 05:4:21 | tipo (b)
El Webclient sabrá que el cambio ya fue realizado y no tendrá que modificar las salidas.
(Porción de código de requerimiento.php ya publicado)
1 2 3 4 5 6 7 8 9 10 11 12 |
if(!empty($_GET['consulta']) && $_GET['consulta']==2) // El cliente quiere logear algo o confirmar algo en el server, en este caso validar el cambio de las salidas // en el cliente de acuerdo al nuevo estado de las salidas. Aqui podemos mandar un Mail o actualizar un objeto o elemento en la pagina // para que al entrar nuevamente el usuario se de cuenta que su cambio se realizó, en este caso el cliente reflejo el cambio de las salidas { $linea=substr($linea,0,24); // Captura el estado de las salidas para filtrar el NO REALIZADO $ar=fopen("archivocontrol.txt","w") or die("Problemas en la creacion"); date_default_timezone_set('America/Argentina/Cordoba'); // Actualiza a zona horaria America ya que sino devuelve hora España $time = date("Y-m-d | h:N:s |", time() ) ; fputs($ar,$linea."REALIZADO"."-".$time); // Reescribe archivo con la indicación de realizado //fputs($ar,"br"); fclose($ar); echo "okey"; } |
Código Arduino con Shield Wiznet W5100
A los efectos de simplicidad, se mostrarán por el puerto serial las cadenas recibidas desde el servidor, como filtrar las subcadenas de cada salida para después aplicarlas a los pines que desea el usuario. Hay que tener en cuenta que la placa Wiznet 5100 utiliza los pines 4,10,11,12 y 13 para comunicarse con ARDUINO 1, por lo que debe evitarse su uso para nuestras aplicaciones. El 4 Se utiliza para la SD card del shield, si es que se usa.
10 Habilitación ETCH de la placa Ethernet
11,12,y 13 son comunicación SPI con la placa ( Mosi, Miso,Clk).
El código está muy bien documentado y he optado por simular las salidas digitales, es decir que el estado de las salidas saldrá impreso por la terminal de consola de Arduino y las cadenas de respuesta debidamente filtradas. En la consola de Arduino se verán no solo las respuestas completas del servidor, sino también los inicios de conexión, los intentos fallidos, las cadenas filtradas de respuesta y también la simulación de cada salida.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
/* Web client Peticiones GET a Hosting gratuito Modifica el estado de 4 salidas digitales en forma diferida */ #include <SPI.h> #include <Ethernet.h> // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; char server[] ="www.guscir.hol.es"; // Set the static IP address to use if the DHCP fails to assign IPAddress Myip(192, 168, 1, 177); // Initialize the Ethernet client library // with the IP address and port of the server // that you want to connect to (port 80 is default for HTTP): EthernetClient client; unsigned long start=millis(); unsigned long periodoConexion=30000; // 30 segundos cada 1/2 minuto el Cliente llama al server boolean flagCon=0; // Flag de conexión de conexión válida servidor boolean flagMod=0; // Flag de modificación de salidas digitales realizadas String cadConsulta= "GET /requerimiento.php?consulta=1 HTTP/1.1"; String cadRespuesta="GET /requerimiento.php?consulta=2 HTTP/1.1"; String cadena=""; boolean httpRequest (String cad ); // Función que se encarga de conectar al servidor Hosting y devuelve true o false si se conecto o no void respuesta(); // Funcion de esperar la respuesta y recibir la cadena HTML completa que responde el servidor void modificarSalida(String cade); // funcion que procesa el estado de las salidas, las separa y actua sobre las salidas void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); // start the Ethernet connection: Primero intentamos por DCHP sino vamos con Myip que es fija if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); // no point in carrying on, so do nothing forevermore: // try to congifure using IP address instead of DHCP: Ethernet.begin(mac, Myip); } // give the Ethernet shield a second to initialize: delay(1000); cadena = cadConsulta; }// setup void loop() { // if there are incoming bytes available // from the server, read them and print them: if(millis()-start>=periodoConexion) { start=millis(); if(flagMod==1) // hay que enviar un GET consulta=2 para notificar que se hizo el cambio { cadena = cadRespuesta; Serial.println("Enviando confirmación cambio realizado"); Serial.println(cadena); flagMod=0; // Se pone a 0 para que no vuelva a notificar y de ahora en mas solo envíe GET con consulta=1 } // El proximo Get notificará al servidor la modificación a la página y el usuario asi podrá saber else { cadena = cadConsulta; Serial.println("Enviando connsulta"); Serial.println(cadena); } if(httpRequest(cadena)==1) { respuesta(); } }// millis } boolean httpRequest(String cad) { flagCon=0; // lo ponemos por default a 0=false Serial.println("connecting..."); // if you get a connection, report back via serial: if (client.connect(server, 80)) { // CONECTAMOS AL SERVER Serial.println("connected"); flagCon=1; // Make a HTTP request: //client.println("GET /requerimiento.php?consulta=1 HTTP/1.1"); Es de esta forma client.println(cad); //client.println("GET /search?q=arduino HTTP/1.1"); //client.println("Host: www.google.com"); client.println("Host: www.guscir.hol.es"); client.println("Connection: close"); // este es como un fin de consulta de GET client.println(); } else { // kf you didn't get a connection to the server: Serial.println("connection failed"); Serial.println("desconectando"); client.stop(); flagCon=0; } delay(2000); // damos tiempo return flagCon; } void respuesta() // lee la respuesta del servidor que lo recibimos igual que la función serial { char c; String rx ; // Cadena de datos recibidos String subx ; // subcadena filtrada // Leemos la respuesta html del servidor, aca viene todo while (client.available()>0) { c = client.read(); rx+=c; // Concatenamos Serial.print(c);// A su vez vamos viendo en el monitor todo lo que recibimos caracter por vez } // while client.stop(); // Detenemos el cliente , es decir cerramos la conexión del cliente cuando termina la respuesta // Si no se hace esto y se vuelve a intentar conectar da FALLA // ANALIZAMOS LA CADENA DE RESPUESTA //********************************** //int longitud= rx.length(); // tomamos longitud de la cadena int pos; // Posición de inicio de subcadena sal1= , por GET consulta=1 int posok; // Posicion de inicio de subcadena okey por GET consulta=2 pos=rx.indexOf("sal1="); // Tomo la posición del inicio de la subcadena posok=rx.indexOf("okey"); //Serial.print("posicion de sal :"); //Serial.println(pos); // Lo que me interesa son los 24 caracteres a partir de la posición detectada que incluye la N de no realizado y la R de realizado if(pos!=-1) // indica que encontro subcadena sal1= { subx=rx.substring(pos,pos+25); // el parametro TO es no inclusivo, por eso es 25 y no pos+24 Serial.print("La subcadena filtrada de interes es :"); Serial.println(subx); if (subx.charAt(24)=='R') //NO Hay que modificar las salidas ya que es la R de realizado { Serial.println("NO HAY QUE MODIFICAR NADA !!!!!!!"); flagMod=0; } if (subx.charAt(24)=='N') // Hay que modificar las salidas ya que es la N de no realizado { Serial.println("HAY QUE MODIFICAR lAS SALIDAS DIGITALES"); modificarSalida(subx); // funcion que procesa el estado de las salidas, las separa } }// pos if(posok!=-1) // indica que encontro subcadena okey en respuesta de consulta=2 { Serial.println ("EL SERVIDOR ACUSO RECIBO DEL CAMBIO"); } } void modificarSalida(String cade) { /* En esta función debemos obtener los valores de las 4 salidas, 0 o 1 y luego de acuerdo a dicho estado modificar los pines digitales en nuestra aplicación que se han obviado y solo se realizará el procesamiento dejando a su ellección la aplicación */ int salida1,salida2,salida3,salida4; salida1=cade.charAt(5)-'0'; salida2=cade.charAt(11)-'0'; salida3=cade.charAt(17)-'0'; salida4=cade.charAt(23)-'0'; Serial.print("SALIDA 1: "); Serial.println(salida1); Serial.print("SALIDA 2: "); Serial.println(salida2); Serial.print("SALIDA 3: "); Serial.println(salida3); Serial.print("SALIDA 4: "); Serial.println(salida4); flagMod=1; } |
Caracteristicas del Software
boolean httpRequest (String cad ) Es una función que se encarga de realizar la conexión al servidor y realizar las consultas GET que pueden ser, como vimos , de dos tipos:
String cadConsulta= «GET /requerimiento.php?consulta=1 HTTP/1.1»; De consulta
String cadRespuesta=»GET /requerimiento.php?consulta=2 HTTP/1.1″; De confirmación
Estas cadenas serán pasadas como argumento de la función httpRequest(). La función devuelve True(1) o false(0) de acuerdo a si se pudo conectar al servidor o no.
void respuesta() Es una función encargada de recibir las respuestas des servidor, analizar si las respuestas son las cadenas de salida o los acuses de recibo sobre el servidor de los cambios realizados por elWebClient. Filtra la cadena total de respuesta que es html y extrae las subcadenas útiles para la aplicación, como son las de tipo (a), (b) o el “okey” de acuse de recibo en el Cliente.
void modificarSalida(String cade) Esta función filtra aún mas la Subcadena útil y extrae el 1 o el 0 de cada salida, y en este caso, saca por consola el estado de cada salida.
Simplificando el funcionamiento se vería de la siguiente manera:
Capturas en el Monitor serie de Arduino WebClient
Consulta WebClient, donde No hay Modificaciones
Consulta WebClient, donde hay Modificaciones que realizar
Consulta WebClient de Confirmación y acuse de recibo
Espero que les sea de utilidad, Los códigos de expusieron para su análisis. En particular el código Arduino presenta en su monitor serial toda la información para el Debugger del mismo. Es de notar que si el Arduino se apaga por alguna razón y luego emite su consulta va a recibir que ya esta Realizado y no modificará el Estado de sus salidas. Esto se puede solucionar de varias maneras, incluso el Arduino puede no basarse en el resultado de REALIZADO/NO REALIZADO para actuar sobre las salidas, es decir puede actuar siempre independiente de este estado, es decir cada vez que recibe la cadena de salidas puede llamar a la función de modificarSalidas() y «refrescarlas». La idea fue hacer este proyecto para ver las múltiples aplicaciones que puede tener. Si bien se guardó la información en el sitio en un archivo de texto, nada impide armar una Base de Datos en MySql y registrar cada cambio del usuario que realiza en las salidas y obtener la cadena directamente de un registro de dicha base. Las páginas están montadas en el servidor gratuito , por lo tanto solo tienen que bajarle el software al Arduino y disponer de una placa Ethernet Shield o ArduinonEthernet para probar esta aplicación.
Bastante bien,,,para la ip dinamicas se podría usar tranquilamente un DnsDinamico como NO-IP
Usted lo ha dicho, usando un servidor DNS podemos evitar el problema de la Ip pública.Gracias
Muy completo el tutorial.
Una pregunta, ¿En que parte del código se indica a que pines de Arduino están conecatadas las salidas que quieres manejar?.Gracias!
Hola, las salidas no las inclui ya que quería mostrar el resto