New to C-Programming here.....
I based most of my code around stuff I found online, like ghostman's.
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.
I think the problem is with the math and maybe the bit size..I'm a bit )) confused there
Any suggestions?
I based most of my code around stuff I found online, like ghostman's.
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.
I think the problem is with the math and maybe the bit size..I'm a bit
Any suggestions?
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);
}
}