lunes, 4 de enero de 2016

Temperatura y humedad con Arduino. DHT11 y LCD-I2C


Hoy os entregaré una entrada que indaga en la intimidad de un sensor de humedad y temperatura, el DHT11, y en la de un display LCD SMC-1602-A con un bus de comunicaciones serie I²C (Inter-Integrated Circuit). 
El circuito de la imagen anterior lo usaremos para visualizar la humedad y la temperatura de ambiente, el índice de calor o index heat (que yo llamo Huella de Calor) y el ambiente (si es seco, normal o húmedo, lo mostrará de forma explícita cuando pulsemos el pulsador P1).
Tanto el display como el sensor precisan de un par de librerías que deben estar instaladas en el entorno IDE de programación de Arduino, y deben ser llamadas en el código con #include (#include le indica al compilador que debe incluir un determinado archivo con un código adicional para poder usar estos elementos).
Para cargar las dos librerías en el entorno IDE, tenemos que ir a Programa -> Include Library -> Manage Libraries...
Las librerías son dos archivos zip que podremos bajar previamente de los siguientes sítios:
Para el display con I²C de aquí. Los detalles los podéis ver aquí.
Para el sensor de humedad y temperatura DHT11 aquí. Los detalles sobre esta librería los encontraréis aquí.



Después de cargar las librerías en el entorno IDE de Arduino, en el código del software tendremos que llamarlas de la siguiente forma:

Para el display LCD SMC-1602-A con I²C:

// Librerías necesarias par el funcionamiento del display
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// SDA (datos) con A4, SCL (clock) con A5, GND con GND(-) y Vcc con Vcc(+5v)

Para el sensor DHT11:

// Basado en código de ladyada para el DHT11, dominio público

#include "DHT.h" //Cargamos las definiciones de la librería para el DHT11
#define DHTPIN 2     // Al pin digital 2 está conectado la salida del sensor

// El sensor de humedad y temperatura utilizado es el DHT11.
// La librería también contiene el de DHT22
#define DHTTYPE DHT11   // DHT 11

// Conectar el - a GND del Arduino UNO
// Conectar el + a 5v
// Conectar la salida Out del sensor a un extremo de un resistor de 10K
// conectado a 5v y al pin 2 DIGITAL

// Inicializamos el sensor DHT11.

DHT dht(DHTPIN, DHTTYPE);

Esto ya está incluido en el código del software que hice para esta aplicación, y no debéis preocuparos por el tema, aunque os lo detallé ahora para que os percatéis del detalle.

Ahora montamos el hardware, y os quedará algo así:


Aquí os dejo un par de fotos con detalles del hardware correspondiente al display I²C y al sensor DHT11:


Sensor DHT11:


Luego de montar el hardware, desde el entorno IDE cargamos en nuestro Arduino el siguiente código (copiar y pegar):

// Librerías necesarias par el funcionamiento del display
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// SDA (datos) con A4, SCL (clock) con A5, GND con GND(-) y Vcc con Vcc(+5v)

// Basado en código de ladyada para el DHT11, dominio público

#include "DHT.h" //Cargamos las definiciones de la librería para el DHT11

#define DHTPIN 2     // Al pin digital 2 está conectado la salida del sensor DHT11


// El sensor de humedad y temperatura utilizado es el DHT11
#define DHTTYPE DHT11   // DHT 11


// Conectar el - a GND del Arduino UNO
// Conectar el + a 5v
// Conectar la salida Out del sensor a un extremo de un resistor de 10K conectado a 5v y al pin 2 DIGITAL

// Inicializamos el sensor DHT11.

DHT dht(DHTPIN, DHTTYPE);

int pulsador1=5; // Pulsador amb pin 5
int amb = 1; //Variable de estado pin 5, pulsador1
int n; // Variable para contar

void setup() {

  pinMode(pulsador1, INPUT); //Pin 5, amb, como entrada
 
  lcd.begin(16,2);
  lcd.setCursor(3,0);
  lcd.print("Nacho's Lab");
  lcd.setCursor(1,1);
  lcd.print("Cotidiana Place");
 
  Serial.begin(9600);
  Serial.println("Información de temperatura y humedad en el monitor serie:");

  dht.begin(); // Iniciamos el sensor
}

void loop() {

  // Solicitud de ambiente al pulsar el pulsador1
 
  for (n=1;n<16;n++) { // Usamos bucle For para mantener 4s y tener control sobre el pulsador cada 250ms

    amb = digitalRead(pulsador1);
    if (amb == LOW){
      ambiente();  // Llamada al subprograma de ambiente
    }
      delay(250);
  }


  // El sensor invierte unos 250 ms en la lectura de la humedad
  float h = dht.readHumidity();
  // Leer la temperatura en grados Celsius (por defecto)
  float t = dht.readTemperature();
  // Leer la temperatura en grados Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Comprueba si alguna lectura falla, y sale rápidamente con return (para intentarlo de nuevo).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("¡Error al leer desde el sensor DHT!");
    lcd.setCursor(0,0);
    lcd.print("     ERROR      ");
    lcd.setCursor(0,1);
    lcd.print("   DE LECTURA!  ");
    return;

  } // Fin de lectura fallida

