Sensor de temperatura y humedad DHT11

Ya hemos visto en otra entrada como medir la humedad empleando un termómetro de bulbo húmedo y uno de bulbo seco, emulando un psicrómetro. Una solución mucho más sencilla es utilizar un componente discreto como el DHT11 que no tiene mantenimiento como pasaba con el psicrómetro y no necesita complicadas fórmulas o tablas para obtener la humedad. Eso sí, la resolución no es ni de lejos tan buena como la que nos proporciona un DS1820 en la medición de temperatura, tiene un error de hasta +- 2ºC frente a los 0.5ºC del DS1820. En cuanto a la humedad relativa tenemos un error del hasta el +-5% con medidas entre el 20% y el 90% de humedad.

El datasheet lo podemos encontrar aquí

De las cuatro patas sólo vamos a emplear 3, dos son la alimentación entre 3 y 5.5V y la tercera se usa como bus de datos de un sólo hilo tanto para leer como para escribir, es necesario conectar una resistencia de pull-up de 4K7 en esta línea.

No hay reloj, así que la comunicación es asíncrona, hacemos una petición de datos y el DHT11 nos responde con una trama devolviendo la temperatura y la humedad relativa. Cada bit transmitido empieza por un flanco de cero a uno y el valor del bit viene dado por el tiempo en estado alto (26-28 us es un 0 y 70 us es un uno).

Aquí os dejo un ejemplo para leer los valores, devuelve cero si todo va bien, o un número menor que cero en caso de defecto. Los valores de temperatura y humedad se escriben en las variables T_DHT11 y RH_DHT11 y la función está preparada para trabajar en el PIN_B5 del PIC.

#define DHT11 PIN_B5
float T_DHT11,RH_DHT11;
UINT8 Tint,Tdec,RHint,RHdec,CRC;

int leer_DHT11(void)
{
UINT16 i,j;
UINT8 chkCRC;
UINT32 Respuesta;

   Tint=0;
   Tdec=0;
   RHint=0;
   RHdec=0;
   Respuesta=0;
   CRC=0;
   set_tris_b(get_tris_b()&0xEF);
   output_high(DHT11);
   delay_ms(25);
   output_low(DHT11);
   delay_ms(25); // Por lo menos 18us
   output_high(DHT11);
   delay_us(30);
   set_tris_b(get_tris_b()|0x10);
   for (i=0;i<100;i++) { // Espera respuesta de 20-40us
      if (!input(DHT11)) break;
      delay_us(1);
   }
   if (i==100) return -1;
   for (i=0;i<100;i++) { // Espera respuesta de 80us
      if (input(DHT11)) break;
      delay_us(1);
   }
   if (i==100) return -2;
   for (i=0;i<100;i++) { // Espera respuesta de 80us
      if (!input(DHT11)) break;
      delay_us(1);
   }
   if (i==100) return -3;
   for (i=0;i<32;i++) {
      for (j=0;j<100;j++) {
         if (input(DHT11)) break;
         delay_us(1);
      }
      if (i==100) return -4;
      delay_us(30);
      Respuesta<<=1;
      if (input(DHT11)) Respuesta|=1;
      for (j=0;j<100;j++) {
         if (!input(DHT11)) break;
         delay_us(1);
      }
      if (i==100) return -5;
   }
   for (i=0;i<8;i++) {
      for (j=0;j<100;j++) {
         if (input(DHT11)) break;
         delay_us(1);
      }
      if (i==100) return -4;
      delay_us(30);
      CRC<<=1;
      if (input(DHT11)) CRC|=1;
      for (j=0;j<100;j++) {
         if (!input(DHT11)) break;
         delay_us(1);
      }
      if (i==100) return -5;
   }
   RHint=make8(Respuesta,3);
   RHdec=make8(Respuesta,2);
   Tint=make8(Respuesta,1);
   Tdec=make8(Respuesta,0);
   chkCRC=(RHint+RHdec+Tint+Tdec)&0xFF;
   set_tris_b(get_tris_b()&0xEF);
   output_high(DHT11);
   T_DHT11=(float)make16(Tint,Tdec)/256.0;
   RH_DHT11=(float)make16(RHint,RHdec)/256.0;
   if (chkCRC==CRC) return 0;
   return -6;
}

Eso es todo por hoy. Hasta la próxima.

Responder a Óscar Cancelar la respuesta

Tu email nunca se publicará.

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies