Autor Tema: DHT11 con 16F877A  (Leído 532 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 70
DHT11 con 16F877A
« en: 07 de Marzo de 2020, 18:48:30 »
Hola buenas a todos, una consulta. Tengo este código para el funcionamiento del sensor que me funciona bárbaro con un cristal de 8 Mhz, el tema es que lo necesito acoplar a otro programa en el cual estoy usando un cristal de 4Mhz, lo cual el código del sensor DHT11 no me funciona con un cristal de 4Mhz, quería consultar si alguien sabe el porque...???

Aqui coloco el código del programa del sensor que funciona bien con el cristal de 8Mhz

Código: C++
  1. //LCD module connections
  2. #define LCD_RS_PIN PIN_B0
  3. #define LCD_RW_PIN PIN_B1
  4. #define LCD_ENABLE_PIN PIN_B2
  5. #define LCD_DATA4 PIN_B3
  6. #define LCD_DATA5 PIN_B4
  7. #define LCD_DATA6 PIN_B5
  8. #define LCD_DATA7 PIN_B6
  9. //End LCD module connections
  10.  
  11. #include <16F877A.h>
  12. #fuses HS,NOWDT,NOPROTECT,NOLVP                      
  13. #use delay(clock = 8M)
  14. #include <lcd.c>            // include LCD driver source file
  15. #use fast_io(A)
  16. #define DHT11_PIN PIN_A0    // connection pin between DHT11 and mcu
  17.  
  18. char message1[] = "Temp = 00.0 C  ";
  19. char message2[] = "RH   = 00.0 %  ";
  20.  
  21. short Time_out;
  22.  
  23. unsigned int8 T_byte1, T_byte2, RH_byte1, RH_byte2, CheckSum ;
  24.  
  25.  
  26. void start_signal(){
  27.   output_drive(DHT11_PIN);    // configure connection pin as output
  28.   output_low(DHT11_PIN);      // connection pin output low
  29.   delay_ms(18);
  30.   output_high(DHT11_PIN);     // connection pin output high
  31.   delay_us(40);
  32.   output_float(DHT11_PIN);    // configure connection pin as input
  33. }
  34. short check_response(){
  35.   delay_us(40);
  36.   if(!input(DHT11_PIN)){      // read and test if connection pin is low
  37.     delay_us(80);
  38.     if(input(DHT11_PIN)){     // read and test if connection pin is high
  39.       delay_us(50);
  40.       return 1;
  41.     }
  42.   }
  43. }
  44. unsigned int8 Read_Data(){
  45.   unsigned int8 i, k, _data = 0;        // k is used to count 1 bit reading duration
  46.   if(Time_out)
  47.     break;
  48.   for(i = 0; i < 8; i++){
  49.     k = 0;
  50.     while(!input(DHT11_PIN)){           // Wait until DHT11 pin get raised
  51.       k++;
  52.       if(k > 100){
  53.         Time_out = 1;
  54.         break;
  55.       }
  56.       delay_us(1);
  57.     }
  58.     delay_us(30);
  59.     if(!input(DHT11_PIN))
  60.       bit_clear(_data, (7 - i));        // Clear bit (7 - i)
  61.     else{
  62.       bit_set(_data, (7 - i));          // Set bit (7 - i)
  63.       while(input(DHT11_PIN)){          // Wait until DHT11 pin goes low
  64.         k++;
  65.         if(k > 100){
  66.         Time_out = 1;
  67.         break;
  68.       }
  69.       delay_us(1);}
  70.     }
  71.   }
  72.   return _data;
  73. }
  74. void main(){
  75.   lcd_init();                                 // Initialize LCD module
  76.   lcd_putc('\f');                             // LCD clear
  77.   delay_ms(1000);
  78.  
  79.   while(TRUE){
  80.     Time_out = 0;
  81.     Start_signal();
  82.     if(check_response()){                     // If there is a response from sensor
  83.       RH_byte1 = Read_Data();                 // read RH byte1
  84.       RH_byte2 = Read_Data();                 // read RH byte2
  85.       T_byte1 = Read_Data();                  // read T byte1
  86.       T_byte2 = Read_Data();                  // read T byte2
  87.       Checksum = Read_Data();                 // read checksum
  88.       if(Time_out){                           // If reading takes long time
  89.         lcd_putc('\f');                       // LCD clear
  90.         lcd_gotoxy(5, 1);                     // Go to column 5 row 1
  91.         lcd_putc("Time out!");
  92.       }
  93.       else{
  94.        if(CheckSum == ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) & 0xFF)){
  95.          message1[7]  = T_Byte1/10  + 48;
  96.          message1[8]  = T_Byte1%10  + 48;
  97.          message1[10] = T_Byte2/10  + 48;
  98.          message2[7]  = RH_Byte1/10 + 48;
  99.          message2[8]  = RH_Byte1%10 + 48;
  100.          message2[10] = RH_Byte2/10 + 48;
  101.          message1[11] = 223;                   // Degree symbol
  102.          lcd_gotoxy(1, 1);                     // Go to column 1 row 1
  103.          printf(lcd_putc, message1);           // Display message1
  104.          lcd_gotoxy(1, 2);                     // Go to column 1 row 2
  105.          printf(lcd_putc, message2);           // Display message2
  106.        }
  107.        else{
  108.          lcd_putc('\f');                       // LCD clear
  109.          lcd_gotoxy(1, 1);                     // Go to column 1 row 1
  110.          lcd_putc("Checksum Error!");
  111.        }
  112.       }
  113.     }
  114.     else {
  115.       lcd_putc('\f');                          // LCD clear
  116.       lcd_gotoxy(3, 1);                        // Go to column 3 row 1
  117.       lcd_putc("No response");
  118.       lcd_gotoxy(1, 2);                        // Go to column 1 row 2
  119.       lcd_putc("from the sensor");
  120.     }
  121.   delay_ms(1000);
  122.   }
  123. }

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1184
Re:DHT11 con 16F877A
« Respuesta #1 en: 07 de Marzo de 2020, 19:13:02 »
Tienes que volver a recompilar el código definiendo que estás usando un cristal de 4MHz en lugar de 8MHz, así como configurar los fuses correctamente para ese cristal, de lo contrario no funcionará.
Igual tienes que verificar los delay de 1us, ya que con cristal de 4MHz cada ciclo instrucción es de 1us si usas assembler, pero ahora estás usando C, por lo que esos delays pueden no estar generándose correctamente, intenta incrementarlos a unos 10 a 20 us.

elreypic.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 70
Re:DHT11 con 16F877A
« Respuesta #2 en: 07 de Marzo de 2020, 19:58:20 »
cambie los fuse por los que tengo en el otro programa que vengo utilizando con el cristal de 4Mhz y el cristal

los tiempo probe con 10 y 20 us y me sale  "time out" en el LCD

Código: C++
  1. #FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP    
  2. #use delay(clock=4M)
  3.  

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1184
Re:DHT11 con 16F877A
« Respuesta #3 en: 09 de Marzo de 2020, 11:36:18 »
Que tal martinchd,

He analizado la hoja de datos del sensor, y por lo que veo en tu código existe un delay de 1us, el cual te dije originalmente que aumentaras a de 10 a 20 us, pero eso no es posible, mi error. Mas bien ese delay de 1us ya no es necesario; elimínalo.

elreypic.
« Última modificación: 09 de Marzo de 2020, 13:46:07 por elreypic2 »

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1184
Re:DHT11 con 16F877A
« Respuesta #4 en: 17 de Marzo de 2020, 07:27:07 »
Que tal martinchd,

No se si pudiste resolver el problema. Pero si no es así, me puse manos a la obra un par de horas el fin de semana y resolví la situación de poder leer el DHT11 con el PIC16F877A con un cristal de 4MHz. Hice la simulación en proteus y me funcionó. Aquí está el código:

Código: [Seleccionar]
#define LCD_ENABLE_PIN PIN_B2
#define LCD_RS_PIN PIN_B0
#define LCD_RW_PIN PIN_B1
#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7

#include <16F877A.h>
#device ADC=10
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal=4000000)
#include <lcd.c>
#use fast_io(A)
#define DHT11_PIN PIN_A0    // connection pin between DHT11 and mcu

char message1[] = "Temp = 00.0 C  ";
char message2[] = "RH   = 00.0 %  ";
 
short Time_out;
 
unsigned int8 T_byte1, T_byte2, RH_byte1, RH_byte2, CheckSum ;
 
 
void start_signal(){
  output_drive(DHT11_PIN);    // configure connection pin as output
  output_low(DHT11_PIN);      // connection pin output low
  delay_ms(18);
  output_float(DHT11_PIN);    // configure connection pin as input
  delay_us(40);
}