// Información a través del monitor serie

  // Sensación térmica en Fahrenheit (por defecto) (Compute heat index)
  float hif = dht.computeHeatIndex(f, h);
  // Sensación térmica en Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humedad: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Índice de calor: ");
  Serial.print(hic);
  Serial.print(" *C ");
  Serial.print(hif);
  Serial.println(" *F");

// Información a través del LCD I2C
 
  lcd.setCursor(0,0);
  lcd.print("Humedad: ");
  lcd.print(h);
  lcd.print(" %");
  lcd.setCursor(0,1);
  lcd.print("Grados: ");
  lcd.print(t);
  lcd.print(" *C");

  for (n=1;n<16;n++) {

    amb = digitalRead(pulsador1);
    if (amb == LOW){
      ambiente();
    }
      delay(250);
  }
 
// Sensación térmica
     
  lcd.setCursor(0,0);
  lcd.print("Huella de calor:");
  lcd.setCursor(8,1);
  lcd.print(hic);
  lcd.print(" *C");


} // Fin de programa

void ambiente(){  //subprograma ambiente, sólo en pantalla de LCD I2C
  float h = dht.readHumidity();
 
      if (h <= 50)
     {
          lcd.setCursor(0,0);
          lcd.print("Ambiente:       ");
          lcd.setCursor(0,1);
          lcd.print("Seco (Dry)      ");
       
     };
      if (h >= 51 && h <= 60)
     {
          lcd.setCursor(0,0);
          lcd.print("Ambiente:       ");
          lcd.setCursor(0,1);
          lcd.print("Normal (Normal) ");
       
     };
      if (h >= 61)
     {
          lcd.setCursor(0,0);
          lcd.print("Ambiente:       ");
          lcd.setCursor(0,1);
          lcd.print("Humedad (Humid) ");
       
     };
     delay(4000);
}


// Fin de código

El código está bastante detallado con un nutrido grupo de comentarios, y es fácil de entender. Inicialmente el programa nos presenta en el display una pantalla de bienvenida que podremos personalizar fácilmente:


Luego muestra cada la humedad y la temperatura:


Alternando cada cuatro segundos con la Huella de calor o Index heat:




Al pulsar el pulsador P1 nos muestra en cualquier momento el Ambiente, o sensación según la humedad, de forma explícita:



Si falla el sensor por alguna razón, muestra lo siguiente:



Olvidaba comentaros, aunque leyendo el software se aprecia, que podéis disponer de una nutrida información sobre la humedad y la temperatura de ambiente, así como de la sensación térmica (index heat), tanto en grados Fahrenheit como Celsius, usando el Monitor Serie de Arduino:


Con el siguiente vídeo ilustramos esta entrada. La música es de Another Music2 (2013). Fusion Juice. Gracias por compartir generosamente.


 

