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.


 

5 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