PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   PIC - Thiết kế và Ứng dụng (http://www.picvietnam.com/forum/forumdisplay.php?f=23)
-   -   rắc rối với pic 16F877a và cảm biến SHT11 (http://www.picvietnam.com/forum/showthread.php?t=5080)

tiendungkct 14-10-2009 09:00 PM

rắc rối với pic 16F877a và cảm biến SHT11
 
1 Attachment(s)
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
Code:


#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:
Code:

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

Sht11
 
1 Attachment(s)
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

Trích:

Nguyên văn bởi nvtiep3ik50hut (Post 30485)
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


Múi giờ GMT. Hiện tại là 12:30 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam