Estación Meteorológica – Capturando Temperatura, Humedad y Luminosidad en MySQL usando Apache, php, Arduino + Ethernet Shield

Uno de nuestros tutoriales mas comentados es Capturando datos en MySQL usando Apache, php, Arduino + Ethernet Shield. Por este motivo quise darle una actualización y al mismo tiempo responder con un ejemplo a muchas de las consultas que nos realizaron en ese tutorial, a continuación los pasos para implementar una estación meteorológica usando el sensor DHT11, un LDR, un Arduino y una Ethernet Shield.

arduino_ethernet_45grados

Este proyecto es similar al anterior, un Arduino Uno con una Ethernet Shield, pero esta vez agregué 2 variables mas, ahora mide temperatura, humedad y luminosidad; estos datos los envía al igual que antes mediante una instrucción GET a un servidor remoto y aquí algo nuevo, el servidor remoto responde en XML indicándole al Arduino cual de los tres leds que posee debe encender o apagar. Les parece interesante?

1. Materiales

  • Arduino Uno Release 3
  • Ethernet Shield
  • Sensor DHT11 o DHT22
  • LDR – Fotoresistencia
  • 3 Leds
  • 2 resistencias de 10K (Ppara los sensores)
  • 3 resistencias de 1k (Para los leds)
  • Cables de conexión
  • Protoboard
  • Servidor Web Apache / PHP / MySQL

2. Diagrama

El proyecto al tener mas componentes se ve un poco mas complejo, pero con observación y cuidado es fácil construir el prototipo en el protoboard.

Hay que tener cuidado con la polaridad de los LEDs y los 4 pines del sensor DHT11 (o DHT22 según sea el caso).

Otro punto importante a recordar es que Arduino usa los pines 10, 11, 12 y 13 (SPI) para comunicarse con la Ethernet Shield por lo cual no pueden ser utilizados como Entrada/Salida.

Arduino-EthernetShield-DHT11-LDR

3. Programación de Arduino

El sketch para Arduino esta basado en los que utilizamos en los tutoriales Midiendo Temperatura y Humedad con Arduino y el sensor DHT11 y  Capturando datos en MySQL usando Apache, php, Arduino + Ethernet Shield, este sketch es una fusion de ambos considerando eso si  que ahora agregamos un sensor mas y 3 leds. Recomiendo leer ambos tutoriales para entender mejor como trabaja este proyecto.

Esquema de Pines

Arduino Pin 2 : Pin 2 del Sensor DHTxx
Arduino Pin 5 : + Led 1
Arduino Pin 6 : + Led 2
Arduino Pin 7 : + Led 3
Arduino Pin A0:  - LDR
Arduino +5V   : + Protoboard
Arduino GRD   : - Protoboard

Las demas conexiones deben verse en el diagrama.

El sketch que pueden copiar y pegar en la interfaz de desarrollo para Arduino  es el siguiente:

// InternetDeLasCosas.cl
// Script que obtiene la temperatura y humedad desde un sensor DHTxx
// y envia estos datos a un servidor web.
// El servidor web procesa los datos y responde en xml indicando que
// Leds deben ser encendidos o apagados en el Arduino
//
// Escrito por @joniuz

#include <SPI.h>
#include <Ethernet.h>
// Libreria para Sensores DHT
#include "DHT.h"

#define DHTPIN 2     // Pin del Arduino al cual esta conectado el pin 2 del sensor

// Descomentar segun el tipo de sensor DHT usado
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Inicializa el sensor DHTxx
DHT dht(DHTPIN, DHTTYPE);

// Configuracion de fotocelda
int fotocelda = 0;
int luminosidad;

// Configuracion Ethernet Shield
// Mac unica de cada EthernetShield
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x4E, 0xD7 };

// Direccion IP Fija en caso de que no pueda obtenerla por DHCP
IPAddress ip(172,17,17,217);

// Direccion del DSN en caso de que no pueda obtenerla por DHCP
//IPAddress myDns(172,17,17,1);

// Inicializa la instancia client
EthernetClient client;

// Direccion del servidor (cambiar por su direccion)
char server[] = "www.iot.cl";

// Ultima conexion al servidor medida en millisegundos
unsigned long ultimaConexion = 0;          
              
// Intervalo en milisegundos entre conexiones
const unsigned long intervaloConexion = 20000;   

// Leds conectados a Salidas Digitales
int led_1; // Umbral de temperatura
int led_2; // Umbral de humedad
int led_3; // Umbral de luminosidad

// Setup de Arduino
void setup() {
  
  // Configura salidas digitales para los Leds
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  
  // Inicializa puerto serial
  Serial.begin(9600);
  Serial.println("######### Internetdelascosas.cl #########");
  Serial.print("Sensor de temperatura-humedad DHT");
  Serial.print(DHTTYPE);
  Serial.println(" / web");
  Serial.println();
  
  // Espera 1 segundo para que se inicie la tarjeta Ethernet
  delay(1000);
  
  // Intenta inicializar la EthernetShield via DCHCP
  Serial.println("Iniciando EthernetShield via DHCP");
  if(!Ethernet.begin(mac)) {
    // Si el DHCP falla, inicia la EthernetShield con IP estatica
    Serial.println("Falla al obtener IP desde DHCP, iniciando con IP estatica");
    Ethernet.begin(mac, ip);
  }
  
  // Imprime la direccion IP de la tarjeta
  Serial.print("Direccion IP: ");
  Serial.println(Ethernet.localIP());
  Serial.println();
  
  // Inicializa Sensor DHTxx
  Serial.print("Iniciando Sensor DHT");
  Serial.println(DHTTYPE);
  Serial.println();
  dht.begin();
  // Espera dos segundos para dar tiempo al sensor mientras obtiene muestra
  delay(2000);
}
// Loop principal
void loop() {
  // Si hay conexion con el servidor
  if (client.connected()) {
    if (client.available()) {
      // Obtiene la respuesta del servidor y busca los tags xml <led_1> <led_2> y <led_3>
      if(client.find("<led_1>")) {
        led_1 = client.parseInt();
      }
      if(client.find("<led_2>")) {
        led_2 = client.parseInt();
      }
      if(client.find("<led_3>")) {
        led_3 = client.parseInt();
      }
      // Imprime valores enviados por servidor
      Serial.println("Valores enviados por servidor");
      Serial.print("Led 1: ");
      Serial.println(led_1);
      Serial.print("Led 2: ");
      Serial.println(led_2);
      Serial.print("Led 3: ");
      Serial.println(led_3);
      // Cierra conexion
      Serial.println("Cerrando conexion..."); 
      Serial.println();
      client.stop();
      // Enciende Leds segun valores
      if (led_1)
        digitalWrite(5, HIGH);
      else
        digitalWrite(5, LOW);
      if (led_2)
        digitalWrite(6, HIGH);
      else
        digitalWrite(6, LOW);
      if (led_3)
        digitalWrite(7, HIGH);
      else
        digitalWrite(7, LOW);
    }
  }
  else if(millis() - ultimaConexion > intervaloConexion) {
    httpRequest();
  }
}
// Fin del loop principal