short check_response(){
  delay_us(40);
  if(!input(DHT11_PIN)){      // read and test if connection pin is low
    delay_us(80);
    if(input(DHT11_PIN)){     // read and test if connection pin is high
      delay_us(50);
      return 1;
    }
  }
}

unsigned int8 Read_Data(){
  unsigned int8 i, k, _data = 0;        // k is used to count 1 bit reading duration
  if(Time_out)
    break;
  for(i = 0; i < 8; i++){
    k = 0;
    while(!input(DHT11_PIN)){           // Wait until DHT11 pin get raised
      k++;
      if(k > 100){
        Time_out = 1;
        break;
      }
    }
    delay_us(24);
    if(!input(DHT11_PIN))
      bit_clear(_data, (7 - i));        // Clear bit (7 - i)
    else{
      bit_set(_data, (7 - i));          // Set bit (7 - i)
      while(input(DHT11_PIN)){          // Wait until DHT11 pin goes low
        k++;
        if(k > 100){
        Time_out = 1;
        break;
        }
      }
    }
  }
  return _data;
}
void main(){
  lcd_init();                                 // Initialize LCD module
  lcd_putc('\f');                             // LCD clear
  delay_ms(1000);
 
  while(TRUE){
    Time_out = 0;
    Start_signal();
    if(check_response()){                     // If there is a response from sensor
      RH_byte1 = Read_Data();                 // read RH byte1
      RH_byte2 = Read_Data();                 // read RH byte2
      T_byte1 = Read_Data();                  // read T byte1
      T_byte2 = Read_Data();                  // read T byte2
      Checksum = Read_Data();                 // read checksum
      if(Time_out){                           // If reading takes long time
        lcd_putc('\f');                       // LCD clear
        lcd_gotoxy(5, 1);                     // Go to column 5 row 1
        lcd_putc("Time out!");
      }
      else{
       if(CheckSum == ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) & 0xFF)){
         message1[7]  = T_Byte1/10  + 48;
         message1[8]  = T_Byte1%10  + 48;
         message1[10] = T_Byte2/10  + 48;
         message2[7]  = RH_Byte1/10 + 48;
         message2[8]  = RH_Byte1%10 + 48;
         message2[10] = RH_Byte2/10 + 48;
         message1[11] = 223;                   // Degree symbol
         lcd_gotoxy(1, 1);                     // Go to column 1 row 1
         printf(lcd_putc, message1);           // Display message1
         lcd_gotoxy(1, 2);                     // Go to column 1 row 2
         printf(lcd_putc, message2);           // Display message2
       }
       else{
         lcd_putc('\f');                       // LCD clear
         lcd_gotoxy(1, 1);                     // Go to column 1 row 1
         lcd_putc("Checksum Error!");
       }
      }
    }
    else {
      lcd_putc('\f');                          // LCD clear
      lcd_gotoxy(3, 1);                        // Go to column 3 row 1
      lcd_putc("No response");
      lcd_gotoxy(1, 2);                        // Go to column 1 row 2
      lcd_putc("from the sensor");
    }
  delay_ms(1000);
  }
}

Espero te sirva.

elreypic.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 70
Re:DHT11 con 16F877A
« Respuesta #5 en: 20 de Marzo de 2020, 20:01:27 »
Muchisimas gracias "elreypic2" anduvo bárbaro.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 70
Re:DHT11 con 16F877A
« Respuesta #6 en: 20 de Marzo de 2020, 20:15:39 »
lo probe en Proteus y funciona barbaro, cuando lo grabo en el pic y lo pruebo en el circuito, me pide temp y hr pero me parpadea el display con el texto - No response from the sensor- Que sera. ?

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1184
Re:DHT11 con 16F877A
« Respuesta #7 en: 22 de Marzo de 2020, 11:08:02 »
lo probe en Proteus y funciona barbaro, cuando lo grabo en el pic y lo pruebo en el circuito, me pide temp y hr pero me parpadea el display con el texto - No response from the sensor- Que sera. ?

En realidad no lo probé en el circuito real ya que no cuento con sensores DHT11. Si pudieras colocar el circuito que estás usando en la realidad, tal vez ahí esté la falla. O bien que se requiera ajustar los tiempos de comunicación entre el PIC y el sensor.
De otra manera me haces una pregunta en la estoy a ciegas y no es posible adivinar. Jejeje.

elreypic.


 

anything