DHT11 code from pic18f4550 does not work with pic18f57Q84

66 views Asked by At

I am trying to read the DHT11 on a PIC18f57Q84 and display it to an LCD screen. I found somebody online who did this for a PIC18f4550 and tried to make it work on my PIC18f57Q84 development board. I am very new PIC and MPLAB X IDE so I essentially just modified the code until it built. But of course it doesn't work. Link to site https://www.electronicwings.com/pic/dht11-sensor-interfacing-with-pic18f4550

I copied the .c and .h files into the source and header folders respectively for the project. I removed the OSSCON line since it wasn't working and I changed the syntax of some of the register definitions to work with what I am used to. I also changed the #include pic18f4550 to #include pic18f57q84. One thing I noticed is that even though I need to have Configuration_Header_File.h located in the header folder of the project in order to successfully build the program, most of that file goes unrecognized and stops the build if I #include it. The only file I really changed is the humidity_temp.c file. I have checked the wiring of the LCD and DHT11 so those shouldnt be the problem.

   #include <pic18f57q84.h>
#include <xc.h>
#include <stdio.h>
#include "LCD_16x2_8-bit_Header_File.h"

#define Data_Out LATAbits.LATA0             /* assign Port pin for data*/
#define Data_In PORTAbits.RA0 /* read data from Port pin*/
#define Data_Dir TRISAbits.TRISA0      /* Port direction */
#define _XTAL_FREQ 8000000          /* define _XTAL_FREQ for using internal delay */

void DHT11_Start();
void DHT11_CheckResponse();
char DHT11_ReadData();


void main() 
{
    char RH_Decimal,RH_Integral,T_Decimal,T_Integral;
    char Checksum;
    char value[10];    
   

    LCD_Init();         /* initialize LCD16x2 */
    ADCON1=0x0F;        /* this makes all pins as a digital I/O pins */    
    while(1)
    {   
        DHT11_Start();                  /* send start pulse to DHT11 module */
        DHT11_CheckResponse();          /* wait for response from DHT11 module */
        
        /* read 40-bit data from DHT11 module */
        RH_Integral = DHT11_ReadData(); /* read Relative Humidity's integral value */
        RH_Decimal = DHT11_ReadData();  /* read Relative Humidity's decimal value */
        T_Integral = DHT11_ReadData();  /* read Temperature's integral value */
        T_Decimal = DHT11_ReadData();   /* read Relative Temperature's decimal value */
        Checksum = DHT11_ReadData();    /* read 8-bit checksum value */
        
        /* convert humidity value to ascii and send it to display*/    
        sprintf(value,"%d",RH_Integral);
        LCD_String_xy(0,0,value);
        sprintf(value,".%d ",RH_Decimal);
        LCD_String(value);
        LCD_Char('%');
        
        /* convert temperature value to ascii and send it to display*/
        sprintf(value,"%d",T_Integral);
        LCD_String_xy(1,0,value);
        sprintf(value,".%d",T_Decimal);
        LCD_String(value);
        LCD_Char(0xdf);
        LCD_Char('C');
        
        sprintf(value,"%d  ",Checksum);
        LCD_String_xy(1,8,value);
        
        /* check addition of humidity and temperature value equals to checksum */
        if(Checksum != (RH_Integral + RH_Decimal + T_Integral + T_Decimal))
            LCD_String_xy(0,8,"Error");
        else
            LCD_String_xy(0,8,"No Error");
        
        MSdelay(500);
        
    }
}

char DHT11_ReadData()
{
  char i,data = 0;  
    for(i=0;i<8;i++)
    {
        while(!(Data_In & 1));      /* wait till 0 pulse, this is start of data pulse */
        __delay_us(30);         
        if(Data_In & 1)             /* check whether data is 1 or 0 */    
          data = ((data<<1) | 1); 
        else
          data = (data<<1);  
        while(Data_In & 1);
    }
  return data;
}

void DHT11_Start()
{    
    Data_Dir = 0;       /* set as output port */
    Data_Out = 0;       /* send low pulse of min. 18 ms width */
    __delay_ms(18);
    Data_Out = 1;       /* pull data bus high */
    __delay_us(20);
    Data_Dir = 1;       /* set as input port */    
//    LED = 14;
}

void DHT11_CheckResponse()
{
    while(Data_In & 1);     /* wait till bus is High */     
    while(!(Data_In & 1));  /* wait till bus is Low */
    while(Data_In & 1);     /* wait till bus is High */
} 
1

There are 1 answers

0
Kozmotronik On

Migrating from one old PIC model to a newer model could be kind of painful if you don't refer to their respective datasheets. The PIC18F57Q84 is one of the recent PIC18 models chip that has many new features.

Well, if I look at your code, the first thing I can say you that you don't have to include the pic18f57q84 explicitly. The xc.h will refer to the needed chip headers automatically if you select the right chip model in your MPLABX IDE.

Second, the actual bug in your migrated code that leaves your project unfunctional is the port setup. The ADCON1 register in the PIC18F57Q84 has nothing to do with controlling analog functionality of the GPIOs. It may be relevant for the older chip though. So for the newer chip you need to disable analog function of GPIOs by using the corresponding ANSELx register. In your case, it would be the ANSELA register to be modified. According to my theory, if you change this line

ADCON1=0x0F;        /* this makes all pins as a digital I/O pins */

to the following

ANSELA = 0;        /* this makes all PORTA pins as a digital I/O pins */

your project should become functional with your new chip.