Driver para el DHT22 (RHT22) en CCS

Después de mucho tiempo vuelvo a escribir en el blog y en esta ocasión les comparto la libreria para el sensor de temperatura y humedad DHT22…..

Después de mucho tiempo vuelvo a escribir en el blog y en esta ocasión les comparto la librería para el sensor de temperatura y humedad DHT22 o también lo he encontrado con el numero de RHT22 que para el caso es lo mismo, la librería esta basada en la que hizo el usuario “zerovlc” del foro http://www.todopic.com.ar la librería es la siguiente:

///Driver DHT22

#define dht22 PIN_A2
#bit dht_io = 0xf92.2
byte dht22_dat[5];
byte leer_datos_dht();
Void dht_init (void){
dht_io=0;
delay_ms(1);
output_high(dht22);
}
byte leer_datos_dht(){
byte i = 0;
byte result=0;
for (i=0; i< 8; i++) {
//We enter this during the first start bit (low for 50uS) of the byte
//Next: wait until pin goes high
while(input(dht22)==0);
delay_us(30);
if (input(dht22)==1){//Was: if(PINC & _BV(dht_PIN))
result |=(1<<(7-i));
}
while (input(dht22)==1);
//Was: while((PINC & _BV(dht_PIN)));
}//end of "for.."
return result;
}
Void leer_dht22 (float &dhthum,float &dthtemp){
//byte GlobalErr=0;
byte dht22_in, i, dht22_checksum;
int16 temperatura, humedad;
float temp,hum;
dht_io=0; // configurar el pin como salida
output_high(dht22);
delay_us(20);
output_low(dht22);
delay_ms(18);
output_high(dht22);
delay_us(22);
dht_io=1;// configurar el pin como entrada
delay_us(5);
dht22_in=input(dht22);
if(dht22_in) {
//GlobalErr=1;
printf("\r\ndht condicion 1 de inicio no encontrada");
return;
}
delay_us(80);
dht22_in=input(dht22);
if(!dht22_in){
//GlobalErr=2;
printf("\r\ndht condicion 2 de inicio no encontrada");
return;
}
delay_us(80);
for (i=0; i<5; i++){
dht22_dat[ i ] = leer_datos_dht(); // capturando datos
}
dht_io=0;
delay_us(10);
output_high(dht22);
dht22_checksum= dht22_dat[0]+dht22_dat[1]+dht22_dat[2]+dht22_dat[3];
if(dht22_dat[4]!=dht22_checksum){
//GlobalErr=3;
printf("\r\nDHT checksum error");
}
humedad = make16(dht22_dat[0],dht22_dat[1]);
temperatura = make16(dht22_dat[2],dht22_dat[3]);
hum = humedad;
temp = temperatura;
dhthum = (hum)/10;
dthtemp = (temp)/10;
}//Fin Driver



Y este es un ejemplo de como usarla.

#include <18f4550.h>           //PIC utilizado
#device adc=10
//#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG
//#use delay(clock=20M)
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48M)
//Pal bootloader
#build (reset=0x1000,interrupt=0x1008)
#org 0x0000,0x0FFF{}
//#use i2c(Master,slow,sda=PIN_A4,scl=PIN_A5)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include "dht22.c"
//#include <LCD20X4.c>
void main(){
int16 lux;
float dhthum, dthtemp;
setup_adc_ports(AN0|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
//EXT_INT_EDGE(H_TO_L);
//lcd_init();
//lcd_putc("\fSensor T-H\nDHT22 RHT03");
printf ("\f\r\nSensor de temperatura y humedad:\r\nDHT22-RHT03");
delay_ms(500);
//printf(lcd_putc,"\fHola-Saludos\nEnviame un dato");
dht_init();
sht21_init();
delay_ms(300);
//lcd_putc("\f");
while(true){
set_adc_channel(0);
delay_ms(1);
lux=read_adc();
printf("\r\nAdc =: %lu ",lux);
delay_ms(10);
leer_dht22(dhthum, dthtemp);
delay_ms(10);
printf("\r\nDHT22 Humedad = %f %%",dhthum);
delay_ms(1);
printf("\r\nDHT22 Temperatura = %f %cC", dthtemp,223);
delay_ms(1);
printf("\r\n...terminado..\n");
delay_ms(2000);
}
}



La versión que comparto sirve para valores positivos de temperatura para valores negativos hay que agregar 2 líneas de código más, eso ya se los dejo a ustedes.
por ultimo les dejo el link de la librería original


http://www.todopic.com.ar/foros/index.php?topic=35680.0


Saludos!


Les dejo unos videos del la librería funcionando.




Comentarios

  1. hola

    muy buena el driver. me hace mucha falta para ir puliendo un proyecto mas grande.
    Yo estoy mas acostubrado a trabajar con picbasic. Y me estoy introduciendo en el CCS.
    Lo que no veo claro que hay que añadir para que funcione la temperatura con valores negativos, nose como introducirlo en la variable float.

    Por lo que e entendido en el datasheet. es que el valor de la temperatura el bit mas significativo te indica si es un valor positivo o negativo.

    Si fuera tan amable de indicarme como lo haces tu.

    Muchas gracias por la ayuda

    ResponderEliminar
    Respuestas
    1. hola, disculpa eso que pides aproposito lo deje así para que le pensaran como hacerlo, saludos

      Eliminar
  2. Hola,

    estoy intentando hacer funcionar el sensor DHT22 con el PIC 18F4550 y no he tenido suerte, supongo que me esta faltando configurar algo, ya intente conectarlo a otro pin diferente, intente cambiando el cristal de 20 Mhz por uno de 4 Mhz, pero sale siempre por la opcion "ht condicion 1 de inicio no encontrada". El sensor lo tengo conectado: pata1 Vcc, pata 2 al PIN 15 del PIC (RC0) con una resistencia de 10K (tambien probe con 4K7) a Vcc, pata 3 sin conectar y pata 4 a tierra.

    El código es el mismo "pero".... lo pase a MikroC:
    /* ARCHIVO DHT22_new.c*/
    #ifndef __DHT22_NEW_C
    #define __DHT22_NEW_C
    #include
    #include
    #include

    short int dht22_dat[5];

    void dht_init (void){
    dht_io=0;
    Delay_Ms(1);
    dht22=1;
    }

    short int leer_datos_dht(void){
    short int i = 0;
    short int result=0;
    for (i=0; i< 8; i++) {
    //We enter this during the first start bit (low for 50uS) of the byte
    //Next: wait until pin goes high
    while(dht22==0);
    delay_us(30);
    if (dht22==1){//Was: if(PINC & _BV(dht_PIN))
    result |=(1<<(7-i));
    }
    while (dht22==1);
    //Was: while((PINC & _BV(dht_PIN)));
    }//end of "for.."

    return result;
    }

    void leer_dht22(){// (char *dhthum, char *dthtemp){
    //byte GlobalErr=0;
    unsigned short dht22_in, i, dht22_checksum;
    int temperatura, humedad;
    float temp, hum;
    char message1[10];
    char message2[10];

    dht_io=0; // configurar el pin como salida
    dht22=1;
    Delay_Us(20);
    dht22=0;
    Delay_Ms(18);
    dht22=1;
    Delay_Us(22);

    dht_io=1;// configurar el pin como entrada
    Delay_Us(5);
    dht22_in=dht22;

    if(dht22_in) {
    //GlobalErr=1;
    My_Lcd_Out_Clear(1,1,"Con 1 de inicio no encontrada");
    return;
    }

    Delay_Us(80);
    dht22_in=dht22;

    if(!dht22_in){
    //GlobalErr=2;
    My_Lcd_Out_Clear(1,1,"con 2 de inicio no encontrada");
    return;
    }

    delay_us(80);

    for (i=0; i<5; i++){
    dht22_dat[ i ] = leer_datos_dht(); // capturando datos
    }

    dht_io=0;
    delay_us(10);
    dht22=1;

    dht22_checksum= dht22_dat[0]+dht22_dat[1]+dht22_dat[2]+dht22_dat[3];

    if(dht22_dat[4]!=dht22_checksum){
    //GlobalErr=3;
    My_Lcd_Out_Clear(1,1,"\r\nDHT checksum error");
    }

    message1[0] = dht22_dat[2]/10 + 48;
    message1[1] = dht22_dat[2]%10 + 48;
    message1[2] = dht22_dat[3]/10 + 48;
    message1[3] = 223; // Degree symbol
    message1[4] = '\0';
    message2[0] = dht22_dat[0]/10 + 48;
    message2[1] = dht22_dat[0]%10 + 48;
    message2[2] = dht22_dat[1]/10 + 48;
    message2[3] = '\0';

    Lcd_Cmd(_Lcd_Clear);
    Lcd_Out(1, 1, message1);
    Lcd_Out(2, 1, message2);

    /*humedad = make16(dht22_dat[0],dht22_dat[1]);
    temperatura = make16(dht22_dat[2],dht22_dat[3]);

    hum = humedad;
    temp = temperatura;

    dhthum = (hum)/10;
    dthtemp = (temp)/10;*/
    }
    #endif

    /* ARCHIVO DHT22_new.h*/
    #ifndef __DHT22_NEW_H
    #define __DHT22_NEW_H

    #define dht22 RC0_bit
    #define dht_io TRISC0_bit

    void dht_init (void);
    short int leer_datos_dht(void);
    void leer_dht22 ();//float *dhthum,float *dthtemp);

    #endif

    /* ARCHIVO PINCIPAL */
    #includes...
    ...
    void main(){
    ADCON0=0;
    ADCON1=00001111;// 'All digital
    CMCON=7;// 'Comparators OFF
    INTCON2=0;//
    delay_ms(500);
    dht_init();
    Delay_ms(100);
    while(1) {
    leer_dht22();
    Delay_ms(100);

    }
    }

    será el sensor que esta funcionando mal? o es problema del la traduccion a MikroC?

    Saludos,

    ResponderEliminar
    Respuestas
    1. hola, y esta parte
      #define dht22 PIN_A2
      #bit dht_io = 0xf92.2

      donde o como la declaras en mikroC?

      existe el: make16 en mikroC?

      prácticamente lo dejaste = que el mio, así que no lo tradujiste bien al mikroc, y yo desconozco mikroC

      saludos

      Eliminar
    2. Hola como estas? la parte que tu tienes como:
      #define dht22 PIN_A2
      #bit dht_io = 0xf92.2
      en mikroC es:
      #define dht22 RC0_bit //Define cual es el pin de datos
      #define dht_io TRISC0_bit //Define la direccion si es entrada o salida.

      Creo que no existe la instruccion make, por eso comente esa parte del código, sin embargo nunca llega hasta ahi porque falla en la inicializacion del sensor. Yo creo que esta relacionado con el tiempo y con la configuracion de los osciladores.

      Seguire investigando y probando,
      gracias de todas formas,
      Saludos,
      Alejandro.

      Eliminar
  3. hola nuna pregunta solo para confirmar el DHT22 es igual al RHT03 o funciona igual muchas gracias

    ResponderEliminar
  4. muchas gracias por responder.
    ahora tengo otra pregunta:
    despues de que el sensor confirma que va a enviar los datos luego sigue el tren de pulsos corespondiente al los 40 bits (para la suma de los 5 Bytes) y empieza con un bajo de 50us y luego depende de la longitud del pulso alto se detrmina si es 1 o 0 y luego termina con un bao de 50us (siendo 26 a 28 us para un cero y de 70us para un 1) para despues seguir con el siguente bit. eso fue lo que entendi de el datasheet me podrias decir si estoy en lo cierto o no ? muchas gracias

    ResponderEliminar
  5. nos ayudarias a crear este mismo programa en mplab

    ResponderEliminar
  6. Modificaciones en los delay de la libreria dht22.c para que funcione en proteus 8.

    ///Driver DHT22

    #define dht22 PIN_A2
    #bit dht_io = 0xf92.2
    byte dht22_dat[5];
    byte leer_datos_dht();
    Void dht_init (void){
    dht_io=0;
    delay_ms(1);
    output_high(dht22);
    }
    byte leer_datos_dht(){
    byte i = 0;
    byte result=0;
    for (i=0; i< 8; i++) {
    //We enter this during the first start bit (low for 50uS) of the byte
    //Next: wait until pin goes high
    while(input(dht22)==0);
    delay_us(30);
    if (input(dht22)==1){//Was: if(PINC & _BV(dht_PIN))
    result |=(1<<(7-i));
    }
    while (input(dht22)==1);
    //Was: while((PINC & _BV(dht_PIN)));
    }//end of "for.."
    return result;
    }
    Void leer_dht22 (float &dhthum,float &dthtemp){
    //byte GlobalErr=0;
    byte dht22_in, i, dht22_checksum;
    int16 temperatura, humedad;
    float temp,hum;
    dht_io=0; // configurar el pin como salida
    output_high(dht22);
    delay_us(25);
    output_low(dht22);
    delay_ms(18);
    output_high(dht22);
    delay_us(30);
    dht_io=1;// configurar el pin como entrada
    delay_us(5);
    dht22_in=input(dht22);
    if(dht22_in) {
    //GlobalErr=1;
    printf("\r\ndht condicion 1 de inicio no encontrada");
    return;
    }
    delay_us(80);
    dht22_in=input(dht22);
    if(!dht22_in){
    //GlobalErr=2;
    printf("\r\ndht condicion 2 de inicio no encontrada");
    return;
    }
    delay_us(80);
    for (i=0; i<5; i++){
    dht22_dat[ i ] = leer_datos_dht(); // capturando datos
    }
    dht_io=0;
    delay_us(10);
    output_high(dht22);
    dht22_checksum= dht22_dat[0]+dht22_dat[1]+dht22_dat[2]+dht22_dat[3];
    if(dht22_dat[4]!=dht22_checksum){
    //GlobalErr=3;
    printf("\r\nDHT checksum error");
    }
    humedad = make16(dht22_dat[0],dht22_dat[1]);
    temperatura = make16(dht22_dat[2],dht22_dat[3]);
    hum = humedad;
    temp = temperatura;
    dhthum = (hum)/10;
    dthtemp = (temp)/10;
    }//Fin Driver

    ResponderEliminar
    Respuestas
    1. pero en la realidad la librería funciona con tus modificaciones o solo para tu simulación?

      Eliminar
  7. #include <18f4550.h>

    #device adc=10 //Usa resolución de 10 bits
    #fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
    #use delay(clock=8000000)
    #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

    //LCD
    #define LCD_DB4 PIN_D0
    #define LCD_DB5 PIN_D1
    #define LCD_DB6 PIN_D2
    #define LCD_DB7 PIN_D3
    #define LCD_RS PIN_C0
    #define LCD_E PIN_C1
    #include "flex_lcd.C" // cambiar comillas

    //DHT22
    #include "dht22.C" // cambiar comillas
    void main(){
    //DHT22
    float dhthum, dthtemp;
    lcd_init();
    lcd_putc("\fSensor T-H\nDHT22 RHT03");
    printf ("\f\r\nSensor de temperatura y humedad:\r\nDHT22-RHT03");
    delay_ms(500);
    printf(lcd_putc,"\fHola-Saludos\nEnviame un dato");
    dht_init();
    delay_ms(300);

    while(true){
    //DHT22
    leer_dht22(dhthum, dthtemp);
    delay_ms(10);
    printf("\r\nDHT22 Humedad = %f %%",dhthum);
    printf("\r\nDHT22 Temperatura = %f %cC", dthtemp,223);
    printf(lcd_putc,"\fHum= %f %%",dhthum);
    printf(lcd_putc,"\nTemp= %f %cC", dthtemp,223);
    printf("\r\n%f",dthtemp);
    delay_ms(1);
    printf("\r\n...terminado..\n");
    delay_ms(2000);


    }
    }

    ResponderEliminar
  8. Me sale un problema en el compilador CCS #bit dht_io = 0xf92.2.
    No sé porqué? agradezco quien me pueda colaborar.

    ResponderEliminar
    Respuestas
    1. que pic usas?
      ese 0xf92.2 es un registro interno del pic, tu debes cambiarlo por el pic que uses

      Eliminar
  9. disculpa me podrias ayudar como puedo conectar dos dht22?

    ResponderEliminar
  10. Hola, estoy tratando de modificar la librería para un programa que ya tengo hecho, que tenía un one wire en PIN_A0 de un 16f886 le defino #define dht22 PIN_A0 y lo dejo con #bit dht_io = 0xf92.2 y me muestra los valores bien en proteus, en la "protoboard no funciona" :S .Le cambio #bit dht_io = 0x85.0 que si no me equivoco 0x85 es la dirección de TRISA para el 16f886 y no me muestra valores de humedad ni temperatura en proteus....... 2 preguntas nunca trabaje directamente con la memo de esta forma siempre use #use fast_io(A) y set_tris_x(x), como puedo definir el resto de los pines como de entrada y salida?.
    acabo de sacarle #use fast_io(A) y el set_tris y me arranca el circuito en la proto pero en temp me da un valor de 8 cifras en temp punto y un valor más (y me imagino que en hum también pero no se acaba a ver uso un display de 16x2), y no me funciona el resto del programa.... se me quemaron los papeles alguien me puede dar una mano?,

    ResponderEliminar

Publicar un comentario

Entradas populares