CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem with DHT11 humidity and temp measurement
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

Problem with DHT11 humidity and temp measurement
PostPosted: Fri May 02, 2014 12:39 am     Reply with quote

I have interfaced DHT11 humidity and temp sensor with pic microcontroller.
Controller used: 16F690. Compiler ver: 4.114. Oscillator: internal oscillator 4Mhz

Below is the code:
main.c
Code:
#include "16F690.h"
#fuses INTRC_IO
#use delay(clock=4000000)

#define DHT_IO   PIN_C0

#define RS   PIN_B4
#define RW   PIN_B6
#define EN   PIN_A4

int1 bExit;
unsigned int8 iByteIndex;

unsigned int16 CRC;
unsigned int Humidity;
unsigned int Temperature;

unsigned char DHT_Data[];

void lcd_init();
void lcd_cmd(unsigned char c);
void lcd_data(unsigned char z);
void disp_cmd(unsigned char cmd_value);
void disp_data(unsigned char data_value);

#int_rtcc                         
void Set_Enable()               
{                               
   // This function is called every time Timer0 overflows (255->0). Timer0 is setup
   // so that this occurs approx. 15 times per second, or once every 66mS.
   
   if (!bExit)                       
   bExit = True;
}

void DHT_Start(void)
{
   // Here we send the 'start' sequence to the DHT sensor! We pull the DHT_IO pin low for 25mS, and
   // then high for 30mS. The DHT sensor then responds by pulling the DHT_IO pin low, and then pulling it
   // back high.
   
   Output_low(DHT_IO);
   delay_ms(25);
   Output_high(DHT_IO);
   delay_us(30);
   
   // Here we wait while the DHT_IO pin remains low.....
   bExit = False;
   set_timer0(0);
   while (!input(DHT_IO) && !bExit);

   // Here we wait while the DHT_IO pin remains high.....
   bExit = False;
   set_timer0(0);
   while (input(DHT_IO) && !bExit);
}

int8 DHT_ReadData(void)
{
   // This subroutine reads a byte of data (8 bits) from the DHT sensor...
   int8 iIndex;
   int8 iValue = 0;

   for(iIndex = 0; iIndex < 8 ; iIndex++)
   {
      bExit = False;
      set_timer0(0);
      while (!input(DHT_IO) && !bExit);
      delay_us(30);

      if (input(DHT_IO))
      {
         iValue = iValue |(1<<(7 - iIndex));
         bExit = False;
         set_timer0(0);
         while (input(DHT_IO) && !bExit);
      }
   }

   return iValue;   
}

void main()
{
   setup_comparator(NC_NC_NC_NC);
   SETUP_ADC(ADC_OFF);
   SETUP_CCP1(CCP_OFF);

   setup_timer_0(T0_internal | T0_8_bit);
   set_timer0(0);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   lcd_init();
   disp_cmd(0x80);
   printf(disp_data, "Humidity        ");

   disp_cmd(0xC0);
   printf(disp_data, "Measurement     ");

   delay_ms(2000);

   disp_cmd(0x01);

   while(1)
   {
      // Here we send the initialization sequence to "wake up" the DHT sensor, and put it into
      // data transmission mode.
      DHT_Start();
      
      // Here we read a total of 5 bytes of data (40 bits) from the DHT sensor. For the DHT-11 sensor,
      // the integer data is contained in the 1st (Humidity), and 3rd (Temperature) bytes transmitted,
      // and the 2nd and 4th decimal bytes are always zero (0). For the DHT-22 sensor, the integer data is
      // is contained in the 1st (Humidity), and 3rd (Temperature) bytes transmitted, and the decimal
      // data is contained in the 2nd (Humidity), and 4th (Temperature) bytes transmitted. The 5th byte
      // contains the CRC byte for both sensor types.
      for (iByteIndex = 0; iByteIndex < 5 ; iByteIndex++)
      {
         DHT_Data[iByteIndex] = DHT_ReadData();
      }
      
      // Here we calculate the CRC by adding the 1st four bytes, and looking at only the lower 8 bits.
      // This value should match the 5th byte sent by the sensor which is the CRC byte!
      CRC = DHT_Data[0] + DHT_Data[1] + DHT_Data[2] + DHT_Data[3];
      CRC = CRC & 0xFF;
      
      if (CRC != DHT_Data[4] && !bExit)
   //   fprintf(PC, "CRC Error, expected: %Lu, and received: %u\n\r", CRC, DHT_Data[4]);
      
      Humidity = DHT_Data[0];
      Temperature = DHT_Data[2];

      disp_cmd(0xC0);
      printf(disp_data, "Humidity: %2u %%", Humidity);

      delay_ms(5000);
      //fprintf(PC, "Humidity: %ld%%\n\r", Humidity);
      //fprintf(PC, "Temperature: %ldC\n\r", Temperature);
   }
}

void lcd_init()
{
   disp_cmd(0x02);      // To initialize LCD in 4-bit mode.
   disp_cmd(0x28);      // To initialize LCD in 1 lines, 5x7 dots and 4bit mode.
   disp_cmd(0x0C);
   disp_cmd(0x01);
   disp_cmd(0x06);
   disp_cmd(0x80);
}

void lcd_cmd(unsigned char c)
{
   output_c(c);
   output_low(RS);
   output_low(RW);
   output_high(EN);
   delay_ms(15);
   output_low(EN);
}

void lcd_data(unsigned char z)
{
   output_c(z);
   output_high(RS);
   output_low(RW);
   output_high(EN);
   delay_ms(15);
   output_low(EN);
}

void disp_cmd(unsigned char cmd_value)
{
   unsigned char cmd_value1;
   cmd_value1=(cmd_value & 0xF0);
   lcd_cmd(cmd_value1);               // Send to LCD
   cmd_value1 = ((cmd_value<<4) & 0xF0);   // Shift 4-bit and mask
   lcd_cmd(cmd_value1);               // Send to LCD
}

void disp_data(unsigned char data_value)
{
   unsigned char data_value1;
   data_value1=(data_value & 0xF0);
   lcd_data(data_value1);
   data_value1 = ((data_value<<4) & 0xF0);
   lcd_data(data_value1);
}


When i power up, it displays humidity measurement for 2 secs and then it displays Humidity: 0%. Why it is not displaying humidity values.

I'm testing in the real hardware. To show the circuit, i have drawn the circuit in proteus and shown here
https://imageshack.com/i/nelh1qwj

Please help
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 02, 2014 12:44 am     Reply with quote

Quote:
unsigned char DHT_Data[];

The error is in the line above.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri May 02, 2014 12:48 am     Reply with quote

Code:
unsigned char DHT_Data[4];


Will it solve my problem?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 02, 2014 1:01 am     Reply with quote

Quote:
unsigned char DHT_Data[4];
Will it solve my problem?


for (iByteIndex = 0; iByteIndex < 5 ; iByteIndex++)
{
DHT_Data[iByteIndex] = DHT_ReadData();
}

You are using array indexes from 0 to 4. That's 5 elements.
So you still have a problem.

You are writing code for a driver, which is at least an intermediate topic.
I'm not trying to beat up on you, but this array stuff should have been
learned a long time ago.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri May 02, 2014 1:03 am     Reply with quote

I got it now,
Code:
unsigned char DHT_Data[5];


Hope now its ok
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri May 02, 2014 7:27 am     Reply with quote

When i changed to
Code:
unsigned char DHT_Data[5]


Display always shows 253% all the time.

What could be the problem?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 02, 2014 8:39 am     Reply with quote

Quote:
#include "16F690.h"
#fuses INTRC_IO
#use delay(clock=4000000)


#int_rtcc
void Set_Enable()
{
// This function is called every time Timer0 overflows (255->0). Timer0 is setup
// so that this occurs approx. 15 times per second, or once every 66mS.

if (!bExit)
bExit = True;
}


Quote:

setup_timer_0(T0_internal | T0_8_bit);


Quote:
5.0 TIMER0 MODULE
The Timer0 module is an 8-bit timer/counter.

There are 8 prescaler options for the Timer0 module
ranging from 1:2 to 1:256.


Timer0 is clocked at Fosc/4, which is 1 MHz for your program.
To get an interrupt rate of 15 Hz, you would need to do this:

1 MHz / 65536 = 15 Hz (approx.)

But your Timer0 setup doesn't have a prescaler of T0_DIV_256.
It's missing that parameter:
Quote:

setup_timer_0(T0_internal | T0_8_bit);
Ttelmah



Joined: 11 Mar 2010
Posts: 19561

View user's profile Send private message

PostPosted: Fri May 02, 2014 8:41 am     Reply with quote

A couple of things to think about, related to the timer....
Code:

   bExit = False;
   set_timer0(0);

What happens if the timer times out between the two instructions?. 1 in 256 probability of this happening (with the current timer programming), and if it does bExit will immediately be TRUE.

You need to set the timer to zero _before_ clearing BExit.

Then your timing is wrong.

You have the timer programmed to use 8bit, and it counts from Fosc/4. The timer will interrupt 3906 times per second, not 15 times per second. BExit is always going to get set TRUE before the line changes. To give 15* per seocnd, you need the /256 prescaler selected. Then it'll give 1000000/(256*256) = 15.25* per second.

setup_timer_0(T0_INTERNAL | T0_8_BIT | T0_DIV_256);
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Fri May 02, 2014 8:43 am     Reply with quote

Hi,

Quote:
'What could be the problem?'


That is kind of an open-ended question, don't you think? It could be any number of problems!

Did you change anything else in your code? You definitely need the 5 elements in your array, so that should not cause your issue! Post any other changes you've made!

Your posted code appears to be based on some DHT11 driver code that I posted a while back. You seem to have made a number of key changes that have disabled that (working) code? You appear to be a bit of a 'newbie' programmer lacking in a lot of basic 'C' programming knowledge', so I'm wondering what motivated you to try to 'improve' the working code?

John
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri May 02, 2014 9:46 pm     Reply with quote

I didn't change another other part of the code.

Yes ezflyr, I'm using your library to display the humidity on lcd.

my complete code:
Code:
#include "16F690.h"
#fuses INTRC_IO
#use delay(clock=4000000)

#define DHT_IO   PIN_C0

#define RS   PIN_B4
#define RW   PIN_B6
#define EN   PIN_A4

int1 bExit;
unsigned int8 iByteIndex;

unsigned int16 CRC;
unsigned int16 Humidity;
unsigned int16 Temperature;

unsigned int16 DHT_Data[5];

void lcd_init();
void lcd_cmd(unsigned char c);
void lcd_data(unsigned char z);
void disp_cmd(unsigned char cmd_value);
void disp_data(unsigned char data_value);

#int_rtcc                         
void Set_Enable()               
{                               
   // This function is called every time Timer0 overflows (255->0). Timer0 is setup
   // so that this occurs approx. 15 times per second, or once every 66mS.
   
   if (!bExit)                       
   bExit = True;
}

void DHT_Start(void)
{
   // Here we send the 'start' sequence to the DHT sensor! We pull the DHT_IO pin low for 25mS, and
   // then high for 30mS. The DHT sensor then responds by pulling the DHT_IO pin low, and then pulling it
   // back high.
   
   Output_low(DHT_IO);
   delay_ms(25);
   Output_high(DHT_IO);
   delay_us(30);
   
   // Here we wait while the DHT_IO pin remains low.....
   bExit = False;
   set_timer0(0);
   while (!input(DHT_IO) && !bExit);

   // Here we wait while the DHT_IO pin remains high.....
   bExit = False;
   set_timer0(0);
   while (input(DHT_IO) && !bExit);
}

int8 DHT_ReadData(void)
{
   // This subroutine reads a byte of data (8 bits) from the DHT sensor...
   int8 iIndex;
   int8 iValue = 0;

   for(iIndex = 0; iIndex < 8 ; iIndex++)
   {
      bExit = False;
      set_timer0(0);
      while (!input(DHT_IO) && !bExit);
      delay_us(30);

      if (input(DHT_IO))
      {
         iValue = iValue |(1<<(7 - iIndex));
         bExit = False;
         set_timer0(0);
         while (input(DHT_IO) && !bExit);
      }
   }

   return iValue;   
}

void main()
{
   setup_comparator(NC_NC_NC_NC);
   SETUP_ADC(ADC_OFF);
   SETUP_CCP1(CCP_OFF);

   setup_timer_0(T0_INTERNAL | T0_8_BIT | T0_DIV_256);
   set_timer0(0);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   lcd_init();
   disp_cmd(0x80);
   printf(disp_data, "Humidity        ");

   disp_cmd(0xC0);
   printf(disp_data, "Measurement     ");

   delay_ms(2000);

   disp_cmd(0x01);

   while(1)
   {
      // Here we send the initialization sequence to "wake up" the DHT sensor, and put it into
      // data transmission mode.
      DHT_Start();
      
      // Here we read a total of 5 bytes of data (40 bits) from the DHT sensor. For the DHT-11 sensor,
      // the integer data is contained in the 1st (Humidity), and 3rd (Temperature) bytes transmitted,
      // and the 2nd and 4th decimal bytes are always zero (0). For the DHT-22 sensor, the integer data is
      // is contained in the 1st (Humidity), and 3rd (Temperature) bytes transmitted, and the decimal
      // data is contained in the 2nd (Humidity), and 4th (Temperature) bytes transmitted. The 5th byte
      // contains the CRC byte for both sensor types.
      for (iByteIndex = 0; iByteIndex < 5 ; iByteIndex++)
      {
         DHT_Data[iByteIndex] = DHT_ReadData();
      }
      
      // Here we calculate the CRC by adding the 1st four bytes, and looking at only the lower 8 bits.
      // This value should match the 5th byte sent by the sensor which is the CRC byte!
      CRC = DHT_Data[0] + DHT_Data[1] + DHT_Data[2] + DHT_Data[3];
      CRC = CRC & 0xFF;
      
      if (CRC != DHT_Data[4] && !bExit)
   //   fprintf(PC, "CRC Error, expected: %Lu, and received: %u\n\r", CRC, DHT_Data[4]);
      
      Humidity = DHT_Data[0];
      Temperature = DHT_Data[2];

      disp_cmd(0xC0);
      printf(disp_data, "Humidity: %4lu %% ", Humidity);

      delay_ms(2000);
      //fprintf(PC, "Humidity: %ld%%\n\r", Humidity);
      //fprintf(PC, "Temperature: %ldC\n\r", Temperature);
   }
}

void lcd_init()
{
   disp_cmd(0x02);      // To initialize LCD in 4-bit mode.
   disp_cmd(0x28);      // To initialize LCD in 1 lines, 5x7 dots and 4bit mode.
   disp_cmd(0x0C);
   disp_cmd(0x01);
   disp_cmd(0x06);
   disp_cmd(0x80);
}

void lcd_cmd(unsigned char c)
{
   output_c(c);
   output_low(RS);
   output_low(RW);
   output_high(EN);
   delay_ms(15);
   output_low(EN);
}

void lcd_data(unsigned char z)
{
   output_c(z);
   output_high(RS);
   output_low(RW);
   output_high(EN);
   delay_ms(15);
   output_low(EN);
}

void disp_cmd(unsigned char cmd_value)
{
   unsigned char cmd_value1;
   cmd_value1=(cmd_value & 0xF0);
   lcd_cmd(cmd_value1);               // Send to LCD
   cmd_value1 = ((cmd_value<<4) & 0xF0);   // Shift 4-bit and mask
   lcd_cmd(cmd_value1);               // Send to LCD
}

void disp_data(unsigned char data_value)
{
   unsigned char data_value1;
   data_value1=(data_value & 0xF0);
   lcd_data(data_value1);
   data_value1 = ((data_value<<4) & 0xF0);
   lcd_data(data_value1);
}
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Sat May 03, 2014 8:18 am     Reply with quote

Display reads the wrong value which is showing constantly 1997 %...
temtronic



Joined: 01 Jul 2010
Posts: 9253
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat May 03, 2014 9:15 am     Reply with quote

Since it's not displaying right, you have to 'break' the program into 2 parts. 'Reading the sensor' and 'displaying the data'.

For starters, I'd fix the variable 'humidity' to a valid number that you expect and see what the LCD shows.
This simple test will confirm the LCD 'driver' code is functioning properly.
Actually you should use several known values, say 0, midpoint, maximum.

recode/recompile/retest/report back.....

hth
jay
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

PostPosted: Sat May 03, 2014 12:39 pm     Reply with quote

I had something to do with similar sensor RHT03.
I did read data successfully.
This is the driver:
Code:

void RHT03_Init(void)
{
   printf("\fRHT03 Initialization. . .");
   delay_ms(1500);                              //When power is supplied to sensor, don't send any instruction to the sensor within one second to pass unstable status
   printf("\fRHT03 Initialization done!");
}

void RHT_Start()
{
   output_low(RHT_IO);     // MCU pull low data bus  this process must beyond 1~10ms
   delay_ms(15);           // this process must beyond 1~10ms
   output_float(RHT_IO);   // MCU will pulls up and wait 20-40us for RHT03's response.
   while(input(RHT_IO));   // Wait for RHT03 pulls low the buss for 80uS as response signal
   while(!input(RHT_IO));   // Wait for RHT03 pulls up 80us for preparation to send data
   While(input(RHT_IO));   // RHT03 prepares data for being send (80uS)
}



int8 RHT_ReadData(void)    //RHT03 is sending data to MCU
{
int8 iIndex;
int8 iValue=0;
   for(iIndex = 0; iIndex < 8 ; iIndex++) //filling 8bit variable, bit by bit, according to RHT03 input state,
   {
      while(!input(RHT_IO));     // every bit's transmission begin with low-voltage-level that last 50us
      delay_us(35);             
      shift_left(&iValue, 1, input(RHT_IO));
      while(input(RHT_IO));
   }
   return iValue;
}


and this is the code that handle it.

Code:

#INCLUDE <16F1508.h>
#FUSES INTRC_IO, NOMCLR, NOWDT, PUT, NOBROWNOUT
#USE delay(internal=16M)
#USE rs232(BAUD=9600, UART1,ERRORS)

#define RHT_IO Pin_B6
#Define LED PIN_C7

#Include <C:\Users\Riko\Desktop\Leonid_Silistra\CCS\RHT-03 driver\RHT03.c>


void PrintData(int B1, int B2, int B3, int B4);

void main (void)
{
int8 i;
int8 ByteIndex[5];
RHT03_Init();

While (True)
   {
   RHT_Start();                                 //immediately after this line we must call reading of 40bits data
   
      for (i=0;i<5;i++)                         //5 bytes being read in this loop
      {
         ByteIndex[i] = RHT_ReadData();
      }
   
   
   if(ByteIndex[0]+ByteIndex[1]+ByteIndex[2]+ByteIndex[3]==ByteIndex[4])
      printf("\r DATA Reception Succesful!");
   else
      printf("\rDATA Garbage!");
   PrintData(ByteIndex[0],ByteIndex[1],ByteIndex[2],ByteIndex[3]);
      delay_ms(2300);                        //The process of data reception must last more than 2secs
     
   }
}


void PrintData(int B1, int B2, int B3, int B4)
{
int16 humidity;
int16 temperature;
int1 TempSign;                         //the sign of the temperature (either minus or plus)
   TempSign = bit_test(B3,7);          //bit 7 determines if temerature is positive or negative, (=1-negative), (=0 positive)
   humidity = make16(B1,B2);           //assemble entire byte for humidity
   temperature = make16(B3,B4);        //assemble entire byte for humidity
   temperature &= 0b0111111111111111;  //exclude the sign of the temperature so I can convert it to a float value
   
   if(TempSign)                        //If temperature 15th bit is==1 the temperature value is negative
      printf(" T = -%.1f",(float)temperature/10);   //Note that I manualy put the minus sign
   else
      printf(" T = %.1f",(float)temperature/10);
     
   printf(" RH = %.1f",(float)humidity/10);
}

_________________
A person who never made a mistake never tried anything new.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Sun May 04, 2014 9:06 pm     Reply with quote

hi rikotech8, it displays RHT03 Initialization. . . and then,
RHT03 Initialization done! and stays there itself.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon May 05, 2014 4:12 am     Reply with quote

Hi hemnath,

If all you can do is report the output messages from a particular program with no ability to understand what is going on, or to troubleshoot any further, then I don't think you've got any future as an embedded developer/programmer.....

Sorry!

John

Ps The driver you are now using is poorly written because there are many places it can hang without any feedback to the user at all. You need to find out where this is happening, and more importantly, why......
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group