Hola a todos, estoy realizando un proyecto en el cual la interacción con Arduino sera mediante la web, aun no tengo escrito el código fuente del proyecto porque he decidido probar cada modulo por separado para ir depurando de cierta forma, ya que el proyecto contempla muchos módulos, el problema radica en que programe mi Arduino UNO para servir una simple aplicación web que permite apagar y encender un ventilador a un porcentaje de velocidad especifico, todo bien hasta ahí, cuando enciendo mi Arduino obtiene su dirección IP y accedo a la aplicación mediante la misma en el navegador de una maquina en la red LAN, pero cuando he decidido probarlo con un amigo que esta en la red publica, es decir la red WAN, el codigo HTML de la aplicación llega incompleto, en el ejemplo "WebServer" que trae la librería Ethernet.h aparece un delay(1) con un comentario que indica que se usa para esperar que el navegador reciba el Response, resulta que lo use y no sirvió, solamente me sirvió al colocar un delay(5000), no puedo dejar a mi Arduino estático por 5 SEGUNDOS solo para servir una simple pagina web, también probé usando EthernetClient.flush() y nada, ¿Sera algún fallo de la librería? Estuve viendo el código fuente de la librería w5100.h a ver si podría ser algo relacionado con los sockets y nada ¿Existe alguna otra librería mejorada? ![]()
Veo muy normal que en Internet las respuestas se dilaten mucho más que una red local.
Puedes probar a lanzar un ping a una máquina de red local, y responderá en un par de milisegundos, mientras que si lanzas el ping a www.google.es la cosa se te irá fácil por encima de los 100.
Si no quieres dejar el Arduino parado durante 5 segundos, podrás seguir haciendo otras cosas mientras va llegando la respuesta completa.
chema_zgz:
Veo muy normal que en Internet las respuestas se dilaten mucho más que una red local.
Puedes probar a lanzar un ping a una máquina de red local, y responderá en un par de milisegundos, mientras que si lanzas el ping a www.google.es la cosa se te irá fácil por encima de los 100.Si no quieres dejar el Arduino parado durante 5 segundos, podrás seguir haciendo otras cosas mientras va llegando la respuesta completa.
¿Como podría hacer que mi Arduino siga haciendo otras cosas? Creo que lo que necesito es que algo me indique cuando todo ha sido ya enviado al cliente para poder llamar a EthernetClient.stop()
Si el problema es que que antes de hacer el client.stop(), el Arduino siga ejecutando el loop, siempre puedes probar a controlar el tiempo con los millis().
Yo probaría para empezar algo así como lo siguiente, a ver si no te diera problemas.
Declaras unsigned long tiempopas, y byte controltiempo=0 en el setup
Luego asignas tiempopas=millis() y controltiempo=1 en la parte de código en el que quieras empezar a contar los 5 segundos, quizá justo después de enviar el último carácter del html al cliente.
Después controlas el tiempo pasado, y que el control de tiempos esté activado, en vez de hacer un delay
if (((millis()-tiempopas)>5000) & (controltiempo==1)){client.stop();controltiempo=0;}
Te tendrías que asegurar que en cada loop, las condiciones previas lleguen hasta ahí. Con el ejemplo de WebServer que he ojeado, creo que sí lo haría (ya te quedaria a ti verificarlo)
Pero ojo con esto, porque a la hora de programar, es más fácil parar todo, hasta esperar respuesta, que dejar el loop rodando. En ese caso hay que pensar más, no vaya a ser que en los ciclos de loop, el programa vuelva a entrar en sitios que no querríamos.
chema_zgz:
Si el problema es que que antes de hacer el client.stop(), el Arduino siga ejecutando el loop, siempre puedes probar a controlar el tiempo con los millis().Yo probaría para empezar algo así como lo siguiente, a ver si no te diera problemas.
Declaras unsigned long tiempopas, y byte controltiempo=0 en el setup
Luego asignas tiempopas=millis() y controltiempo=1 en la parte de código en el que quieras empezar a contar los 5 segundos, quizá justo después de enviar el último carácter del html al cliente.
Después controlas el tiempo pasado, y que el control de tiempos esté activado, en vez de hacer un delay
if (((millis()-tiempopas)>5000) & (controltiempo==1)){client.stop();controltiempo=0;}
Te tendrías que asegurar que en cada loop, las condiciones previas lleguen hasta ahí. Con el ejemplo de WebServer que he ojeado, creo que sí lo haría (ya te quedaria a ti verificarlo)
Pero ojo con esto, porque a la hora de programar, es más fácil parar todo, hasta esperar respuesta, que dejar el loop rodando. En ese caso hay que pensar más, no vaya a ser que en los ciclos de loop, el programa vuelva a entrar en sitios que no querríamos.
Tienes razón en lo que dices y de hecho lo agradezco mucho, y podría ser una alternativa, el problema esta en que cuando un usuario este muy lejos de mi red, se comprenderá el retardo de 5 segundos, pero cuando este conectado a mi misma red también tendría que esperar 5 segundos y se notara la ineficiencia, necesitaría mas bien algo que me indique que todos los bytes ya fueron enviados antes de desconectar el socket.
A ver si esta noche pruebo ese código de ejemplo y te puedo decir, porque hay algo que no me cuadra, y me surge la curiosidad (soy autodidacta en esto, y voy aprendiendo a base de toparme con los problemas y analizarlos).
No sé bien el detalle de cómo funciona.
-
En teoría, si espera 1 ms, y luego cierra, es porque envía la página y no espera respuesta del cliente. En tal caso pienso que igual daría que el cliente tarde en recibirlo 5 que 5000 ms, ya le llegaría, cosa que no ocurre, según entiendo de tu primer mensaje.
-
Si el cliente no responde nada cuando recibe la página, no habrá forma de saber si lo ha servido bien. Habría que analizar si envía algo después de enviarle la página. Eso se podría analizar, monitorizando una posible respuesta por el puerto serie, pero me suena que después de cargar una página web el cliente no manda un OK ni nada.
-
Si esperamos 5000, y luego cerramos, no debería retrasarse la visualización en el cliente hasta el stop, a no ser que el client.stop() implique algo más que el cierre de conexión.
Son tres cosas que intentaré aclararme. Te contaré si saco conclusión, aunque con suerte, habrá alguien que pueda aclarar el asunto antes.
He encontrado este ejemplo, básico de interacción. Supongo que el tuyo será similar, y que si retardas siempre los 5 segundos con el delay, el efecto en red local puede ser de "sistema perezoso o cargado"
http://diymakers.es/crear-servidor-web-con-arduino/
Nada, que no voy a poder resolverte la cuestión. He simulado la situación hasta donde he podido, y lo que he verificado es todo lo que tú dices:
-
el navegador no muestra la página hasta que cierras el socket, así que si lo retrasas 5 segundos, sea con delay, sea con un contador de millis, la página se hará perezosa en red local. Con el contador lo que ganas es que puedes hacer otras cosas, pero sigues con la ralentización de la página
-
he ojeado varios proyectos preparados para servir páginas en Internet, y en todos tienen el delay de 1 entre la impresión del cierre de la página y el client.stop. De ahí me extraña tu problema, pero no tengo configurada la red de casa para poder acceder desde fuera, y no puedo hacer las pruebas.
A ver si hay suerte y entra al quite alguien "más autorizado".
chema_zgz:
Nada, que no voy a poder resolverte la cuestión. He simulado la situación hasta donde he podido, y lo que he verificado es todo lo que tú dices:
el navegador no muestra la página hasta que cierras el socket, así que si lo retrasas 5 segundos, sea con delay, sea con un contador de millis, la página se hará perezosa en red local. Con el contador lo que ganas es que puedes hacer otras cosas, pero sigues con la ralentización de la página
he ojeado varios proyectos preparados para servir páginas en Internet, y en todos tienen el delay de 1 entre la impresión del cierre de la página y el client.stop. De ahí me extraña tu problema, pero no tengo configurada la red de casa para poder acceder desde fuera, y no puedo hacer las pruebas.
A ver si hay suerte y entra al quite alguien "más autorizado".
Gracias por tu esfuerzo, pero si yo tambien ya he hecho varias cosas, sino estamos equivocados, entonces eso de "Conecta tu Arduino a Internet" es una estafa jajajajaja ![]()
No creo, tendrá su cosa. A ver si un día me pongo a tocar el router para dejar algo de salida fuera en casa, y puedo probar alguna cosita más.
De momento la placa con el shield y el sketch de servidor está montada esperando.
Si encuentras solución, ya comentarás.
Hola. La primera impresión es que debería ser suficiente con un client.flush() antes de cerrar el puerto, aunque dices que eso ya lo probaste. ¿Podrías poner tu código a ver si inspira alguna idea más?
noter:
Hola. La primera impresión es que debería ser suficiente con un client.flush() antes de cerrar el puerto, aunque dices que eso ya lo probaste. ¿Podrías poner tu código a ver si inspira alguna idea más?
No coloco codigo porque el que tenia de prueba lo elimine, pero ya probe el metodo EthernetClient.flush() y nada, de hecho al llamar a EthetnetClient.stop() automaticamente se llama al metodo EthernetClient.flush(), simplemente mi duda es si alguien sabe porque ocurre esto de que en realidad EthernetClient.stop() no funciona correctamente, quizas sea una limitante del EthernetShield, ¿Alguien sabra de una libreria no oficial para el EthernetShield o especifica para hacer un servidor HTTP con Arduino?
La solución consiste en llamar al método EthernetClient::flush() luego de haber escrito un byte con EthernetClient::write(), con eso me funciono perfecto, aunque se podría también llamar a EthernetClient::flush() al haber escrito una cierta cantidad de bytes que no sea muy grande.