SHT75

General discussion on mikroC.
Author
Message
dariush_abbasi
Posts: 120
Joined: 11 May 2008 18:47

#16 Post by dariush_abbasi » 31 Jul 2009 17:42

Hi,
Would you please tell me what is the usage of the following 3 line?
And how should i change the register settings in main for 16f877A or 18F452?

Code: Select all

 OSCCON=0x71;
 ANSEL=0;
 ANSELH=0;
Thanks.

around
Posts: 119
Joined: 27 May 2008 23:16
Location: Victoria, BC Canada
Contact:

#17 Post by around » 31 Jul 2009 20:39

You need to spend some time reading the datasheets.

The settings of these registers are clearly explained in each datasheet. Once you understand what the setting is used for, then you can determine how you need to change them for different processors.

Using a higher-level language like C does not remove the requirement to understand how the processor functions at the more basic levels.

Cheers,

Adrian

barbarossa
Posts: 37
Joined: 25 Jan 2007 14:18
Location: Sweden, Tågarp

#18 Post by barbarossa » 31 Jul 2009 22:30

what Adrian said

//Andreas

dariush_abbasi
Posts: 120
Joined: 11 May 2008 18:47

#19 Post by dariush_abbasi » 03 Aug 2009 20:09

Hi,
I change your code for PIC18F452 but there is a problem.
Without the "calc_sth11 and Command" functions the LCD shows "H0 T0"
but with those functions my LCD doesn't work!?
What should i do?
here is my code.
Thanks a lot.

Code: Select all

enum {TEMP,HUMI};
#define FALSE            0
#define TRUE             1
#define DATA_T           TRISB.F4
#define DATA_P           PORTB.F4
#define SCK_T            TRISB.F6
#define noACK            0
#define ACK              1
                                //adr  command  r/w
#define MEASURE_TEMP     0x03   //000   0001    1
#define MEASURE_HUMI     0x05   //000   0010    1

//LCD pin conf
sbit LCD_RS at RC7_bit;
sbit LCD_EN at RC6_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC3_bit;

sbit LCD_RS_Direction at TRISC7_bit;
sbit LCD_EN_Direction at TRISC6_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC3_bit;



unsigned char in_string[16]={0},in_i=0,in_stop=FALSE;


////////////////////////////////////////////////////////////////////////////////


void Write_Float(float tmp_var)
{
   char tmp_string[16];
   FloatToStr(tmp_var,tmp_string);
   Uart1_Write_Text(tmp_string);
   Uart1_Write('\r');

}
////////////////////////////////////////////////////////////////////////////////
void Write_Int(unsigned int tmp_int)
{
   char tmp_string[16];
   IntToStr(tmp_int,tmp_string);
   Uart1_Write_Text(tmp_string);
   Uart1_Write('\r');

}
////////////////////////////////////////////////////////////////////////////////
void Write_LCD(unsigned char row, unsigned char col,float tmp_var)
{
   char tmp_string[16];
   FloatToStr(tmp_var,tmp_string);
   LCD_Out(row,col,tmp_string);
}

////////////////////////////////////////////////////////////////////////////////
void Command(float *var)
{
   unsigned char i=0,position,tmp_string[16];
   if ((in_string[0]>='0')&&  (in_string[0]<='6') )
   {
     position=in_string[0]-48;
     while(in_string[i])
     {
        tmp_string[i]=in_string[i+2];
        i++;
     }
     if (i>1) var[position]=atof(tmp_string);  //if position is followed by float
     else Write_Float(var[position]);
   }
}

////////////////////////////////////////////////////////////////////////////////




//------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
  unsigned char i,error=0;
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  {
    if (i & value) DATA_T=1;          //masking value with i , write to SENSI-BUS
    else DATA_T=0;
    SCK_T=1;                          //clk for SENSI-BUS
    asm nop;asm nop;asm nop;        //pulswith approx. 5 us
    SCK_T=0;
  }
  DATA_T=1;                           //release DATA_T-line
  SCK_T=1;                            //clk #9 for ack
  error=DATA_P;                       //check ack (DATA_T will be pulled down by SHT11)

  SCK_T=0;
  return error;                     //error=1 in case of no acknowledge
}

//------------------------------------------------------------------------------
char s_read_byte(char ack)
//------------------------------------------------------------------------------
{    unsigned char i, val = 0;
     for (i=0x80;i>0;i/=2)
     {
         SCK_T = 1;
         if (DATA_P) val = (val | i);
         SCK_T = 0;
     }
     DATA_T = !ack;
     SCK_T = 1;
     asm nop;asm nop;asm nop;
     SCK_T = 0;
     DATA_T = 1;


     return val;
}
//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
//         _____         ________
// DATA_T:      |_______|
//             ___     ___
// SCK_T : ___|   |___|   |______
{
   DATA_T=1;
   SCK_T=0;                   //Initial state
   asm nop;
   SCK_T=1;
   asm nop;
   DATA_T=0;
   asm nop;
   SCK_T=0;
   asm nop;asm nop;asm nop;
   SCK_T=1;
   asm nop;
   DATA_T=1;
   asm nop;
   SCK_T=0;
}

//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA_T-line=1 and at least 9 SCK_T cycles followed by transstart
//         _____________________________________________________         ________
// DATA_T:                                                      |_______|
//            _    _    _    _    _    _    _    _    _        ___     ___
// SCK_T : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{
  unsigned char i;
  DATA_T=1; SCK_T=0;                    //Initial state
  for(i=0;i<9;i++)                  //9 SCK_T cycles
  { SCK_T=1;
    SCK_T=0;
  }
  s_transstart();                   //transmission start
}


//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value,unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) without checksum
{
  unsigned error=0;
  unsigned int i;

  s_transstart();                   //transmission start
  switch(mode)
  {                     //send command to sensor
    case TEMP   : error+=s_write_byte(MEASURE_TEMP); break;
    case HUMI   : error+=s_write_byte(MEASURE_HUMI); break;
    default     : break;
  }
  for (i=0;i<65535;i++) if(DATA_P==0) break; //wait until sensor has finished the measurement
  if(DATA_P) error+=1;                // or timeout (~? sec.) is reached
  *(p_value+1)=s_read_byte(ACK);    //read the first byte (MSB)
  *(p_value)=s_read_byte(noACK);    //read the second byte (LSB)
  return error;
}
/*
void calc_sth11(float *p_h ,float *p_t, float *var)
{
  float h, t;            // rh:      Humidity [Ticks] 12 Bit
              // t:       Temperature [Ticks] 14 Bit
  h=*p_h;
  t=*p_t;

  t=var[5]+var[6]*t;                  //calc. temperature from ticks to [°C]
  h=(t-25)*(var[3]+var[4]*h)+var[0]+var[1]*h+var[2]*h*h;

  if(h>100) h=100;       //cut if the value is outside of
  if(h<0.1) h=0.1;       //the physical possible range

  *p_t=t;                //return temperature [°C]
  *p_h=h;                //return humidity[%RH]
}

*/

////////////////////////////////////////////////////////////////////////////////
void main()
{
   unsigned int h_raw,t_raw;
   unsigned char i,error;
   float h_val,t_val,cal[7];

   OSCCON=0x71;
   ADCON1 = 0;
   TRISB=0;
   PORTB=0;
   TRISC=0;
   Lcd_Init();
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Cmd(_LCD_CURSOR_OFF);
   Lcd_Out(1,1,"H");
   Lcd_Out(2,1,"T");
   PIE1=0x20;
   INTCON=0xC0;
   while (1)
   {
      error=FALSE;
      error+=s_measure((unsigned char*) &h_raw,HUMI);  //measure humidity
      error+=s_measure((unsigned char*) &t_raw,TEMP);  //measure temperature
      if(error) s_connectionreset();
      else
      {
         h_val=h_raw;
         t_val=t_raw;
   // calc_sth11(&h_val,&t_val,cal);           //calculate humidity, temperature
         Write_LCD(1,2,h_val);
         Write_LCD(2,2,t_val);

      }
      if (in_stop==TRUE)                            //interpret commands
      {
   //   Command(cal);
         for(i=0;i<16;i++) in_string[i]='\0';        //clear string and flags
         in_stop=FALSE;
         in_i=0;
      }
      delay_ms(1000); // to be changed to timer interrupt

   }
}

