f

fullvice

Usuario (Argentina)

Primer post: 22 jun 2011Último post: 22 abr 2014
2
Posts
20
Puntos totales
335
Comentarios
G
Guardar temperatura en servidor web
InfoporAnónimo4/22/2014

Hola a todos ! Hoy les presento un tutorial de "Como obtener la temperatura remotamente y guardarla en un servidor web". Que vamos a necesitar: 1- Un Arduino (en mi caso UNO R3) 2- Un Shield Ethernet compatible 3- Un sensor de temperatura y/o humedad (en mi caso DHT-11) 4- Una Protoboard o PCB donde soldar 5- Un Router/Switch 6- Un Servidor Web (que tenga MySQL) Primero, vamos a subir el código del Arduino, pero antes vamos a darle una revisión para que se entienda que va a hacer y por si quieren modificar algo del mismo. El código de la Arduino (UNO R3) que yo utilice, es el siguiente: #include <SPI.h> #include <Ethernet.h> #include <DHT.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Dirección MAC que deseamos asignarle al Ethernet Shield IPAddress ip(192, 168, 0, 101); // IP del Ethernet Shield de la arduino que queremos que utilice char serverName[] = "192.168.0.191"; unsigned int puertoWeb = 80; // Web a navegar - IP del Servidor y Puerto EthernetClient client; // Cliente Ethernet DHT dht; // Definir Variable del Sensor unsigned long tiempoEspera = 600000; // Espero 10 minutos por cambios de temperatura en el hambiente char* modelos[4] = {"DHT11", "DHT22", "AM2302", "RHT03"}; void setup(){ Serial.begin(115200); // Inicializacion del USB - Maxima velocidad para maxima velocidad de refresco Serial.println("Iniciando..."); // String serial para saber que esta iniciando dht.setup(A0); // Inicializacion del Sensor Serial.print("Modelo detectado: "); Serial.println(modelos[dht.getModel() - 1]); Ethernet.begin(mac, ip); // Inicializacion del Ethernet Shield pinMode(13,OUTPUT); // Que no moleste/gaste el LED que siempre se prende... delay(1000); // Le damos 1 segundo de espera para que haga lo que necesite respecto a conexion de red Serial.println("Iniciado"); } void loop(){ Serial.print("Esperando "); Serial.print(dht.getMinimumSamplingPeriod()/1000); Serial.println(" segundos para continuar"); delay(dht.getMinimumSamplingPeriod()); // Delay minimo que necesita el Sensor para volver a funcionar Serial.println("Obteniendo Temperatura y Humedad..."); float temperatura = dht.getTemperature(); // Leo la temperatura float humedad = dht.getHumidity(); // Leo la humedad Serial.print("Temperatura: "); // Envio por USB los datos si los quiero ver al instante Serial.print(temperatura); Serial.print("; Humedad: "); Serial.println(humedad); String pedido = "GET /habitacion.php?t="; // Creo la línea de texto donde va a enviar la informacion y de que forma (GET) pedido += temperatura; pedido += "&h="; pedido += humedad; pedido += " HTTP/1.0"; Serial.println("Enviando datos HTTP para guardar..."); client.connect(serverName, puertoWeb); // Me conecto con el servidor para enviar - Puerto Web (80) client.println(pedido); // Envio client.println(); Serial.println("Enviados"); client.stop(); // Detengo el cliente y cierro conexion Serial.print("Esperando "); Serial.print(obtenerTiempo(tiempoEspera)); Serial.println(" para volver a empezar"); delay(tiempoEspera); // Espero el tiempo especificado anteriormente para enviar la informacion (Delay respecto a posible cambios de temperatura) } String obtenerTiempo(unsigned long milisegundosOriginal){ unsigned long nuevoTiempo = milisegundosOriginal/1000; char* nomenclatura[3] = {" segundo(s)", " minuto(s)", " hora(s)"}; String resultado; if(nuevoTiempo < 60){ resultado += nuevoTiempo; return resultado + nomenclatura[0]; }else if(nuevoTiempo >= 60 && nuevoTiempo < 3600){ resultado += (nuevoTiempo/60); return resultado + nomenclatura[1]; }else if(nuevoTiempo >= 3600){ resultado += (nuevoTiempo/3600); return resultado + nomenclatura[2]; }else{ return "TIEMPO máximo EXEDIDO !"; } } Las primeras 3 líneas (#include) son la inclusión de las librerías para que funcione nuestro código. La primera (SPI) es para el funcionamiento de Ethernet Shield (w5100). La segunda (Ethernet) es para el funcionamiento de la comunicación entre el Ethernet Shield y la Red. La tercera (DHT) es para el funcionamiento del sensor de Temperatura y Humedad. Buscar la librería en GitHub como: https://github.com/markruys/arduino-DHT Las siguientes 2 líneas representan la Dirección MAC e IP del Ethernet Shield. (Verificar que no se duplique la IP/MAC en la Red !!!) Estas líneas, representan la Dirección IP del Servidor al cual quiero acceder para guardar los datos con su respectivo puerto (default 80), y la siguiente es la declaración del cliente Ethernet, llamado "cliente". Declaramos la variable que utilizaremos para acceder al sensor. Recuerden que esta forma de Declarar la brinda el desarrollador de la librería, ya que esta no es nativa del programa que brinda Arduino. Aquí declaramos el tiempo (en milisegundos) que deseamos que aguarde antes de repetir el ciclo de obtención de temperatura/humedad y guardarlo en la Base de Datos. (Mas abajo se muestra como obtener el tiempo en milisegundos) Una cosa importante que hay que destacar es que usamos el tipo de variable "unsigned long". Esto permite que el numero no tenga "negativos" y, por ende, tiene mas numeros positivos. También, usamos "long" por la cantidad de "0" que podemos poner. Para mas información: http://arduino.cc/es/Reference/UnsignedLong Esta línea permite definir, en "texto", el modelo del sensor que va a detectar la librería DHT. Debemos hacer esto ya que la función que devuelve el modelo, solo lo indica con números de 0 a 4. Recordar que esta función es la primera en ser recorrida antes de comenzar el bucle infinito. Aquí se inicializan por única vez las distintas librerías y demás cosas que necesitamos para el correcto funcionamiento. Iniciamos el USB en su máxima velocidad para una rápida lectura de la información, y luego, mostramos que ha comenzado el proceso de Inicialización. Inicializamos el sensor, colocando entre paréntesis, el PIN que deseamos utilizar. En este caso debe ser si o si uno "analógico" por el tipo de información (escala) que responde el sensor. Luego enviamos por USB el modelo detectado. Habrán notado que dice: "dht.getModel() - 1"; El "- 1" se debe a que esa función responde de 0 a 4, pero el "0" no es un modelo, sino una notación interna que usa la librería para darse cuenta que tiene que obtener el modelo. Si nosotros no ponemos "- 1", estaría todos nuestros modelos de la línea 15, corridos uno a la derecha. Ej.: si tenemos conectado el "DHT11", nos devolvería "DHT22". La primera línea nos permite inicializar el Ethernet Shield, con su respectiva Dirección MAC e IP. La siguiente es para, simplemente, apagar el LED del puerto 13 que siempre queda prendido. La 3 línea es un retraso para darle tiempo al Ethernet Shield, que realice cualquier cosa que tenga que hacer antes de poder utilizarlo. Y la última línea es para informar por USB que termino la Inicialización. Recordar que esta función "loop()" es la que siempre estaremos en bucle infinito, aquí se ejecuta todo el código que necesitamos procesar infinitamente. Enviamos por USB el tiempo que necesita esperar el sensor para poder procesar de nuevo la temperatura y humedad, y lo ponemos en esa espera. (Si, necesita esperar un tiempito para otra muestra de temperatura y humedad, que el autor de la librería se encargó de buscar, y automáticamente nos dice cuanto es). Obtenemos la temperatura y la humedad, y lo guardamos en las respectivas variables. Tienen que ser "float" porque es analógico, recuerden que estamos en el PIN analógico "0". Informamos por USB la temperatura y humedad. Recuerden que no se puede enviar variables con "texto" de forma combinada. Esta es una de las partes mas importantes, aquí es donde se arma la información a enviar. Si tienen conocimientos de RED y/o Webs (Headers HTTP) van a poder entender a la perfección estas líneas. La primer línea define la variable "pedido" como "String" y comienza con un valor de: "GET" (tipo de envío) "/habitacion.php" (Dirección Web que tendríamos que acceder hacia el server para poder interactuar con el archivo) y luego vienen las variables: "?t=" (Temperatura) y "&h=" (Humedad). Por como se conforman los Headers HTTP, debemos agregar al final y con un espacio: " HTTP/1.0". Si deseáramos enviar más información en ese "pedido", deberíamos colocar la variable, por ejemplo: "&a=" y el ID de la habitación donde se obtuvo información (Suponiendo de que tenemos varios sensores en nuestro Arduino, pero deberíamos procesar eso), luego agregar la información que corresponda a esa variable "&a=", por ejemplo, "pedido += habitacion;"; Y así seguir. Enviamos por USB la confirmación que se comenzará a enviar los datos que procesamos en las líneas anteriores. La primera línea, respecto a la variable "client", nos permite establecer conexión con el Servidor Web que nos queremos conectar, la siguiente realiza el envío de los datos, y la última se requiere para terminar el HEADER antes mencionado. Recordar que si La primera línea, nos informa por USB que se realizó el envío (no confirma si fue exitoso, pero informa que se pasó por la parte del código que realiza el envío), luego, para evitar conexiones o procesamientos raros respecto al Router/Switch y Servidor, se cierra la conexión. Para finalizar, se envía por USB el tiempo que deseamos esperar antes que se repita todo el proceso, y comenzamos la espera con la conocida función "delay". Para hacerlo un poco mas legible, decidí crear una simple función donde, al obtener el tiempo, nos devuelva un "texto" que nos diga segundos/minutos/horas que debemos esperar. En la siguiente parte explicaré como se realiza. Para crear una función, cabe aclarar que es igual que en C/C++, lo que se necesita especificar son 3 cosas: Qué tipo de dato voy a devolver (INT, FLOAT, LONG, DOUBLE, STRING, ETC.), si no devuelvo coloco "VOID", en nuestro caso "String", ya que lo utilizamos para enviar por USB informando el tiempo de espera. El segundo es el nombre, en nuestro caso "obtenerTiempo". Y el tercero, es que tipo de dato acepto, para nosotros seria "unsigned long" y el nombre que le quiero dar, "milisegundosOriginal". Si no necesitase aceptar esto último, simplemente, luego del nombre, dejo los parentesis vacios: "obtenerTiempo()". No olvidarse abrir y cerrar llave. En nuestro caso particular, no es necesario realizar la última declaración del "unsigned long milisegundosOriginal" porque es una variable global, por ende, puedo accederla igual, pero si llego a reutilizar esta función, tendría que si o si enviarle el tiempo que deseo. Realizamos la declaración de variables. La primera corresponde a un nuevo tiempo que voy a guardar, retirando los últimos 3 números que, como son milisegundos, no me son necesarios. La segunda declaración corresponde a los 3 tipos de "tiempos" que puedo obtener: "segundos", "minutos", "horas". Y la última declaración, corresponde al "texto" donde voy a guardar mi resultado de la función para devolverlo a donde se me pidió. Cabe aclarar que seguimos utilizando "unsigned long" ya que mi tiempo, siempre fue ese tipo de dato; También que luego de la división, estamos hablando en segundos, no milisegundos. (Ya es mas legible para manipular) Realizamos nuestros "if" necesarios para separar por "tiempos" lo que vamos a devolver. El primer "if" corresponde a que estamos en segundos, el segundo "if" (else if) corresponde entre 1 minuto y 59 minutos, y el último "if" (else if) corresponde a más de 1 hora. El último "else" no sería muy accesado, ya que valores negativos no podemos obtener, y, en el caso que nos excedamos del valor máximo que puede guardar "unsigned long" produciríamos un "overflow" haciendo que el dato guardado en "milisegundosOriginal" no sea el correcto, osea, devolvería cualquier dato, no mayor a nuestro máximo por tipo de dato, y tampoco negativo; seguiría siendo válido, pero todo es por seguridad. De igual forma, cabe aclarar que siempre estamos con el mismo tipo de variable (unsigned long) así que aquí no podría fallar mucho, pero recordemos que si deseamos reutilizar la función, podríamos estar hablando de datos más grandes que un "unsigned long". También recordar que, para poder retornar (return) un dato, debemos hacerlo por separado, osea, no podemos retornar una variable con texto (variable + "texto", por eso utilizamos la variable antes creada (resultado) y le agregamos el nuevo valor de tiempo más la nomenclatura que le corresponda (segundos, minutos, horas). Para poder obtener los milisegundos correctos para nuestra espera, vamos a utilizar la tecnología, para evitarnos confundirnos en las cuentas. Para eso, accedemos a nuestro mejor amigo Google, y en el buscador escribiremos el tiempo que deseemos, por ejemplo: "10 minutos a milisegundos". Pueden reemplazar "minutos" por "horas", "segundos", "dias", etc... Acabamos de finalizar todo el código respecto a Arduino. Ahora vamos a comenzar con SQL. Primero debemos tener el Servidor Web, para esto se pueden utilizar nativos (IIS/Wind0ws o LAMP/Linux) o algunos ya compilados como XAMPP, WampServer, y otros. Para la instalación del que deseen, utilicen páginas de ayudas oficiales ya que son muy simples estos últimos nombrados. Lo importante de estos Servidores Webs es que vengan con PHP y phpMyAdmin (Lector de Base de Datos Web). Debemos crear una base de datos con el nombre que deseen, en mí caso "arduino", y el código de la base de datos es: CREATE DATABASE IF NOT EXISTS `arduino` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE `arduino`; Si utilizan phpMyAdmin: Para la tabla donde se guardarán los archivos, vamos a llamarla "sensor_temp_hum": CREATE TABLE IF NOT EXISTS `sensor_temp_hum` ( `id` int(11) NOT NULL AUTO_INCREMENT, `temperatura` int(3) NOT NULL, `humedad` int(2) NOT NULL, `fecha_hora` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=97 ; Asi ya finalizamos la Base de Datos. Ahora continuamos con el código PHP que va a agregar los datos a la Base de Datos. Para eso, vamos a crear un archivo PHP con el siguiente nombre: "habitacion.php" y, copiamos y pegamos el siguiente código dentro del archivo. <?php $ipServidor [/color][color=#007700][/color][color=#007700]= '127.0.0.1'; [/color][color=#007700][/color][color=#0000BB]$usuario = 'root'; [/color][color=#007700][/color][color=#0000BB]$contraseña = ''; [/color][color=#007700][/color][color=#0000BB]$db = 'arduino'; [/color][color=#007700][/color][color=#0000BB]mysql_connect($ipServidor,$usuario,$contraseña); [/color][color=#007700][/color][color=#0000BB]mysql_select_db(arduino); [/color][color=#007700]unset([/color][color=#0000BB]$ipServidor,$usuario,$contraseña); [/color][color=#007700][/color][color=#0000BB]$temperatura = $_GET['t']; [/color][color=#007700][/color][color=#0000BB]$humedad = $_GET['h']; [/color][color=#007700][/color][color=#0000BB]$sql = 'INSERT INTO `sensor_temp_hum` SET humedad = "'.mysql_real_escape_string($humedad).'", temperatura = "'.mysql_real_escape_string($temperatura).'", fecha_hora = NOW()'; [/color][color=#007700][/color][color=#FF8000]/* [/color][color=#0000BB]echo "<br>"; [/color][color=#0000BB]echo $sql; */ [/[/color][color=#0000BB]color][color=#0000BB]mysql_query($sql); [/color][color=#007700][/color][color=#0000BB]mysql_close(); [/color][color=#007700][/color][color=#0000BB]?> La primera línea y la última de todas, nos permite ejecutar código PHP. Así especificamos que el código va a ser PHP. Las siguientes 3 líneas se utilizan para realizar la conexión a la Base de Datos del Servidor Web donde este alojada, sabiendo así su "IP", "usuario", y "contraseña". Dependiendo de qué servidor hayan instalado, en el proceso de instalación de MySQL les pedirá una contraseña (algunos piden, otros no). Si se les pidió que ingresaran una contraseña, esa misma deben ingresar en la variable "$contraseña" entre las comillas simples " '' ". La siguiente línea nos permite especificar la Base de Datos (nombre) que vamos a utilizar, en nuestro caso 'arduino', si es que no utilizaron otro. Las siguientes 2 líneas, nos permite conectarnos a la Base de Datos y elegir la Base de Datos que vamos a utilizar. Una vez realizada la conexión, borramos las variables que las mantienen, para evitar cualquier cosa respecto a seguridad y para borrarlas de memoria RAM (a pesar que cualquiera podría abrir para editar este archivo...). Para obtener la temperatura y humedad, debemos leer el array "$_GET" que nos brindará de todos los "GETS" que hayamos recibido, en nuestro caso "$_GET['t']" y "$_GET['h']". Si en los pasos de Arduino, agregaron alguna variable, deben especificarla ahora. En el ejemplo de "&a=" que yo mencioné, deberíamos agregar alguna variable que nos sea de referencia y guardarla, así: "$habitacion = $_GET['a'];". Luego creamos la variable que enviará la información a la Base de Datos para poder guardarla. En este paso debemos agregar las demás variables que hayamos creado, como "$habitacion" de la siguiente manera: luego de "fecha_hora = NOW()" deben colocar una "," y la variable como la hayan nombrado en la Tabla creada anteriormente: `fecha_hora = NOW(), habitacion = "'.mysql_real_escape_string($habitacion).'"´ y así seguir concatenando. Para finalizar, utilizamos la función que envía sentencias SQL con su respectiva sentencia ($sql): "mysql_query($sql)" y cerramos la conexión con "mysql_close();" Cabe aclarar que la función "mysql_real_escape_string" utilizada sirve para evitar inyecciones SQL. Para más información leer: www.php.net/manual/es/function.mysql-real-escape-string.php La única forma de ver los datos es accediendo a la Base de Datos, a la tabla misma. Esto lo logramos accediendo a la IP del Servidor Web y con la dirección "/phpMyAdmin". En mi caso, que el servidor es local a donde voy a acceder (es la misma PC) accedo de la siguiente manera: localhost/phpMyAdmin/. Esto se debe colocar donde ponemos las direcciones web como "www.google.com", "www.clubarduino.com.ar", etc... Dependiendo en la antes mencionada configuración al momento de instalar, quizás deban ingresar usuario y contraseña, colocan "root" como usuario y la contraseña que escribieron (si no les pidió contraseña, dejen en blanco). Una vez dentro y conectados en phpMyAdmin, veremos las Bases de Datos a la Izquierda, seleccionamos "arduino" (si no le cambiaron el nombre) y se desplegarán tablas, deberíamos ver una sola con el nombre "sensor_temp_hum", le hacemos click. Una vez dentro, veremos los datos si es que se ingresaron datos mediante Arduino alguna vez... Recordar que arduino envía datos directamente cuando finaliza su inicialización y obtención de datos. En el caso que no guarde nada, pero si vean por USB que funciona, deben borrar los símbolos de comentar de PHP: "/* */", luego traten de acceder al archivo PHP que creamos, mediante la siguiente URL (si están en la misma PC que el Servidor): "http://127.0.0.1/habitacion.php?t=25&h=50". Así podremos ver si hay algún error o no. Si no arrojó ningún error, debería darnos un texto largo, igual al que escribimos en la variable "$sql" pero con su información completada. Si falta algún dato, ejemplo, "humedad = " y no muestra ningún número, está funcionando mal alguna variable de PHP, fijarse que no tiene otro nombre. Una vez arreglado, volver a agregar "/* */" donde corresponde. Los invito a participar del foro argentino de Arduino: www.clubarduino.com.ar pasense por el foro !!! Y gracias @Cavul por mostrarme que estaba mal para poder postear ! Les dejo el link al Tema y la comunidad: http://www.taringa.net/comunidades/arduinga/8628888/Aporte-Guardar-temperatura-en-servidor-web.html Saludos !

10
0
L
La situacion que no queremos ver o no nos muestran !
OfftopicporAnónimo6/22/2011

Hola a todos los taringeros ! Antes que nada quiero avisar que NO es un post para personas susceptibles a cosas muy fuertes ! Me dejo perplejo y a su ves llorando... La idea de este post es cambiar un poquito la mirada y ver (son solo 7 minutos) lo que pasa y no queremos ver o nos olvidamos, y tambien reflexionar un poco... Espero que no se pongan a comentar cosas negativas, porque van a ser borrados y bloqueados al instante...

10
1
PosteameloArchivo Histórico de Taringa! (2004-2017). Preservando la inteligencia colectiva de la internet hispanohablante.

CONTACTO

18 de Septiembre 455, Casilla 52

Chillán, Región de Ñuble, Chile

Solo correo postal

© 2026 Posteamelo.com. No afiliado con Taringa! ni sus sucesores.

Contenido preservado con fines históricos y culturales.