Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help me fix my code for programming SHT11 in C

Status
Not open for further replies.

daisy11

Newbie level 2
Joined
Jun 3, 2010
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,296
New to C-Programming here.....

I based most of my code around stuff I found online..most is taken from datasheet

Compiler is Hi-Tech. The LCD prints out 15.40 C when it should be room temp (~22C). Humidity is obviously also wrong because it is a function of temperature.

The LCD does change values when I hold my finger to it for instance, so I know that the communication is fine. PIC16f887 is running 4 MHz at 5V for both chip and sensor.

I think the problem is with the math and maybe the bit size...



Code:
/*******************************************************************************
*******************************************************************************/

#include <delay.h>
#include <lcd.h>
#include <htc.h>
__CONFIG(INTCLK & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & DUNPROTECT &
BORDIS & IESOEN & FCMDIS & LVPDIS & DEBUGEN & WP2);
#include <math.h>
#include <stdio.h>

 
enum {TEMP,HUMI};

#define TRIS_DATA TRISC5    //data port condition: input/output
#define TRIS_SCK  TRISC4

#define DATA RC5         //SHT11 DATA pin
#define SCK RC4          //STH11 SCK pin

#define noACK 0
#define ACK 1

//adrress commands from Sensirion   //adr ||command || r/w
#define STATUS_REG_W 0x06           //000    0011       0
#define STATUS_REG_R 0x07           //000    0011       1
#define MEASURE_TEMP 0x03           //000    0001       1
#define MEASURE_HUMI 0x05           //000    0010       1
#define RESET 0x1e                  //000    1111       0

//Constants used for SHT Humidity Measurment
#define C1 -4.0
#define C2 0.0405
#define C3  -0.0000028

//Constants used for SHT Temeperature Measurment (14 Bit)
#define D1 -40.0
#define D2 0.01

// constant use for SHT True Humidity Measurement (12 Bit)
#define T1  0.01
#define T2  0.00008



/************************************************************
// writes a byte on the Sensibus and checks the acknowledge
***************************************************************/
//------------------------------------------------------------------------------
unsigned char s_write_byte(unsigned char value)
//------------------------------------------------------------------------------	
		
{
	
	
   unsigned char i,error=0;
   TRIS_DATA = 0;   //SHT11 WRITE...make DATA-line output
   SCK=0; //initial state
   for (i=0x80;i>0;i/=2) //shift bit for masking
   {
     DelayUs(5);
     if (i & value)
         DATA=1; //masking value with i , write to SENSI-BUS
     else
         DATA=0;
     SCK=1; //clk for SENSI-BUS
     
     DelayUs(5);   //pulswith approx. 5 us
     
     SCK=0;
   }

  
   TRIS_DATA = 1;    //SHT11 READ..make DATA-line input
   DelayUs(5);
   SCK=1; //clk #9 for ack
   DelayUs(5);
   error = DATA; //check ack (DATA will be pulled down by SHT11)
   SCK=0;
   return error; //error=1 in case of no acknowledge
}


/****************************************************************************/
// reads a byte from the Sensibus and gives an acknowledge in case of "ack=1"
/****************************************************************************/

unsigned char s_read_byte(unsigned char ack)
{
   unsigned char i,val=0;
   TRIS_DATA = 1;        //SHT11 READ
   //DATA=1; //release DATA-line
   for (i=0x80;i>0;i/=2) //shift bit for masking
   {
     DelayUs(5);
     SCK=1; //clk for SENSI-BUS
     if (DATA)
     val=(val | i); //read bit		
     DelayUs(5);
     SCK=0;
   }
   TRIS_DATA = 0;    //make DATA-Line output
   DATA=!ack;         //in case of "ack==1" pull down DATA-Line
   SCK=1; //clk #9 for ack 
   DelayUs(5); //pulswith approx. 5 us
   SCK=0;
   TRIS_DATA=1;
   //DATA=1; //release DATA-line
   return val;
}


//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{
   TRIS_DATA = 0;   //SHT11 WRITE - DATA_Line output

   DATA=1;
   SCK=0;   //Initial state
   DelayUs(5);
   SCK=1;
   DelayUs(5);
   DATA=0;
   DelayUs(5);
   SCK=0;
   DelayUs(5);
   SCK=1;
   DelayUs(5);
   DATA=1;
   DelayUs(5);
   SCK=0;
}


//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{
   unsigned char i;
   TRIS_DATA = 0;  //SHT11 WRITE
   DATA=1; SCK=0;  //Initial state
   for(i=0;i<12;i++) //12 SCK cycles....more than 9 for safe being
   {
	 SCK=1;
     DelayUs(5);
     SCK=0;
   }
   s_transstart(); //transmission start
}


//----------------------------------------------------------------------------------
void main()
//----------------------------------------------------------------------------------
// 1. Define Ports
// 2. Initalize LCD and reset connection to sensor
// 3. While Loop: calculate humidity [%RH] and temperature []C in 12BIT mod
// 4. print temperature, humidity, dew point

{ 	
	unsigned char error,checksum, byte_1, byte_2;
    int lValue_Temp, lValue_Hum, i;
    int fTemp_true,Rh_lin,fRh_True;
   
 	   //CONFIG1 = 0b1110000011000101;
 	   OSCCON = 0b01100101;
 	   OSCTUNE = 0b00001111;
	   TRISD = 0x00;
       TRISA = 0x00;
       TRISB = 0x00;
       TRISC = 0x00;
       INTCON = 0x00; //disable interrupts
       ANSEL=0x00; //Digital AN[0:7]
       ANSELH = 0x00; //Digital AN[13:8]
       ADCON0=0; //turn off A/D
       
       
   lcd_init();
   s_connectionreset();
   DelayUs(20);
  // s_write_statusreg(0x03); //low resolution data
   while(1)
   {
	   
    
    /********************************************************
      Measure Temperature
    ********************************************************/
    
    s_connectionreset();
    s_transstart(); //transmission start
	s_write_byte(MEASURE_TEMP); //measure Temperature
	while (DATA); //wait until SHT11 ends measurements
	//Save highest byte read, in RAM
	byte_1 =  s_read_byte(ACK);
	//Save lowest byte read, in RAM
	byte_2 =  s_read_byte(noACK);
    lValue_Temp = (byte_1*256) + byte_2; //combines two bytes (8 bit) into a 16 bit (word)
    
    
    /********************************************************
      temperature calculation
    ********************************************************/
    
    fTemp_true = (D1+(D2*lValue_Temp)*100);
    
    /********************************************************
     Meausure Humidity
    ********************************************************/
    
    s_connectionreset(); //Reset Sensor BUS
	s_transstart(); //transmission start
	s_write_byte(MEASURE_HUMI); //measure Humidity
	while (DATA); //wait until SHT11 ends measurements
	//Save highest byte read, in RAM
	byte_1 =(unsigned char)  s_read_byte(ACK);
	//Save lowest byte read, in RAM
	byte_2 = (unsigned char) s_read_byte(noACK);
    lValue_Hum = ((unsigned char)byte_1*256) + (unsigned char)byte_2; //combines two bytes (8 bit) into a 16 bit (word)
    
    /********************************************************
      Humidity calculation
    ********************************************************/
    
    Rh_lin = (C1+(C2*lValue_Hum)+(C3*lValue_Hum*lValue_Hum));
    fRh_True = (((fTemp_true-25)*(T1+(T2*lValue_Hum)))+Rh_lin)*100;
    if((fRh_True/100)>100) fRh_True=10000;
    //if((fRh_True/100)<0.1)fRh_True=0.001;
    
    
    
    /********************************************************
      Print to LCD
    ********************************************************/
    
    char buffer[20];
    sprintf(buffer, "T=%d.%d C H=%d.%d %%", fTemp_true/100, fTemp_true%100, fRh_True/100, fRh_True%100); 
	lcd_goto(0);	// select first line
	lcd_puts(buffer);
     
//----------wait approx. 0.8s to avoid heating up SHTxx----------------------
//-----------------------------------------------------------------------------------
     for(i=0;i<2000;i++)
        DelayUs(8000);

   }
}
 

daisy11,

Were you ever able to get your code working? I ran into similar issues where the RH was really about 44% and the
Temp at 23C and it was reading 66.1C/51%RH.

Mike
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top