dariush_abbasi
Posts: 120
Joined: 11 May 2008 18:47

#20 Post by dariush_abbasi » 05 Aug 2009 15:58

Hi,
Why by adding a function(even a line of code) i can't see the "T" and "H" on LCD???!!
Although the following instructions is before the while,by adding either calc_sth11 or Command(cal) i can see nothing on LCD and MCU doesn't send any data to LCD!

Code: Select all

   Lcd_Out(1,1,"H");
   Lcd_Out(2,1,"T");
Any suggestion?
Thanks in advance.
Bye.

barbarossa
Posts: 37
Joined: 25 Jan 2007 14:18
Location: Sweden, Tågarp

#21 Post by barbarossa » 05 Aug 2009 19:29

no, I have no idea

//A

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#22 Post by zristic » 06 Aug 2009 14:29

dariush_abbasi wrote:Why by adding a function(even a line of code) i can't see the "T" and "H" on LCD???!!
Please, tell us exactly what function you add and then the program stops working?
Thanks.

dariush_abbasi
Posts: 120
Joined: 11 May 2008 18:47

#23 Post by dariush_abbasi » 06 Aug 2009 19:49

Hi,
Thanks a lot for your reply.
When calling either:

Code: Select all

calc_sth11(&h_val,&t_val,cal);
or

Code: Select all

Command(cal);
i can't see the H(on the first row) and T(on the second row) and LCD receives no data and shows nothing,but when change the code to:

Code: Select all

// calc_sth11(&h_val,&t_val,cal);
// Command(cal);
LCD works properly and shows those H AND T on LCD.
I also get into the calc_sth11 function and made the following changes:

Code: Select all

void calc_sth11(float *p_h ,float *p_t, float *var)
{
  float h, t;            // rh:      Humidity [Ticks] 12 Bit
              // t:       Temperature [Ticks] 14 Bit
  h=*p_h;
  t=*p_t;

  //t=var[5]+var[6]*t;                  //calc. temperature from ticks to [°C]
  //h=(t-25)*(var[3]+var[4]*h)+var[0]+var[1]*h+var[2]*h*h;

  // if(h>100) h=100;       //cut if the value is outside of
  //if(h<0.1) h=0.1;       //the physical possible range

  *p_t=t;                //return temperature [°C]
  *p_h=h;                //return humidity[%RH]
}
With deleting the 4 lines of code now i can call the"calc_sth11" function and LCD works,but with either of them LCD halts.
I've checked the code with either MikroC and MikroC PRO and they have same problem.
Thanks again.
Best regards.

barbarossa
Posts: 37
Joined: 25 Jan 2007 14:18
Location: Sweden, Tågarp

#24 Post by barbarossa » 07 Aug 2009 08:38

A/ Define the eeprom according to the image below.
B/ Use 10k pull up on both SCK and DATA pins
C/ Connect the SHT to the pins that are defined by:

Code: Select all

#define DATA_T           TRISB.F4
#define DATA_P           PORTB.F4
#define SCK_T            TRISB.F6 
 



Image

dariush_abbasi
Posts: 120
Joined: 11 May 2008 18:47

#25 Post by dariush_abbasi » 07 Aug 2009 12:22

Hi barbarossa,
Thanks.
I exactly did as you said.
The problem is calc_sth11 function that when i add it ,the LCD stops working!
I wonder what is their relation.

barbarossa
Posts: 37
Joined: 25 Jan 2007 14:18
Location: Sweden, Tågarp

#26 Post by barbarossa » 07 Aug 2009 21:38

Ok, I can't tell you what is wrong.

First you should concentrate on actually get the data from the sensor, so strip the code from everything that is not necessary, i.e. calc_sht11, calibration, Uart..... and put the raw data on the LCD. Then use the conversion constants from the data sheet in calc_sht11. Only after that it would make any sense to implement any calibration feature.

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#27 Post by zristic » 10 Aug 2009 14:16

@dariush_abbasi: can you please provide me the whole project, zipped or rarred to my email: zristic att mikroe.com

Thanks.

dariush_abbasi
Posts: 120
Joined: 11 May 2008 18:47

#28 Post by dariush_abbasi » 10 Aug 2009 20:48

Hi,
I changed the original code once more for "MikroC PRO for PIC" and the same problem appears.
My code:


Code: Select all

typedef union
{ unsigned int i;
  float f;
} value;
//
enum {TEMP,HUMI};

#define DATA_T           TRISB.F4
#define DATA_P           PORTB.F4
#define SCK_T            TRISB.F6

#define noACK 0
#define ACK   1
                            //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

//LCD pin conf
sbit LCD_RS at RC7_bit;
sbit LCD_EN at RC6_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC3_bit;

sbit LCD_RS_Direction at TRISC7_bit;
sbit LCD_EN_Direction at TRISC6_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC3_bit;

void Write_LCD(unsigned char row, unsigned char col,float tmp_var)
{
   char tmp_string[16];
   FloatToStr(tmp_var,tmp_string);
   LCD_Out(row,col,tmp_string);
}

//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
  unsigned char i,error=0;
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { if (i & value) DATA_T=1;          //masking value with i , write to SENSI-BUS
    else DATA_T=0;
    SCK_T=1;                          //clk for SENSI-BUS
    asm nop;asm nop;asm nop;        //pulswith approx. 5 us
    SCK_T=0;
  }
  DATA_T=1;                           //release DATA-line
  SCK_T=1;                            //clk #9 for ack
  error=DATA_P;                       //check ack (DATA will be pulled down by SHT11)
  SCK_T=0;
  return error;                     //error=1 in case of no acknowledge
}

//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
  unsigned char i,val=0;
  DATA_T=1;                           //release DATA-line
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { SCK_T=1;                          //clk for SENSI-BUS
    if (DATA_P) val=(val | i);        //read bit
    SCK_T=0;
  }
  DATA_T=!ack;                        //in case of "ack==1" pull down DATA-Line
  SCK_T=1;                            //clk #9 for ack
  asm nop;asm nop;asm nop;          //pulswith approx. 5 us
  SCK_T=0;
  DATA_T=1;                           //release DATA-line
  return val;
}

//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
//       _____         ________
// DATA_T:      |_______|
//           ___     ___
// SCK_T : ___|   |___|   |______
{
   DATA_T=1; SCK_T=0;                   //Initial state
   asm nop;
   SCK_T=1;
   asm nop;
   DATA_T=0;
   asm nop;
   SCK_T=0;
   asm nop;asm nop;asm nop;
   SCK_T=1;
   asm nop;
   DATA_T=1;
   asm nop;
   SCK_T=0;
}

//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA_T:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK_T : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{
  unsigned char i;
  DATA_T=1; SCK_T=0;                    //Initial state
  for(i=0;i<9;i++)                  //9 SCK cycles
  { SCK_T=1;
    SCK_T=0;
  }
  s_transstart();                   //transmission start
}

//----------------------------------------------------------------------------------
char s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset
{
  unsigned char error=0;
  s_connectionreset();              //reset communication
  error+=s_write_byte(RESET);       //send RESET-command to sensor
  return error;                     //error=1 in case of no response form the sensor
}

//----------------------------------------------------------------------------------
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
  unsigned char error=0;
  s_transstart();                   //transmission start
  error=s_write_byte(STATUS_REG_R); //send command to sensor
  *p_value=s_read_byte(ACK);        //read status register (8-bit)
  *p_checksum=s_read_byte(noACK);   //read checksum (8-bit)
  return error;                     //error=1 in case of no response form the sensor
}

//----------------------------------------------------------------------------------
char s_write_statusreg(unsigned char *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
  unsigned char error=0;
  s_transstart();                   //transmission start
  error+=s_write_byte(STATUS_REG_W);//send command to sensor
  error+=s_write_byte(*p_value);    //send value of status register
  return error;                     //error>=1 in case of no response form the sensor
}

//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
  unsigned error=0;
  unsigned int i;

  s_transstart();                   //transmission start
  switch(mode){                     //send command to sensor
    case TEMP        : error+=s_write_byte(MEASURE_TEMP); break;
    case HUMI        : error+=s_write_byte(MEASURE_HUMI); break;
    default     : break;
  }
  for (i=0;i<65535;i++) if(DATA_P==0) break; //wait until sensor has finished the measurement
  if(DATA_P) error+=1;                // or timeout (~2 sec.) is reached
  *(p_value+1)=s_read_byte(ACK);    //read the first byte (MSB)
  *(p_value)=s_read_byte(noACK);    //read the second byte (LSB)
  *p_checksum =s_read_byte(noACK);  //read checksum
  return error;
}


//----------------------------------------------------------------------------------------
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature [°C] and humidity [%RH]
// input :  humi [Ticks] (12 bit)
//          temp [Ticks] (14 bit)
// output:  humi [%RH]
//          temp [°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

  float rh,t,rh_lin,rh_true,t_C;
  rh= *p_humidity;
  t = *p_temperature;


  t_C=t*0.01 - 40;                  //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 [°C]
  *p_humidity=rh_true;              //return humidity[%RH]
}

//----------------------------------------------------------------------------------
void main()
//----------------------------------------------------------------------------------
// sample program that shows how to use SHT11 functions
// 1. connection reset
// 2. measure humidity [ticks](12 bit) and temperature [ticks](14 bit)
// 3. calculate humidity [%RH] and temperature [°C]
// 4. calculate dew point [°C]
// 5. print temperature, humidity, dew point

{ value humi_val,temp_val;
  unsigned char error,checksum;
  OSCCON=0x71;
  ADCON1 = 0;
  TRISB=0;
  PORTB=0;
  TRISC=0;
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Out(1,1,"H: ");
  Lcd_Out(2,1,"T: ");
  PIE1=0x20;
  INTCON=0xC0;
  s_connectionreset();
  while(1)
  { error=0;
    error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);  //measure humidity
    error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);  //measure temperature
    if(error!=0) s_connectionreset();                 //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
//******HEAR IS THE PROBLEM""""""""""""
      calc_sth11(&humi_val.f,&temp_val.f);            //calculate humidity, temperature
      Write_LCD(1,4,humi_val.f);
      Write_LCD(2,4,temp_val.f);


    }
    //----------wait approx. 0.8s to avoid heating up SHTxx------------------------------
    delay_ms(800);     //(be sure that the compiler doesn't eliminate this line!)
    //-----------------------------------------------------------------------------------
  }
}
LCD without "calc_sth11" function:
Image
LCD with "calc_sth11" function:
Image

I don't expect to get the exact data on LCD but at least some numbers.
As far as i know there is no relation between adding a function and halting the LCD,because LCD initializations is before everything and the code must show those "H: & T:" at least once.
However i can't figure out what is the problem.
Thanks everybody for reading my posts.

dariush_abbasi
Posts: 120
Joined: 11 May 2008 18:47

#29 Post by dariush_abbasi » 10 Aug 2009 20:54

Hi dear zristic,
Thanks a lot for your favor.
I'll post the project.
Maybe there is something wrong with my register settings.

User avatar
nikola.kostic
mikroElektronika team
Posts: 433
Joined: 11 Aug 2009 12:12

#30 Post by nikola.kostic » 11 Aug 2009 12:46

Hello dariush_abbasi,

We tested your latest code including calc_sth11 function on our EasyPIC5 board and using mikroC PRO compiler v 2.50. Our LCD shows letters H: and L: and some values for both of them. Therefore, we could not reproduce the problem you described.

Post Reply

Return to “mikroC General”