19 comentarios:

  1. TERMOHIGROMETRO_LCD:83: error: 'class DHT' has no member named 'computeHeatIndex'

    float hif = dht.computeHeatIndex(f, h);

    ^

    TERMOHIGROMETRO_LCD:85: error: 'class DHT' has no member named 'computeHeatIndex'

    float hic = dht.computeHeatIndex(t, h, false);

    ^

    exit status 1
    'POSITIVE' was not declared in this scope


    Si puedes ayudarme a corregir el error, te lo agradeceria mucho.
    emecekase@gmail.com

    ResponderEliminar
    Respuestas
    1. Hola. Gracias por leer este blog. Lo que creo que te pasa es que no subiste la librería adecuado referente al sensor DHT11. Baja el ZIP, y cárgalo en Programa -> Include Library -> Add.ZIP Library... La verdad es que el error que mencionas no lo sufrí nunca yo. Revisa las librerías que cargaste, tanto la del Display I2C como la del DHT11. Revisa las conexiones del Display y del sensor DHT.Un saludo

      Eliminar
  2. Hola, estoy en proceso para hacer este proyecto pero tengo el mismo problema que Juan manuel, pero en este caso me dice que la variable POSITIVE no esta declarada:

    Tutorial_utilizar_pantalla_i2c_16x2:5: error: 'POSITIVE' was not declared in this scope

    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

    ^

    Se encontraron múltiples librerías para "LiquidCrystal_I2C.h"
    Usado: C:\Users\NACHO\Documents\Arduino\libraries\LiquidCrystal_I2C
    No usado: C:\Users\NACHO\Documents\Arduino\libraries\arduino_250223
    exit status 1
    'POSITIVE' was not declared in this scope

    ResponderEliminar
    Respuestas
    1. Es posible que en mi software de Arduino tenga instado dos librerías para el cristal líquido, y quizás la que os puse no sea la adecuada. Tenéis que mirar en Programa -> Include Library -> Manage Libraries... Yo tengo instaladas las siguientes: LiquidCrystal I2C by Frank de Brabander, LiquidCrystal Built-In by Arduino, Adafruit LiquidCrystal_I2C Version unknown (la que colgué) Hay Arduinos y display baratos que no tienen las características exactas al que yo uso, y eso te obligará a instalar algún tipo de librería distinta. Busca en Internet una librería adecuada para tu display. Búscala con Manage Libraries... que a través de él puedes buscar otras librerías para cualquier dispositivo, y para I2C hay varias.

      Gracias por leer este blog. Un saludo

      Eliminar
    2. Gracias por tu ayuda Nacho, lo mas probable es que sea la libreria que estoy usando, pero la de Frank Brabander la he incluido, igualmente con todas las que usaste, pero no me deja actualizarla ya que al tratar de actualizar falla en descargar. Lo extraño es que al tener todas las librerias que tu usaste me sigue dando el mismo error, de la variable "POSITIVE", aunque ocupe otro tipo de lcd deberia por lo menos compilar el programa para despues subirlo al arduino. Pero ya me las ingeniare para que funcione perfectamente, puesto que le agregare un ventilador automatico si hace mucho calor y ciertos consejos que el arduino mostrara en el display si hace frio, como: "Abrigate, hoy hace frio". En fin, muchas gracias por tu ayuda Nacho y ya vere que hacer.

      Eliminar
  3. no funciona sale el mismo error de "positive"

    ResponderEliminar
    Respuestas
    1. Hola. Gracias por leer este blog. Esto es un problema con alguna de las librerías que usáis. Echar un vistazo aquí: https://magnusglad.wordpress.com/2013/03/16/arduino-lcd/ Probar con alguna de las dos que están vinculadas al enlace anterior. Ya me contaréis. Muchas gracias. Saludos

      Eliminar
    2. no funciona con la libreria que esta en el enlace ya probe con la primera y con la segunda ya cerraron la pagina porfavor espero una pronta ayuda tengo que presentar el proyecto y no he podido por favor espero una urgente respuesta o si puedes pasarme el archivo con el codigo corriendo y sus respectivas librerias si me puedes ayudar estaria muy agradecido gracias

      Eliminar
    3. Hola. Sinceramente, yo no encuentro ningún problema en esta entrada, y lo único que me queda es que le eches un vistazo a este vídeo, y consultes directamente en los contenidos de Github en MOSTRAR MAS del vídeo: https://youtu.be/ymTMqFZEzzA
      Gracias por la lectura de este blog. Saludos

      Eliminar
  4. hola como hago para sacar los valores en el computador como muestras en las fotos

    ResponderEliminar
    Respuestas
    1. Hola: en las fotos se muestra como sale en el display LCD I2C, pero si usas el Monitor serie de Arduino, los datos se muestran como en el vídeo. Abres Arduino, y en Herramientas -> Monitor serie (Ctrl+Mayús+M) aparece la información si usas el código implementado en esta entrada. Gracias por el comentario. Un saludo

      Eliminar
  5. EL codigo me entra sin problemasm solo este cambio, LiquidCrystal_I2C lcd(0x27,16,2)
    Pero lo que no me queda claro es el conexionado del interruptor.

    Un buen trabajo.

    ResponderEliminar
    Respuestas
    1. Hola: Muchas gracias por su comentario y por visitar este blog. El interruptor está conectado, por un extremo, a la resistencia de 10K y al Pin digital 5 del Arduino UNO, y por el otro, al negativo de la alimentación (masa). No hay pérdida, en Arduino UNO está serigrafiado como DIGITAL (PWM~ ), terminal 5. Saludos

      Eliminar
  6. se que escribo después de bastante tiempo pero me gustaría si alguien me pudiera ayudar tengo este error
    'POSITIVE' was not declared in this scope
    "

    ResponderEliminar
    Respuestas
    1. Es la librería del display. Échale un vistazo al siguiente blog: https://microcontrolere.wordpress.com/2019/04/22/positive-was-not-declared-in-this-scope-error-resolved/
      Gracias

      Eliminar
  7. Agradecer a nuestro amigo y guía Nacho Salgado, y comenta que me fascino este proyecto, de la estación meteorológica, me salió em primera, solo minimice datos (16, 2); , Gracias a todos los amigos, soy nuevo en el aprendizaje de los códigos en Arduino uno, cualquier duda o problema en temas mas internos de los códigos me gustaría contar con sus apoyos, cjrios de PERU. Gracias Totales.

    ResponderEliminar
    Respuestas
    1. Gracias por el comentario y la lectura de este blog. Saludos

      Eliminar
  8. hola me sale un error C:\Users\juanf\Desktop\DHT11__LCD\DHT11__LCD.ino:5:53: error: 'POSITIVE' was not declared in this scope
    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
    ^~~~~~~~

    exit status 1

    Compilation error: 'POSITIVE' was not declared in this scope

    ResponderEliminar
    Respuestas
    1. Gracias por interesarte por esta entrada de este blog. En el primer comentario de esta entrada hay una referencia al mismo problema. Échale un vistazo a los comentarios. Un saludo

      Eliminar