// Funcion que realiza la conexion http al servidor y obtiene la respuesta
void httpRequest() {
  // Obtiene los datos del sensor DHTxx
  // Obtiene la Humedad
  float h = dht.readHumidity();
  // Obtiene la Temperatura en Celsius
  float t = dht.readTemperature();
  
  // Control de errores, valida que se obtuvieron valores para los datos medidos
  if (isnan(h) || isnan(t)) {
    Serial.println("Falla al leer el sensor DHTxx!");
    return;
  }
  
  Serial.print("Temperatura: ");
  Serial.println(t);
  Serial.print("Humedad: ");
  Serial.println(h);
  
  // Obtiene datos de la fotocelda
  luminosidad = analogRead(fotocelda);  
  
  Serial.print("Luminosidad = ");
  Serial.print(luminosidad);
  Serial.println();
  // Se conecta al servidor en el puerto 80 (web)
  if (client.connect(server, 80)) {
    // Envia el dato al puerto serial
    Serial.println("Iniciando conexion...");
    // Envia el requerimiento via GET
    client.print("GET /sensorarduino.php?id=joniuz&temperatura=");
    client.print(t);
    client.print("&humedad=");
    client.print(h);
    client.print("&luminosidad=");
    client.print(luminosidad);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("User-Agent: Arduino-Ethernet");
    client.println("Connection: close");
    client.println();

    // Actualiza el tiempo en milisegundos de la ultima conexion
    ultimaConexion = millis();
  } 
}

Este sketch envia informacion para verificar como esta operando el Arduino a la interfaz serial asi que recomiendo que la observen cuando comiencen las pruebas.

4. Servidor Apache – MySQL – PHP

Asumimos que el servidor posee Apache, PHP y MySQL y que estos se encuentran configurados y funcionando sin problemas. Además se dispone de una base de datos en MySQL con un usuario y contraseña a la que tenemos acceso y nos podemos conectar.

Utilizaremos la misma tabla que en el proyecto anterior llamada «variable» que se puede crear con el siguiente script:

CREATE TABLE IF NOT EXISTS `variable` (
  `fecha` datetime NOT NULL,
  `id` varchar(30) NOT NULL,
  `nombre` varchar(100) NOT NULL,
  `valor` float NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

El script que recibira las variables desde el Arduino se debe llamar sensorarduino.php y debe ser puesto en la raíz del sitio web ya que el código del Arduino lo llama con un «GET /sensorarduino.php…» donde el «/» hace referencia a la raíz del servidor. El codigo del script es el siguiente:

<?php
// www.internetdelascosas.cl
//
// Script para recolectar datos enviados por arduinos conectados a la red
//
// contacto@internetdelascosas.cl
//

// Parametros para encender leds
$umbralTemperatura = 22;
$umbralHumedad = 80;
$umbralLuminosidad = 500;

// Parametros de base de datos
$mysql_servidor = "localhost";
$mysql_base = "iot";
$mysql_usuario = "iot";
$mysql_clave = "contraseña_super_segura_que_no_es_hola123";

$id = htmlspecialchars($_GET["id"],ENT_QUOTES);
$temperatura = htmlspecialchars($_GET["temperatura"],ENT_QUOTES);
$humedad = htmlspecialchars($_GET["humedad"],ENT_QUOTES);
$luminosidad = htmlspecialchars($_GET["luminosidad"],ENT_QUOTES);

// Valida que esten presente todos los parametros
if (($id!="") and ($temperatura!="") and ($humedad!="") and ($luminosidad!="")) {
    mysql_connect($mysql_servidor,$mysql_usuario,$mysql_clave) or 
       die("Imposible conectarse al servidor.");
    mysql_select_db($mysql_base) or die("Imposible abrir Base de datos");

    $sql = "insert into variable (fecha, id, nombre, valor) 
            values (NOW(),'$id','temperatura','$temperatura')";
    mysql_query($sql);

    $sql = "insert into variable (fecha, id, nombre, valor) 
            values (NOW(),'$id','humedad','$humedad')";
    mysql_query($sql);

    $sql = "insert into variable (fecha, id, nombre, valor) 
            values (NOW(),'$id','luminosidad','$luminosidad')";
    mysql_query($sql);

    // Genera respuesta en XML para que el Arduino lo procese
    if ($temperatura < $umbralTemperatura)
        echo "<led_1>1</led_1>";
    else
        echo "<led_1>0</led_1>";

    if ($humedad > $umbralHumedad)
        echo "<led_2>1</led_2>";
    else
        echo "<led_2>0</led_2>";

    if ($luminosidad < $umbralLuminosidad)
        echo "<led_3>1</led_3>";
    else
        echo "<led_3>0</led_3>";
    echo "\n";
}
?>

Recuerden cambiar las credenciales de la base de datos MySQL por las de su base de datos.

Este código php genera una salida en XML como la siguiente

<led_1>1</led_1><led_2>0</led_2><led_3>0</led_3>

La cual es procesada por el Arduino el cual lee el valor encerrado en cada tag XML (<led_1> </led_1>) como el valor binario de encendido o apagado del led que corresponde al tag.

5. Prueba Final

Si han realizado todos los pasos correctamente entonces al verificar la interfaz serial del Arduino deberían ver el mensaje de inicio, la dirección IP que asume el Arduino,  los valores que se obtienen desde los sensores y que son enviados al servidor y la respuesta que el servidor envía procesada por el Arduino que indica en binario (0/1) si el led debe encenderse o no

ArduinoSerial

Y al revisar el registro log en el servidor web deberian ver las conexiones que realiza el Arduino

[root@iot]# tail -f /var/log/httpd/iot.cl_access_log
210.1.221.117 - - [14/Jul/2014:18:39:14 +0400] "GET /sensorarduino.php?id=joniuz&temperatura=20.00&humedad=48.00&luminosidad=685 HTTP/1.1" 200 49 "-" "Arduino-Ethernet"
210.1.221.117 - - [14/Jul/2014:18:40:14 +0400] "GET /sensorarduino.php?id=joniuz&temperatura=20.00&humedad=47.00&luminosidad=687 HTTP/1.1" 200 49 "-" "Arduino-Ethernet"

Muy complejo? Ya saben, si tienen dudas pueden consultar comentado en el formulario de mas abajo  y recuerden seguirnos en nuestra cuenta de twitter @InternetDLC y en nuestra fan page de Facebook.

Todo el código fuente de este proyecto esta disponible en nuestro repositorio GitHub.

 

Author: José Zorrilla

Ingeniero Civil Informático, Universidad de Santiago de Chile. Master of Professional Engineering University of Sydney. En Chile trabajó empresas de servicios internet y telcos como IBM, VTR y Entel. Le gusta la fotografía y el armado de drones, tiene estudios de violín, guitarra eléctrica y sintetizadores que enciende cuando tiene algo de tiempo.

103 thoughts

  1. Buenas tardes Joniuz
    Tee scribo desde venezuela, considero que Dios te ha dado grandes dones para compartir. Yo estoy interesado en hacer una lectura de datos analogos y enviarlos a un servidor web para almacenarlos en base de datos. He revisado tus proyectos y estoy un poco claro con las conexiones del arduino, donde he presentado problemas es en la parte de almacenamiento en web.
    Yo tengo instalado WAMP (PHP, MySQL y Apache) pero no logro conectarme desde una maquina remota al servidor con wamp server. he probado asignando ip estaticas y nada.
    Si me pudieras orientar en que lugares web podría obtener esta info seria de mucha ayuda

    1. Hassier

      Lo primero que debes validar es que el servidor web este funcionando correctamente, esto se hace simplemente colocando desde cualquier computador en la red local la dirección IP del servidor en el navegador (Chrome, IE o el que prefieras) y ver si se despliega la pagina de pruebas o muestra algún error. Es importante que sea desde la red local la conexion porque de otra forma debes comenzar a manejar direcciones IPs dinamicas y abrir puertos en tu router de acceso.

      Una vez validado que el servidor web opera correctamente comienza a probar directamente el script php con el navegador, cuando veas que hay respuesta en formato XML comienza a probar con el Arduino.

      Saludos.

      1. Hola

        Muchas gracias por el tutorial tengo dos dudas la primera estoy usando xammp por lo tanto mi servidor web es localhost:8080 ya que el puerto 80 lo tengo ocupado en la linea char server[] = «http://localhost:8080/»; estaria bien de esa manera?
        Y mi otra duda es en la linea de la dirección Ip cual pondria si es localmente que me conecto

        1. Hola Jorge, con respecto a tu primera pregunta, no, no esta bien, localhost es una auto referencia del servidor a su misma direccion ip, si le dices a Arduino que vaya a localhost, intentara hablarse a si mismo. Debes darle la direccion ip de la red local, asi Arduino sabra a que computador o servidor debe hacer la conexion ethernet.
          Con respecto a tu segunda pregunta, aunque te conectes de una red local, esta red tiene ips locales, los cuales debes conocer para poder configurar la conexion entre el Arduino y el servidor. Hay una aplicacion muy buena llamada Fing que permite desde tu celular ver las direcciones de red locales.
          Saludos

  2. Brother:
    Grande tu aporte, voy a implementarlo y te cuento como me fue.
    Ahora el detalle, como toda estación meteorológica, siempre está en un lugar remoto, entonces debemos hacer un upgrade de tu proyecto, para que la info la saques por el modulo wifi y de alli conectar a un bridge que enlace a otro bridge de por lo mínimo 1km en linea de vista y bajar la data para procesarla.
    También me interesa medir el viento, es decir implementar un anemómetro al proyecto, con eso se tendría una verdadera estación meteorológica.
    Porfa si te interesa contactame y estaremos en comunicación.

    1. Tu los has dicho, las estaciones meteorológicas están en lugares remotos, pero esta fue pensada para usarla en la casa. En todo caso, no es mejor usar una Shield GPRS cuando se trata de grandes distancias y así usar la red celular? obviamente el inconveniente es que no es gratuita como la Wifi.

      Con respecto al anemómetro no he encontrado algún sensor que me permita directamente medir las revoluciones de algo que gira, hay uno, pero se debe construir el dispositivo, interesante desafío.

      Saludos

      1. Dr. Joniuz:
        En el sigiuente enlace, venden lo que necesito para medir velocidad del aire:
        http://www.inspeed.com/anemometers/Vortex_Wind_Sensor.asp
        Tambien hay un juguetito para medir dirección del Aire.
        Referente a una red GPRS, sería complicarnos un poco, la mejor solución es hacer un radioenlace entonces:
        Puedo agregar un modulo WIFI, al arduino y la salida de data conectarla a un AP en modo Bridge a unos 1.5km en linea de vista? como sería dicha solución?

  3. Estimado joniuz tengo unas dudas con estas lineas…

    // Intervalo en milisegundos entre conexiones
    const unsigned long intervaloConexion = 20000;
    (Especifica el tiempo entre consultas del arduino?)

    y

    else if(millis() – ultimaConexion > intervaloConexion) {
    httpRequest();

    (esta no la entendi mucho)

    saludos

    1. Pablo, estas lineas controlan el tiempo entre cada conexion al servidor medido en milisegundos, Arduino utiliza la funcion millis() para obtener el tiempo real del sistema.

      Saludos

      1. Estimado Joniuz muchas gracias por tu respuesta.

        Ahora tengo otra consulta…existe alguna forma de crear una conexion segura entre arduino y servidor web…
        es decir que el servidor web verifique que ese arduino esta permitido en la base de datos…lo que estoy haciendo hasta el momento es enviar una Key, desde arduino al servidor y por php verifico que esa key esta en la base de datos.

        pero encuentro este sistema un poco vulnerable. me gustaria algo asi como que en arduino creara una key la envia al servidor, y con alguna llave unica del servidor se desencriptara y verifica en la base BD…espero explicarme bien

        saludos 🙂

  4. Te hago una consulta, hace un tiempo que tengo equipos armados de esa forma, y otros que realizan otras tareas y graban en una base de datos, se grafican en un portal y se envian los datos a distintos carteles.
    Mi tema, es que los sensores DTH22 y BMP085 que tengo, me tiran temperaturas por arriba de las reales.
    tendras idea que puede ser?
    Maxi

  5. Hola amigo, sabe me interesa este tutorial ya que necesito que me ayude con la parte en como puedo subir estos datos a la web y que pueda yo visualisarlo desde cualquier ordenador connectado a la red mediante una pagina web. la verdd nesito controlar un invernadero atraves de la web, porfavor si me podria ayudar con eso esque nose como empesar.

    1. Nestor

      En este tutorial se ve como enviar los datos en forma remota a un servidor web, solo falta hacer la aplicacion web que permita ver esos datos ya sea en tablas o graficos lo cual escapa un poco al alcance de este sitio.

      Nos comunicaremos por correo electronico para ayudarle con su proyecto.

      Saludos

      1. Estimado Joniuz:
        A mi también me interesaría implementar la aplicación web q permita visualizar la data en modo gráfico y tener un histograma del mismo, porfavor envíame tu email para contactarnos.

        Gracias por tus valiosos aportes

      2. Me interesa mucho este tema me podrían enviar información se los agradecería.
        Felicitaciones por el tutorial.

      3. Me encuentro en un proyecto similar existe la posibilidad que me envíen información a mi mail.
        Felicitaciones por el tutorial.

        1. Carlos, la idea de estos tutoriales es justamente evitar enviar emails. Si tiene alguna duda o necesita ayuda consulte aqui, a todos les puede servir.

          Saludos

  6. hola te felicito por el tutorial me encuentro trabajando en algo similar intento tomar los datos de un invernadero y graficarlos en la pagina web si pudieses ayudarme o guiarme te lo agradecería mucho.

    Gracias por tus aportes

      1. Gracias por la ayuda , una ultima consulta para comunicar algún boton de php con el arduino tendras material ?

  7. Tengo una consulta con respeto a la dirección del servidor, en mi caso estoy usando xammp, en mi caso en la sección char server[] = «www.iot.cl».

    Debo reemplazar http://www.iot.cl por http://192.168.1.13/phpmyadmin, o solo me basta con la ip que adquiere mi pc que en este caso es 192.168.1.13.

    Espero me puedas aclarar esta duda, de ante mano muchas gracias.

    1. Miguel, solo debes remplazar la direccion por la ip, la otra direccion que mencionas es la direccion del administrador web de la base de datos.

      Saludos

  8. Hola joniuz, me sirvió mucho este tutorial.
    Sólo tengo una duda, cómo puedo pasar una variable dentro de una etiqueta XML para que el arduino actue. Por ejemplo:
    echo «»$fijar_temp»»;

    y el arduino lo lee asi:
    if(client.find(«»)) {
    fijar_temp = client.parseFloat();
    Serial.println(fijar_temp); //Me imprime «0.00»

    1. Saul, el codigo hace exactamente eso, recibe variables que son enviadas via XML, eso si las variables son enteras, en el codigo que sugieres solo debes agregar el tag XML en la instrucion client.find(««)

      Saludos

    1. Carlos, si se puede, pero debes cambiar toda la programacion del sensor porque el modo de lectura es diferente. En todo caso el LM35 es un sensor poco confiable, el DHTxx es mucho mejor.

  9. janoiuz, te felicito por tu trabajo esta muy bien echo, demuestras lo profesional que eres.
    Actualmente estoy trabajando en un proyecto muy similar, pero aplicado al control domótico, tengo mi pagina web creada que usare como servidor, ahora quiero controlar por el momento el estado de 4 luces, o sea que pueda encender y apagar estas luces a través de Internet, ademas de poder encender y apagar usando pulsador conectado al arduino. estaré trabajando en esto y te informare como me va.

    Saludos.

  10. Estimado Joniuz, te consulto una cosa: has probado poner mas de 1 sensor? seria muy complicada la programacion? muchas gracias

    1. Jose Maria

      Se pueden agregar mas sensores del mismo tipo, solo tienes que crear mas instancias del objeto dentro del codigo, aqui un ejemplo:

      #define DHTPIN1 2 // Pin del Arduino al cual esta conectado el pin 2 del sensor1
      #define DHTPIN2 3 // Pin del Arduino al cual esta conectado el pin 3 del sensor2

      DHT dht1(DHTPIN1, DHTTYPE);
      DHT dht2(DHTPIN2, DHTTYPE);

      float t = dht1.readTemperature();
      float t = dht2.readTemperature();

      Saludos

  11. Hola!
    Gracias por tu tutorial.
    Una pregunta, se podría hacer lo mismo, lo único que plasmarlo en una página web?

    Yo se algo de php html css como para hacer una página web, ya hice varias. Pero en fin, me refiero a si yo tengo un dominio http://www.midominio.com , y cada vez que entro puedo tener los datos de mi estación meteorológica.
    Es posible?
    Muchas gracias!

    1. Galo

      Claro que se puede hacer, si revisas el codigo los datos son guardados en una base de datos, por lo que si sabes hacer paginas web dinamicas que puedan leer esos datos desde la base de datos y mostrarlos no deberias tener mayor complicacion.

      Saludos

  12. Estimado, muy buen trabajo.
    Tengo una duda, estoy intentando hacer una estación meteorológica con 4 sensores que son los que me interesan.
    Temperatura.
    Radiación solar.
    Humedad del suelo.
    Precipitación.

    El tema de los sensores, está resuelto y tu código resuelve el tema de captura, sin embargo, he revisado muchos trabajos similares, y la mayoría no intenta resolver el asunto de almacenamiento y frecuencia de la información.

    Por ejemplo, que la captura de las variables sea cada 30 minutos reloj, es decri que el código me muestre una lectura de los sensores a las 7:00 am, 7:30 am, 8:00 am, 8:30 am, 9:00 am, etc, etc así sucesivamente y obviamente todo asociado a una fecha (año, mes, día), en una misma linea, de tal forma que por día se tengan 48 lecturas de los sensores (24 horas y una lectura cada 30 minutos equivale a 48 lecturas por día).

    Te agradecería si me pudieras orientar, con tu código a como recoger y almacenar en una memoria SD los datos de tus sensores de esa forma.

    Muchas gracias,

    1. Jhonny

      Aqui hay dos consultas en una, y la primera que es sobre el tiempo es uno de los temas principales en el desarrollo de dispositivos conectados a Internet. Hay dos formas de hacer lecturas de sensores, una gatillada desde cada sensor hacia en servidor y la otra es que el servidor gatille la consulta. Arduino no tiene un controlador de tiempo real, tiene un reloj interno que es bastante preciso pero no conoce la hora actual asi que no lo recomiendo para gatillar el envio de datos a menos que tenga un reloj real como un modulo GPS. La mejor solucion es hacer la consulta desde el servidor y que el Arduino responda con los valores solicitados

      Con respecto a la memoria SD te recomiendo que veas la documentacion oficial de la libreria en http://arduino.cc/en/Reference/SD

      Nosotros estamos preparando dos tutoriales que trataran justamente ambos temas.

      Saludos

  13. cual es la resistencia de 12 oK? 12 ohms o 12 kilo ohms? perdón me lo dejaron de tarea y no se ni que onda :S

  14. Hola , me encanto la idea y de hecho tengo un proyecto que requiere medir algo y ya tengo todos estos materiales, pero yo solo quiero este proyecto asi para mi haha, no necesesito mandarlo a una pagina, hay forma de poder hacerlo asi? no se como podria modificar el codigo para que este no enviara nada a una web ni nada.
    como lo haria?

    1. Hola Rodo!

      El proyecto sale entre 35 a 50 lucas dependiendo de la calidad de los componentes. Yo tengo uno usando una Raspberry Pi que aparte de reportar temperatura tuitea cuando hay intentos de hackeo y el nivel de spam.

      Saludos por alla, yo aca sigo alimentando a los canguros (son ratones gigantes con alma de perro para mi jajaja)
      JZ

  15. Buenos noches, una consulta, tengo problemas con la subida de los valores a la base de datos, no se que estoy aplicando mal, porque en el monitor serial de Arduino me preseenta los valores, pero en la base me llegan valores 0

    1. Hola, te recomiendo revisar el archivo log del servidor web, aho deberia quedar registrada la peticion GET con los valores de las variables, si estan correctos entonces debes revisar el script PHP.

      Saludos
      JZ

  16. Hola disculpame la pregunta, pero queria saber si se puede hacer que genere un archivo de texto con la temperatura y la humedad y que actualice cada 10 minutos tipo

    34º C – 80% H

    Gracias

    1. Fernando, el archivo de texto deberia generarse en el servidor o en el Arduino? ambas acciones son posibles. En el servidor es muy simple, solo debes agregar un codigo como el siguiente en el script del servidor

      $fh = fopen($temperatura_humedad.txt, ‘w+’);
      fwrite($fh, $datos_a_escribir);
      fclose($fh);

      En el Arduino es un poco mas complejo, porque debes usar una memoria Micro SD, la Shield Ethernet tiene una ranura para este tipo de tarjetas, solo debes incluir la libreria SD y programar la escritura en la tarjeta SD, pero eso da para un tutorial completo.

      Saludos
      JZ

  17. Hola joniuz, he estado buscando este proyecto durante 2 semanas y eres el único que lo explica todo, mis únicas dudas son que no se como conectar el Arduino ethernet shield con el Arduino Uno, y como puedo aprender a controlar los servidores Apache, porque no tengo ni idea, o si ves viable algún otro tipo de servidor, ya que necesito realizar este proyecto donde la importancia esta en la comunicación del Arduino por internet.

    1. Hola Joaquin, no entiendo a que te refieres con conectar la Ethernet Shield con Arduino, simplemente se monta la shield sobre la placa Arduino y listo, debes tener cuidado en no forzarlo mecanicamente y verificar que los pines queden alineados.
      Sobre controlar servidores Apache, la red esta llena de tutoriales, es cosas de buscar, en todo caso, cualquier servidor web sirve para este proyecto.
      Saludos
      JZ

  18. Hola Joniuz
    En primer lugar muchas gracias por tu tutorial.
    Yo estoy usando Hostinger y tengo en este servidor una base de datos MySQL a la que accedo a trabes de un subdominio mediante tu ejemplo con *.php para ingresar datos.

    Ya he hecho con una aplicación de android registros a la base de datos y funciona bien, los datos de conexión y credenciales lo hago bien.

    Mi placa Arduino es «Yun» por lo que ya tiene integrado Ethernet y WIFI.

    He intentado utilizar tu tutorial conectando Arduino apuerto COM no WIFI y con un sensor DHT11 simple, sin leds, solo a modo de prueba para ver si puedo subir los datos tomados a la base de datos.

    La base de datos la tengo asociada en un subdominio http://prueba.wi-sen.esy.es en un subdirectorio «pruba» donde tengo una web de prueba.

    La conexsión no se llega a establecer, pues en el log del servidor no aparece actividad y en el Monitor Serie solo me aparece la primera lectura, una sola y se para.

    Creo que podría tener que ver con mi arduino que es YUN y requiere otro método de conexión,
    Agradecería me pudieras asesorar o ayudar.
    Un saludo-
    Oscar

    1. Oscar, el ejemplo es para una conexion via Ethernet, no sirve para una conexion del tipo COM (utilizando el cable USB). Necesariamente debes conectar el Arduino a la red usando WiFi o su puerto ethernet.

      Saludos
      JZ

  19. Estimado, trabajo en el area y me gustaria intercambiar informacion, tengo Anemometros para medir velocidad de viento, en este momento quiero hacer una aplicacion, si gustas me escribes para contarte mas del tema………….saludos!!!

    1. Alex, depende del tipo de sensor, si es analogo simplemente se conecta a una puerta analoga y se procesa el valor con una funcion de conversion. Si es digital es necesario instalar una libreria, normalmente el fabricante del sensor provee de esta libreria.

      Saludos

  20. hola, disculpa mi ignorancia, recien entro al mundo arduino, veo diferentes placas ethernet y no se cual es la correcta para este proyecto ya que los precios son muy diferentes
    gracias por compartir

      1. Hola, gracias por responder, ya he conseguido todo lo necesarios, el sparkfun completo, quisiera poder conectar todos los sensores con el servidor web.
        me podrias decir si es lo mismo que hiciste con el proyecto tuyo? o que tipo de modificaciones hay que hacer.
        es para un proyecto escolar…y la verdad lo estoy aprendiendo con los chicos.
        muchas gracias por tu rta!

        1. Hola! wow para un proyecto escolar? yo hice lo mismo para un Master en la Universidad de Sydney, que bien por nuestra educacion latinoamericana!
          Para agregar mas sensores necesariamente debes modificar el codigo, revisalo en nuestro repositorio Github para que sepas a que lineas me refiero.
          Por cada sensor debes agregar una linea para leer su valor actual (ver lineas 144, 146 y 149) y guardarlo en una variable, luego debes enviar esas variables al servidor (ver lineas 173 y 175).
          En el servidor debes agregar el codigo para leer las variables que el sensor envia (ver lineas 21, 22 y 23) y luego insertar estos valores en la base de datos (ejemplo lineas 39-41).
          Espero que te sirva esta ayuda y te invito a que te suscribas a nuestro canal de Youyube
          Saludos!

  21. yo tengo este codigo y no se como acomodarlo para que salga el resultado via web…

    (Trozo de codigo borrado)

  22. una pregunta yo uso xampp y no se cual es la direccion del servidor donde la puedo visualizar, tambien se tiene que usar el cable ethernet para conectar el ethernet shield

    1. Leonardo, la direccion del servidor es la direccion IP, usas xampp en tu computadora personal? entonces la direccion es tu IP interno de la red.

      Si, la Ethernet Shield requiere del cable Ethernet para conectarse a la red, no es un dispositivo Wifi.

      Saludos

  23. Hola compadre, primero que nada agradecido de todo el material que subes y el tiempo en explicar las dudas de cada uno. Tengo la siguiente consulta lo que pasa que tengo una Ethernet shield, sin embargo no tiene impresa la mac. Por ende no puedo declararla eb el sketch del arduino y no se si existe alguna forma de consultar la mac o de setearla, ya que ejecute el proyecto y no establece la conexión con la base de datos remoto. El único parámetro que no tengo es la mac, favor tu ayuda y colaboración.

    1. Hola Rene, cuando la mac no esta impresa, probablemente se trata de un clon chino de la placa ethernet shield. Como es clon puedes asignarle cualquier mac siempre que no este dentro de tu red. Te recomiendo probar primero con scripts simples para asegurarte que esta funcionando primero y despues ver algo mas complejo con sensores y variables.
      Saludos

  24. No me permite crear la tabla
    Se debe crear primero la base de datos?
    En este tutorial no aparece y en el anterior tampoco

    mysql> CREATE TABLE IF NOT EXISTS `variable` (
    -> `fecha` datetime NOT NULL,
    -> `id` varchar(30) NOT NULL,
    -> `nombre` varchar(100) NOT NULL,
    -> `valor` float NOT NULL
    -> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
    ERROR 1046 (3D000): No database selected

      1. Si, falta el create database iot; (en el caso que quieras llamarla asi, y una serie de permisos que se deben asignar a un usuario para que acceda a esa base de datos, lo que escapa un poco al alcance de este tutorial y corresponde mas a uno de creacion de usuarios en MySQL.
        Saludos

    1. Rodrigo, el tutorial asume que esta trabajando correctamente el servidor web y MySQL, pero efectivamente falta lo de la base de datos, lo incluiremos. Es necesario que este creada una base de datos con un usuario y contraseña.
      Saludos y gracias por el aporte.

  25. buenas tardes lo que pasa es que igual utilizare esos sensores, utilizado para la automatizacion de incubadora con una aplicacion movil si m podria orientar que lenguaje utilizar y como monitorearla por internet y la aplicacion.

    1. Hola Jorge, lo mas facil es hacer una aplicacion web «responsible», es decir adaptable a las distintas pantallas de los equipos moviles, si funciona bien, ya puedes dedicarte a hacer app para las plataformas Android e iOS. Para el servidor en este caso usamos PHP, pero puedes usar Python tambien.
      Saludos

  26. Tengo un proyecto de construir un monitor de presion arterial, capnografia, EKG , oximetria de pulso utilizando ATMega 358, pero no se como hacer para que los datos obtenidos se pasen a la computadora, cree me pueda asesorar.

    1. Ileana, la mayoria de los proyectos relacionados con e-health necesitan lecturas en tiempo real o un flujo de datos, lo mejor es que uses la interfaz serial para enviar datos al computador y no una conexion con un servidor internet.
      Saludos
      JZ

  27. Hola Joniuz, con los datos obtenidos quiero generar una gráfica en PHP. Tenes algún código para usar con Google Chart o similar para graficar la temperatura?
    Desde ya muchas gracias!

  28. Hola que tal! Muy buen post!

    Tengo una duda, estoy realizando un proyecto similar, utilizaré un sensor DHT11 que medirá la temperatura y humedad de un cuarto con aire acondicionado. Si la temperatura del lugar aumenta, el Arduino enviará un pulso (con ayuda de un relé) al aire acondicionado para encenderlo (si éste estuviera apagado) o si la temperatura es baja, haría lo contrario y esos cambios serán visualizados en una página web con la ayuda de Ajax cada segundo.

    Y lo que se desea es generar reportes de los cambios de temperatura del lugar por lo que los datos serán almacenados en una base de datos. Estuve probando con tu código pero no me está almacenando los datos obtenidos en mi BD de MySQL. El archivo .php si funciona, pero el Arduino no está enviando la información, no sé si debo hacer alguna otra modificación.

    He checado tanto este post como el otro, donde almacenas los datos en MySQL pero el resultado es el mismo.

    Espero te encuentres bien y quedo a la espera de tu pronta respuesta!

    Saludos desde México!

    1. Estimada Marisol
      Si estas usando exactamente el mismo código para el Arduino deberías al menos configurar estas líneas de acuerdo a tu ethernet shield, a tu red y al ip del servidor que esta utilizando


      byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x4E, 0xD7 };
      IPAddress ip(172,17,17,217);
      char server[] = "www.iot.cl";

      Si quieres que revisemos tu código te recomiendo que utilices aplicaciones como GitHub y clones nuestro repositorio, asi podemos ver exactamente donde esta el error y corregirlo. El repositorio de este proyecto esta en https://github.com/internetdelascosas/estacion-meteorologica-arduino

      Saludos
      JZ

      1. De hecho , ese fragmento del código lo tengo configurado de acuerdo a mi ethernet shield, pero quiero pensar que el error está en las ip. Incluso he probado con la librería Mysql connector / arduino y no obtengo el resultado esperado.

        byte mac[]={0xDE,0xAD,0xBE,0xEF,0xFE,0xED}; //Declaracion de la direccion MAC
        byte ip[] = {192,168,20,200}; //Declaracion de la IP
        byte myDns[] = {192,168,20,2}; //DNS
        byte Gateway[] = {192,168,20,254}; //Gateway
        byte Subnet[] = {255,255,255,0}; //Mascara
        EthernetClient cliente;
        EthernetServer servidor(80);
        IPAddress server(192,168,20,128); //Declaracion del servidor

        Tengo el código en las dos versiones, utilizando la librería y a través del PHP, pero ninguno conecta a mi BD.

        Saludos.

        1. Y al usar el php tampoco puedes escribir en la base de datos? hay algun error? busca en el archivo error.log de apache para ver cual es el error. Probablemente sea de un error de credenciales de la base de datos.

          Saludos
          JZ

          1. He conseguido conectar con mi BD, pero no me registra lo obtenido por el sensor (y funciona, pues hice un tester del mismo para comprobar que si obtiene datos). Fue con la ayuda de la librería, pero volveré a intentar hacerlo por php pues, lo más importante no lo está capturando.

            Revisaré igualmente el archivo, puede que sea un error de sintaxis incluso.

            Saludos!

  29. Estimado Joniuz
    Te felicito, excelente tu post !!!

    Trabajo con un arduino con shield ethernet que ejecuta un programa php (alojado en un servidor web raspberry). El php lee algunos valores de una tabla mysql y se los entrega al arduino.
    Pero … tengo dos problemas:
    1.- El arduino en cierto momento, ya no puede conectarse … y la respuesta de client.connect() siempre es falsa. Sin embargo, si lo reinicio, si funciona.
    2.- He visto en varios ejemplos que la conexión se hace en el setup del programa arduino … yo la hago en el loop y la conecto y desconecto cada 10 segundos … cual es la mejor estrategia …. ya que el raspberry podría reiniciarse y el arduino ya no podría conectarse … o sí ??
    Gracias por tu apoyo

    1. Jorge
      El Arduino como plataforma es muy buena para experimentar, y existen muchos clones porque es una plataforma abierta, lamentablemente algunos de estos clones no son de muy buena calidad lo que provoca que se cuelguen o dejen de funcionar (como es tu caso).
      Veo que ya sabes como solucionarlo aplicando un reset por hardware a la placa, para evitar que se cuelgue una solucion un poco extrema es unir uno de los pines del Arduino (por ejemplo el pin12) con el pin reset y luego darle el valor high via programacion, esto hara que el Arduino se reinicie al igual que si hubieses presionado el boton reset.
      Avisanos como te va con esa solucion.
      Saludos
      JZ

  30. Hola tengo instalado el paquete AppServ en windows 10 y estoy usando un Arduino Mega + una
    Ethernet Shield que leen un sensor de temperatura LM35 y una Fotoresistencia y manda las lecturas a un codigo PHP por el metodo GET a una Base de Datos Mysql, pero los valores no se cargan. El codigo php creo que esta bien por que por la URL si puedo cargar los datos en la tabla, mis dudas estan en el codigo para la Ethernet Shield, Aunque parece que si manda los datos por que al poner la direccion Ip declarada para el Arduino Muestra los valores, que cada que vuelve a cargar la pagina se actualizan o cambian. HELP si me pueden ayudar por favor. Gracias

    1. Estimado Gino, para poder ayudarte deberiamos tener acceso al codigo, estas usando nuestro codigo? te pregunto esto porque si accedes desde un browser a la direccion que tiene el Ardunino, no deberias recibir respuesta.
      Saludos
      JZ

  31. Estimado, cómo podría adaptar este sistema para enviar los datos desde una placa gprs al servidor mysql? Cómo podría crear una especie de sitio web al cual yo envío datos, los leo con php y los envío a un servidor? Si pudieses ayudarme me sería de gran ayuda.
    Saludos
    Muy buen aporte.

    1. Hola David, para realizar lo que propones, la unica diferencia es la conectividad GPRS, en este caso usamos una Ethernet Shield que utiliza sus propias instrucciones para conectarse a la red y obtener un ip, en el caso de un modulo GPRS las instrucciones para conectarse a la red y obtener ip son diferentes, lo demas es exactamente lo mismo.
      Saludos
      JZ

  32. Hola, Joniuz, excelente tutorial!
    Quiero hacer este proyecto pero en ves de usar el shield ethernet quiero usar
    SIM900 GPRS/GSM Shield con tarjeta SIM de datos…usar un plan de datos, es posible ??
    …tengo un pequeño invernadero y esta en una zona rural donde tengo solo cobertura de red movil, al ser pequeño no tengo empleados y son días que solo tengo ir para abrir las ventanas y el invernadero esta a 45 km de mi casa, quiero emplear esta tecnología para abrir ventanas,las ventanas q se cierren o abran por si hay viento o la temperatura o humedad baja o crece, pero no entiendo como hacerlo con arduino y SiM900 GPRS/gsm …me puedes ayudar…si es contra coste no importa solo espero tu respuesta…Por favor!

  33. disculpa, tengo una duda. se tiene que configurar el router que utilizamos para asignar una direccion ip y un puerto para la comunicacion (que despues esa IP es la que pondremos en arduino fija)

    1. Hola Jorge, no es necesario, el Arduino puede tener una direccion dinamica, es el servidor (exactamente esta linea de codigo: char server[] = «www.iot.cl»;) el que debe tener una ip fija, que puede ser publica o privada (dentro de tu propia red).
      Saludos.

  34. Hola joniuz te agradezco bastante por compartir todo tu trabajo con nosotros, estoy trabajando en un proyecto con Arduino nano y el modulo enc28j60, es un sistema de alarmas, pero necesito acceder desde un dispositivo fuera de la red local, me gustaría comunicarme mejor contigo para expresarte mis dudas.

  35. Buenas Ingeniero,un placer
    Tengo lo siguiente,deseo mediante arduino tomar valores de un sensor de humedad, esos valores los e graficado en ttiempo real mediante freechar en java, lo que deseo ahora es guardar esos valores en una base de datos MySQL para que se pueda hacer una estadistica de por ejemplo durante el mes cual fue la humedad más alta y añadir mas sensores mas adelante.
    Le agredeceria su ayuda

  36. Deseo colocar en la secadora mecánica de café un sensor de humedad que controle el porcentaje de humedad del grano(café), y una vez captado este porcentaje enviarlo a una página web y si este porcentaje está en un 15% arrojar una alarma.
    Mi pregunta es: ¿se puede aplicar debo utilizar este código u habrá algo más que agregarle?

  37. hola buenas, estoy haciendo un proyecto similar pero solo necesito que se envíe la información del sensor ldr a la base de datos que tengo en un hosting, cómo se podría hacer, hay mucho código en este ejemplo y estoy algo confundido 🙂

    1. Patricio

      Esfuerzate un poco en entender el codigo, aunque es largo es muy simple. La modificacion la debes realizar en las ultimas lineas, que son la llamada al servidor, en esta linea:

      client.print("GET /sensorarduino.php?id=joniuz&temperatura=");
      client.print(t);

      Debes cambiar la variable temperatura por luminosidad, y borrar las otras variables para seguir con

      client.println(" HTTP/1.1");

      Saludos
      JZ

  38. Hola, muy buenas tardes.
    Quiero solicitar tu atyuda en un proyecto (con arduino) de secundaria, y me gustaria hacer esta estacion metereologica, si me podrias hacer el favor de darme instrucciones mas consisas respecto a este proyecto.

    muchas gracias, espero pronta respuesta.

  39. Hola muy bueno tu proyecto, tengo un problema y una consulta.

    Yo tengo en el server php 7 y no me funciona este codigo, tendras una version actualizada?

    es posible encender desde el navegador algun led de forma manual? aparte de la programación de el umbral

    Muchas Gracias

    1. Hola Nahuel
      Estamos trabajando en actualizar todos los scripts a php7.
      Con respecto a encender un led desde el navegador, si es posible, pero deberias tener alguna variable de estado en el servidor, o configurar Arduino como servidor.
      Saludos
      JZ

Responder a Leonardo Reyes Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *