PDA

View Full Version : rắc rối với pic 16F877a và cảm biến SHT11


tiendungkct
14-10-2009, 09:00 PM
mình đang làm việc cảm biến SHT11 và đang gặp vấn đề với cảm biến SHT11 ,mình đọc giá trị nhiệt độ từ cảm biến nhưng giá trị trả về luôn sai cụ thể nhiệt độ mình đọc lên giao động từ 11 độ C đến 14,1 độ C thôi khi lên 14,1 độ C thì nó không tăng nữa mà lại nhảy xuống dưới 14.1 độ C, va độ ẩm đọc vê cũng sai luôn ,mình kiểm tra nhưng không biết sai chổ nào hết .Bạn nào lam qua cho mình kinh nghiệm nhé .thanks


#include <16F877A.h>
#FUSES NOWDT, HS,PUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#include <lcd_lib_4bit.c> //thu vien ham cho lcd_4 bits
#include <math.h>
#use Fast_io(a)
#use Fast_io(b)
#use Fast_io(c)
#use Fast_io(d)
#use Fast_io(e)

typedef union
{ unsigned int i;
float f;
} value;

#define TEMP 0
#define HUMI 1
#define noACK 0
#define ACK_1 1
//adr command r/w
#define STATUS_REG_WRT 0x06 //000 0011 0
#define STATUS_REG_READ 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0

#byte PORTA = 0x05
#byte TRISA = 0x85
#byte PORTB = 0x06
#byte TRISB = 0x86
#bit Port_ctr =TRISB.1 // dieu khien chan data
#bit Sck_dir =TRISB.0
#bit Sck =PORTB.0 // clock for SHT11
#bit DATA =PORTB.1 // data for SHT11



//====================================
void SHT11_Start(void);
void calc_sth11(float *p_humidity ,float *p_temperature);
unsigned char SHT11_Readbyte(unsigned char ack);
unsigned char SHT11_writebyte(unsigned char value);
void SHT11_comm_Rst();
char SHT11_soft_rst();
unsigned char SHT11_measuremant(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
char SHT11_read_reg(unsigned char *p_value, unsigned char *p_checksum);
char SHT11_wrt_reg(unsigned char *p_value);
void ftoa(unsigned char *buf, float f);
unsigned delay=100;//857=1 phut

//====================================

/*================================================= ============================
============================ Cac ham viet cho SHT11===========================
================================================== ===========================*/
/* =================================
ham tao xung start cho SHT11
_____ ________
DATA: |_______|
___ ___
SCK : ___| |___| |______
====================================*/
void SHT11_Start(void)
{
Port_Ctr=0 ; //pin ouput
Data=1; // tao xung start
Sck=0;
delay_us(2);
Sck=1;
Delay_us(2);
Data=0;
Delay_us(2);
Sck=0;
Delay_us(2);
Sck=1;
Delay_us(2);
Data=1;
Delay_us(2);
Sck=0;
}
/* =================================
ham read_byte SHT11
====================================*/
unsigned char SHT11_Readbyte(unsigned char ack)
{
unsigned char i,val=0;

Port_ctr=1; //pin input
data=1; //tha pin data de doc data

for (i=0x80;i>0;i/=2) //shift bit for masking
{
Delay_us(2);
SCK=1; //clk for SENSI-BUS
if (DATA) val=(val | i); //read bit
Delay_us(2);
SCK=0;
}

Delay_us(2);
Port_ctr= 0; //SHT11 WRITE
Delay_us(2);

DATA=!ack; //in case of "ack==1" pull down DATA-Line

SCK=1; //clk #9 for ack
Delay_us(2); //pulswith approx. 5 us
SCK=0;
Delay_us(2);
Port_ctr=1; //release DATA-line

return val;
}


/* ================================================== ================================

================================================== ====================================*/
unsigned char SHT11_Writebyte(unsigned char value)
{
unsigned char i,error=0;

PORT_ctr = 0; //pin out
for (i=0x80;i>0;i/=2) //shift bit for masking
{
Delay_us(2);
if (i & value)
DATA=1; //masking value with i , write to SENSI-BUS
else
DATA=0;
SCK=1; //clk for SENSI-BUS
Delay_us(2); //pulswith approx. 5 us
SCK=0;
}
// DATA=1; //release DATA-line
PORT_ctr = 1; //SHT11 READ
Delay_us(2);
SCK=1; //clk #9 for ack
Delay_us(2);
error = DATA; //check ack (DATA will be pulled down by SHT11)
SCK=0;
return error; //error=1 in case of no acknowledge
}
/*================================================= =============================
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// __________________________________________________ ___ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
================================================== ============================*/
void SHT11_comm_Rst()
{
unsigned char i;
Port_ctr=0; // pin output
Sck_dir=0;
Data=1; //Init state
Sck=0;
for (i=0;i<9;i++)
{
sck=1;
delay_us(2);
Sck=0;
delay_us(2);
}
delay_us(4);
SHT11_start();
}
/*================================================= ============================
Soft reset
================================================== ===========================*/
char SHT11_Soft_Rst()
{
unsigned char error=0;
SHT11_Comm_rst();
error+=SHT11_Writebyte(Reset);
return error ;// error =1 khi ko nhan dc dap ung tu SHT11
}

/*================================================= ============================
Read status register
================================================== ============================*/
char SHT11_read_reg(unsigned char *p_value, unsigned char *p_checksum)
{
unsigned char error=0;
SHT11_start();
error=SHT11_writebyte(Status_reg_read);// send command
*p_value=SHT11_readbyte(ACK_1); //read status register (8-bit)
*p_checksum=SHT11_readbyte(noACK); //read checksum (8-bit)

return error; //error=1 in case of no response form the sensor
}
/*================================================= ============================
write status register
================================================== ============================*/
char SHT11_wrt_reg(unsigned char *p_value)
{
unsigned char error=0;
SHT11_Start(); //transmission start
error+=SHT11_writebyte(STATUS_REG_Wrt);//send command to sensor
error+=SHT11_writebyte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor

}
/*================================================= ============================

================================================== ============================*/
unsigned char SHT11_measuremant(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned char error=0;
unsigned int i;
SHT11_Start();
delay_us(5);
switch (mode)
{ // send command
case TEMP :error += SHT11_Writebyte(Measure_Temp); break;
case HUMI :error += SHT11_writebyte(Measure_Humi); break;
default: break;
}

port_ctr=1; // read data
//delay_ms(320);
for (i = 0; i < 65535 && DATA; i++) Delay_us(100); //wait until sensor has finished the measurement

while (DATA == 1) Delay_us(1);

if(DATA) error+=1; // or timeout (~2 sec.) is reached
*(P_value+1)=(SHT11_readbyte(ACK_1)&0xFF); //read the second byte (MSB)
*(P_Value) =(SHT11_readbyte(ACK_1) &0xFF); //read the first byte (LSB)
*p_checksum =SHT11_readbyte(noACK); //read checksum
return error;

}
/*================================================= ============================
caculator for SHT11
================================================== ============================*/
void calc_sth11(float *p_humidity ,float *p_temperature)
{
float rh,t,rh_lin,rh_true,t_c;
const float C1=-4.0; // for 12 Bit
const float C2= 0.0405; // for 12 Bit
const float C3=-0.0000028; // for 12 Bit
const float T1=0.01; // for 14 Bit @ 5V
const float T2=0.00008; // for 14 Bit @ 5V
rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
t=*p_temperature; // t: Temperature [Ticks] 14 Bit

t_C=(t*0.01 - 39.66); //calc. Temperature from ticks to [C]
rh_lin=C3*rh*rh + C2*rh + C1; //calc. Humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. Temperature compensated humidity [%RH]
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range

*p_temperature=t_C; //return temperature [deg Cel]
*p_humidity=rh_true; //return humidity[%RH]

}
void main(void)
{ value humi_val,temp_val;
unsigned char error,checksum;
unsigned char s[6],s1[6];
SET_TRIS_A(0B00000010);
SET_TRIS_b(0x00);
SET_TRIS_d(0x00);
SET_TRIS_e(0x00);
LCD_init(); //khoi tao lcd
Delay_ms(20);
SHT11_Soft_Rst();
Delay_ms(20);
while(1)
{
error=0;
error+=SHT11_measuremant( (unsigned char*)&humi_val.i,&checksum,HUMI);
//measure humidity
error+=SHT11_measuremant((unsigned char*) &temp_val.i,&checksum,TEMP);
//measure temperature
if(error!=0){ SHT11_comm_Rst(); while(1){led_1=~Led_1;}} //in case of an error: connection reset
else
{
humi_val.f=(float)humi_val.i; //converts integer to float
temp_val.f=(float)temp_val.i; //converts integer to float
calc_sth11(&humi_val.f,&temp_val.f); //calculate humidity, temperatur

LCD_Position(1,1) ;
Printf(LCD_putchar,"TEMP:");
LCD_Position(1,7);
ftoa(s,temp_val.f);
Printf(LCD_putchar,s);

LCD_Position(2,1) ;
Printf(LCD_putchar,"HUMI:");
LCD_Position(2,7);
ftoa(s1,humi_val.f);
Printf(LCD_putchar, s1);
delay_ms(50);
}
}
}

hàm Ftoa của mình:

void ftoa(unsigned char *buf, float f) {
unsigned int rem;
unsigned char *s,length=0;
int i;

i = (int)((float)f*10);

s = buf;
if (i == 0){ //print 0.0 with null termination here
*s++ = '0';
*s++ = '.';
*s++ = '0';
*s=0; //null terminate the string
} else {
if (i < 0) {
*buf++ = '-';
s = buf;
i = -i;
}
//while-loop to "decode" the long integer to ASCII by append '0', string in reverse manner
//If it is an integer of 124 -> string = {'4', '2', '1'}
while (i) {
++length;
rem = i % 10;
*s++ = rem + '0';
i /= 10;
}
//reverse the string in this for-loop, string became {'1', '2', '4'} after this for-loop
for(rem=0; ((unsigned char)rem)<length/2; rem++) {
*(buf+length) = *(buf+((unsigned char)rem));
*(buf+((unsigned char)rem)) = *(buf+(length-((unsigned char)rem)-1));
*(buf+(length-((unsigned char)rem)-1)) = *(buf+length);
}

/* Take care of the special case of 0.x if length ==1*/
if(length==1) {
*(buf+2) = *buf;
*buf = '0';
*(buf+1) = '.';
*(s+2)=0; //null terminate
} else {
*(buf+length) = *(buf+length-1);
*(buf+length-1)='.';
*(s+1)=0; //null terminate
}
}
}


code này mình cũng chỉnh sửa từ code của Senirion
Thanks

falleaf
15-10-2009, 10:41 AM
Nên gửi kèm datasheet của SHT11 thì mọi người mới giúp bạn kiểm tra được chứ.

Chúc vui.

tiendungkct
16-10-2009, 08:53 AM
mình đưa lên datasheet đây mong dc giúp đỡ
thanks

nvtiep3ik50hut
22-10-2009, 10:59 PM
cái này mình làm chạy ngon, nhưng chắc giờ chẳng ai cần nữa...hì

tiendungkct
24-10-2009, 12:26 AM
bạn có thể đưa lên cho mình tham khảo dc ko?
Thanks

minhpic
29-10-2009, 12:35 PM
bạn nào còn SHT11 để lại cho mình một em, đang cần quá. Xin cám ơn
ĐT:0989737456

pucapuca123
05-12-2011, 06:11 PM
cái này mình làm chạy ngon, nhưng chắc giờ chẳng ai cần nữa...hì
bạn đưa project nên cho mọi người tham khảo thì tốt quá nhỉ:D