CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

humidity sensors

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
davt



Joined: 07 Oct 2003
Posts: 66
Location: England

View user's profile Send private message

humidity sensors
PostPosted: Thu Oct 16, 2003 8:50 am     Reply with quote

Hi all
Can anyone recomend a humidity sensor which is cheap and relatively accurate and is easily interfaced to a Pic. I have looked at the sensirion SHT11 but this seems quite expensive and from what I gather needs linearising. If this is the only reasonable device has anyone got a snipet of code to evaluate it?
Many thanks for any help.
Regards.
Dave
TSchultz



Joined: 08 Sep 2003
Posts: 66
Location: Toronto, Canada

View user's profile Send private message

PostPosted: Thu Oct 16, 2003 9:22 am     Reply with quote

The nature of humidity sensor is such that they are difficult to read. From a micro point of view the Sensitron is the easiest to handle since it already has a digital interface. Most of the RH sensors available are either capacitive or inductive and they require specialized excitation and conditioning circuitry to abtian a useable signal. In addition most of them are extremely non-linear, many are actually logarithmetic. An added problem is they are all influenced by temperature and in most cases have to be compensated.

The Philips H1 is one of the more common sensors, it is capacitive with a typical capacitance of 122pF @ 43%RH and has a change of 0.4pF per % RH. Another is Panametrics MiniCap 2, it is also capacitive with a typical capacitance of 207 pF @ 33 % RH, and has a change of 0.3pF per % RH. The Panametrics sensor tends to be fairly linear if driven properly.

Accuracy of these, or any other RH sensor, is highly dependant upon many things, the actual circuit used, the components used, the environment, and contaminants, etc. Keep in mind that many of these sensors are also also very sensitive to contanimants and can be damaged by exposure to things like acetone. They fail becuase the contaminant actually degrades the hygroscopic polymer coating used in the sensor itself.

Some of the newer RH sensors such as the Hygrometrix HMX2000 are micromachined silicon sensors, provide a DC output, are more linear, and are easier to interface to a micro.

The final decision will depend very much on how many you will use, the cost target, and how much work you are willing to invest. All of the RH sensors have their pros and cons, and after having spent the last 15 years working with many of these sensors, I can tell you that they are not at all what they appear to be on paper.
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Thu Oct 16, 2003 9:23 am     Reply with quote

When it comes to measurements accuracy has cost. That SHT11 is an accurate part. As far as linearising goes that only improves it's accuracy. How good is good enough?
rrb011270



Joined: 07 Sep 2003
Posts: 51

View user's profile Send private message Yahoo Messenger

Re: humidity sensors
PostPosted: Thu Oct 16, 2003 6:17 pm     Reply with quote

Check below: This is a code I coded for SHT1x... the code has not yet implemented the Checksum features of the SHT1x...

I guess u can figure it out by reading the appnotes from sensirion...

Yes, SHT1x is an accurate temp & humidity sensor...

davt wrote:
Hi all
Can anyone recomend a humidity sensor which is cheap and relatively accurate and is easily interfaced to a Pic. I have looked at the sensirion SHT11 but this seems quite expensive and from what I gather needs linearising. If this is the only reasonable device has anyone got a snipet of code to evaluate it?
Many thanks for any help.
Regards.
Dave


Code:

#include <18F452.h>           // MCU specific library
#device ICD=TRUE              // with an ICD debugger
#fuses HS,NOLVP,NOWDT,PUT     // high speed, no watch dog timer
#use delay (clock=20000000)   // 20MHz clock
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include <math.h>

// set DATA to PortA1 and SCK to portA2
#define DATA  PIN_A1
#define SCK   PIN_A2

#define noACK 0
#define ACK   1

// SHT1x address=000 is currently supported
// SHT1x command code
                            //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

// constant use for SHT1x Humidity Measurement
#define C1  -4.0
#define C2  0.0405
#define C3  -0.0000028

// constant use for SHT1x Temperature Measurement
#define D1  -40.0
#define D2  0.01

// constant use for SHT1x True Humidity Measurement
#define T1  0.01
#define T2  0.00008


// SHT1x Transmission Start Sequence
void sht1x_xmission_start()
{
   output_high(DATA);
   output_low(SCK);
   delay_us(2);
   output_high(SCK);
   delay_us(2);
   output_low(DATA);
   delay_us(2);
   output_low(SCK);
   delay_us(2);
   delay_us(2);
   delay_us(2);
   output_high(SCK);
   delay_us(2);
   output_high(DATA);
   delay_us(2);
   output_low(SCK);
   delay_us(2);
}


// SHT1x Connection Reset Sequence
void sht1x_connection_reset()
{
   int i;

   output_high(DATA);

   for (i=0; i<9; i++)
   {
      output_high(SCK);
      delay_us(2);
      output_low(SCK);
      delay_us(2);
   }
   sht1x_xmission_start();
}


// SHT1x Address & Command Mode with address=000
void sht1x_command_mode(int iMode)
{
   int i;

   for (i=128; i>0; i/=2)
   {
      if (i & iMode) output_high(DATA);
      else  output_low(DATA);

      delay_us(2);
      output_high(SCK);
      delay_us(2);
      output_low(SCK);
   }

   output_float(DATA);
   delay_us(2);
   output_high(SCK);
   delay_us(2);
   output_low(SCK);

   // delay >11ms for 8-bit measurement
   // delay >55ms for 12-bit measurement
   // delay >210ms for 14-bit measurement
   // before data read from SHT1x
   delay_ms(250);
}


// SHT1x Soft Reset
// resets the interface, clears the status register to default values
// wait minimum 11ms before next command
void sht1x_soft_reset()
{
  sht1x_connection_reset();
  sht1x_command_mode(RESET);
}


// read data from SHT1x and store
long sht1x_read_data()
{
   int i;
   long lTmp;
   long lVal1=0;
   long lVal2=0;
   long lValue;

   // get MSB from SHT1x
   for (i=0; i<8; i++)
   {
      lVal1<<=1;
      output_high(SCK);
      lTmp = input(DATA);
      delay_us(2);
      output_low(SCK);
      delay_us(2);

      if (lTmp) lVal1|=1;
   }

   // acknowledge routine
   output_high(SCK);
   output_low(DATA);
   delay_us(2);
   output_float(DATA);
   output_low(SCK);
   delay_us(2);

   // get LSB from SHT1x
   for (i=0; i<8; i++)
   {
      lVal2<<=1;
      output_high(SCK);
      lTmp = input(DATA);
      delay_us(2);
      output_low(SCK);
      delay_us(2);

      if (lTmp) lVal2|=1;
   }

   lValue = make16(lVal1,lVal2);
   return(lValue);
}


// calculate dewpoint
float sht1x_calc_dewpoint(float fRh,float fTemp)
{
   float fDewpoint;
   float fLogEW;

   fLogEW = ((7.5*fTemp)/(237.3+fTemp))+log10(fRh)-1.33923;
   fDewpoint = ((0.66077-log10(fLogEW))*(237.3))/(log10(fLogEW)-8.16077);
   return(fDewpoint);
}


// Main Program
main()
{
   float fRh_lin;
   float fRh_true;
   float fTemp_true;
   float fDew_point;

   long lValue_rh;
   long lValue_temp;


   setup_adc_ports(NO_ANALOGS);

   sht1x_connection_reset();

   while (TRUE)
   {
      // delay >11ms before next command
      delay_ms(12);

      // start transmission
      sht1x_xmission_start();

      // measure temperature
      sht1x_command_mode(MEASURE_TEMP);
      lValue_temp = sht1x_read_data();

      // temperature calculation
      fTemp_true = (D1+(D2*lValue_temp));

      // delay 11ms before next command
      delay_ms(12);

      // start transmission
      sht1x_xmission_start();

      // measure relative humidity
      sht1x_command_mode(MEASURE_HUMI);
      lValue_rh = sht1x_read_data();

      // relative humidity calculation
      fRh_lin = (C1+(C2*lValue_rh)+(C3*lValue_rh*lValue_rh));
      fRh_true = (((fTemp_true-25)*(T1+(T2*lValue_rh)))+fRh_lin);

      // dewpoint calculation
      fDew_point = sht1x_calc_dewpoint(fRh_true,fTemp_true);

      printf("\nTemperature: %3.6fC",fTemp_true);
      printf("\nRelative Humidity: %3.6f%%",fRh_true);
      printf("\nDew Point: %3.6fC",fDew_point);
      printf("\n");
      delay_ms(1000);
   }
}
[/code]
jamesjl



Joined: 22 Sep 2003
Posts: 52
Location: UK

View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger

No change in LSB
PostPosted: Sun Nov 02, 2003 5:04 am     Reply with quote

I have spent some time looking at your code and producing an implementation of it my self with no real modifications to the main code routines. It appears to work well but I am not getting any change in the LSB when I fetch the 14 bits of the temperature word or the 12 bits of the RH word.

For example
Code:

lValue_temp = 6655 = 001100111111111 = 26.6
lValue_temp = 6691 = 001101011111111 = 29.1


The above two samples are consecutive with nothing generated in between that is different.

As you can see there is no change in the values of the lsb in each case.

This gives me a resolution of 2.55 degress not the 0.01 resolution specified by the manufacturer.

I have included my entire listing but as you can see very little is different to your original. I have used a different controller and frequency (16F874 @ 4MHz) but that is all.

Any help that can be offered is greatly appreciated.

Kind regards,

Jason James.

Code:

#include <16F874.h>           // MCU specific library

#fuses XT,NOLVP,NOWDT,NOPUT, NOBROWNOUT
#use delay (clock=4000000)   // 4MHz clock
#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N)

#include <math.h>

// set DATA to PortA1 and SCK to portA2
#define DATA  PIN_A1
#define SCK   PIN_A2

#define noACK 0
#define ACK   1

// SHT1x address=000 is currently supported
// SHT1x command code
                            //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

// constant use for SHT1x Humidity Measurement
#define C1  -4.0
#define C2  0.0405
#define C3  -0.0000028

// constant use for SHT1x Temperature Measurement
#define D1  -40.0
#define D2  0.01

// constant use for SHT1x True Humidity Measurement
#define T1  0.01
#define T2  0.00008


// SHT1x Transmission Start Sequence
void sht1x_xmission_start()
{
   output_high(DATA);
   output_low(SCK);
   delay_us(2);
   output_high(SCK);
   delay_us(2);
   output_low(DATA);
   delay_us(2);
   output_low(SCK);
   delay_us(2);
   delay_us(2);
   delay_us(2);
   output_high(SCK);
   delay_us(2);
   output_high(DATA);
   delay_us(2);
   output_low(SCK);
   delay_us(2);
}


// SHT1x Connection Reset Sequence
void sht1x_connection_reset()
{
   int i;

   output_high(DATA);

   for (i=0; i<9; i++)
   {
      output_high(SCK);
      delay_us(2);
      output_low(SCK);
      delay_us(2);
   }
   sht1x_xmission_start();
}


// SHT1x Address & Command Mode with address=000
void sht1x_command_mode(int iMode)
{
   int i;

   for (i=128; i>0; i/=2)
   {
      if (i & iMode) output_high(DATA);
      else  output_low(DATA);

      delay_us(2);
      output_high(SCK);
      delay_us(2);
      output_low(SCK);
   }

   output_float(DATA);
   delay_us(2);
   output_high(SCK);
   delay_us(2);
   output_low(SCK);

   // delay >11ms for 8-bit measurement
   // delay >55ms for 12-bit measurement
   // delay >210ms for 14-bit measurement
   // before data read from SHT1x
   delay_ms(250);  //250
}


// SHT1x Soft Reset
// resets the interface, clears the status register to default values
// wait minimum 11ms before next command
void sht1x_soft_reset()
{
  sht1x_connection_reset();
  sht1x_command_mode(RESET);
}


// read data from SHT1x and store
long sht1x_read_data()
{
   int i;
   long lTmp;
   long lVal1=0;
   long lVal2=0;
   long lValue;

   // get MSB from SHT1x
   for (i=0; i<8; i++)
   {
      lVal1<<=1;
      output_high(SCK);
      lTmp = input(DATA);
      delay_us(2);
      output_low(SCK);
      delay_us(2);

      if (lTmp) lVal1|=1;
   }

   // acknowledge routine
   output_high(SCK);
   output_low(DATA);
   delay_us(2);
   output_float(DATA);
   output_low(SCK);
   delay_us(2);

   // get LSB from SHT1x
   for (i=0; i<8; i++)
   {
      lVal2<<=1;
      output_high(SCK);
      lTmp = input(DATA);
      delay_us(2);
      output_low(SCK);
      delay_us(2);

      if (lTmp) lVal2|=1;
   }

   lValue = make16(lVal1,lVal2);
   return(lValue);
}


// calculate dewpoint
float sht1x_calc_dewpoint(float fRh,float fTemp)
{
   float fDewpoint;
   float fLogEW;

   fLogEW = ((7.5*fTemp)/(237.3+fTemp))+log10(fRh)-1.33923;
   fDewpoint = ((0.66077-log10(fLogEW))*(237.3))/(log10(fLogEW)-8.16077);
   return(fDewpoint);
}


// Main Program
void main(void)
{
   float fRh_lin;
   float fRh_true;
   float fTemp_true;
   float fDew_point;
   int8 counter;
   
   long lValue_rh;
   long lValue_temp;

   delay_ms(2000);
   
   setup_adc_ports(NO_ANALOGS);

   sht1x_connection_reset();

   while (TRUE)
   {
//      sht1x_connection_reset();
      // delay >11ms before next command
      delay_ms(12);

      // start transmission
      sht1x_xmission_start();

      // measure temperature
      sht1x_command_mode(MEASURE_TEMP);
      lValue_temp = sht1x_read_data();

      // temperature calculation
      fTemp_true = (D1+(D2*lValue_temp));
      
      // delay 11ms before next command
      delay_ms(12);  //12

      // start transmission
      sht1x_xmission_start();

      // measure relative humidity
      sht1x_command_mode(MEASURE_HUMI);
      lValue_rh = sht1x_read_data();

   //-------------------------------------------------------
   // Format of transmitted string for processing by PC
   // !!lValue_temp,lValue_rh??
   //-------------------------------------------------------
   printf ("!!%lu,%lu??",lValue_temp, lValue_rh);
   //-------------------------------------------------------

      // relative humidity calculation
      fRh_lin = (C1+(C2*lValue_rh)+(C3*lValue_rh*lValue_rh));
      fRh_true = (((fTemp_true-25)*(T1+(T2*lValue_rh)))+fRh_lin);

      // dewpoint calculation
      fDew_point = sht1x_calc_dewpoint(fRh_true,fTemp_true);

   // Five seconds between successive samples.
   delay_ms(5000);

   }
}
Viltor
Guest







The routine acknowledge is erroneous
PostPosted: Mon Dec 08, 2003 1:15 pm     Reply with quote

This is the good


// acknowledge routine
output_low(DATA);
output_high(SCK);
delay_us(2);
output_low(SCK);
output_float(DATA);
delay_us(2);


Regards
Viltor
http://webs.ono.com/viltor
dazlogan



Joined: 19 Oct 2003
Posts: 24
Location: Cambridge, UK

View user's profile Send private message Send e-mail

Precision
PostPosted: Mon Dec 08, 2003 1:25 pm     Reply with quote

Just for your information:

If you a looking for precision humidity measurement, then visit www.michell-instruments.com.

They are leaders in the field.

Unfortunately though, they don't supply sensors on their own, only fully fledged transmitters and precision dew point meters.

Regards,
Darren
picprogrammer



Joined: 10 Sep 2003
Posts: 35

View user's profile Send private message

PostPosted: Tue Nov 23, 2004 4:28 pm     Reply with quote

Same like i posted in another thread:

// acknowledge routine
output_low(DATA);
delay_us(2);
output_high(SCK);
delay_us(2);
output_low(SCK);
output_float(DATA);
delay_us(2);

It runs ok on a 18F452 16mhz
phaychee



Joined: 04 Jan 2007
Posts: 6

View user's profile Send private message

PostPosted: Thu Jan 11, 2007 5:41 am     Reply with quote

hi there

I had tried on the SHT11 code as above.

And for the result, sometimes it can display the reading of humidity and temperature correctly.

But after a few seconds it will display the fault humidity value , such as 2933.14% something like that.


May I know what happen to my SHT11?
Piccolo



Joined: 19 May 2006
Posts: 23
Location: Connecticut

View user's profile Send private message

PostPosted: Thu Jan 11, 2007 7:54 am     Reply with quote

Take a look at HIH-4000 relative humidity sensor from Honeywell.
It has a linear output and good accuracy
mfer



Joined: 11 Jan 2007
Posts: 8

View user's profile Send private message

PostPosted: Thu Jan 11, 2007 8:19 am     Reply with quote

Hello.

I used HIH-4000 with Microchip MCP3221, which gives I2C output. Works fine. Note, that HIH-4000 has rather fast response. (o.k., compared to what, but for me it was fast enough)

Regards,
mfe
asmallri



Joined: 12 Aug 2004
Posts: 1630
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Jan 11, 2007 8:35 am     Reply with quote

phaychee wrote:
hi there

I had tried on the SHT11 code as above.

And for the result, sometimes it can display the reading of humidity and temperature correctly.

But after a few seconds it will display the fault humidity value , such as 2933.14% something like that.


May I know what happen to my SHT11?


I use the SHT7x sensors which are higher precision versions of the SHT1x sensors. I use these sensors in precision environmental monitoring systems which operate in harsh conditions and they have proven very reliable, stable, and repeatable. I use my own CCS drivers and sample application including CRC validation.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!


Last edited by asmallri on Fri Jan 12, 2007 1:44 am; edited 1 time in total
phaychee



Joined: 04 Jan 2007
Posts: 6

View user's profile Send private message

PostPosted: Thu Jan 11, 2007 8:48 pm     Reply with quote

asmallri,

hi, although we r not using the same humidity sensor from sensiron, but can u post up ur sht 7X driver for reference?


Btw, u also don't know what is my sensor problem right?
Thanks anywhere.





Piccolo and mfer,

I had considered sensor from Honeywell before, but it is too expensive if compare to SHT11 Sad
asmallri



Joined: 12 Aug 2004
Posts: 1630
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Jan 12, 2007 1:53 am     Reply with quote

phaychee wrote:
asmallri,

hi, although we r not using the same humidity sensor from sensiron, but can u post up ur sht 7X driver for reference?


These sensor use the same low level driver. I cannot post the driver - it is a commercial product and I sell the driver source code.

[quote]
Btw, u also don't know what is my sensor problem right? [/qoute]

No I do not know your problem. It is possible, but unlikley, that you have a faulty sensor. Either you have a software problem or more likely you have a corrupted data stream.

The corrupted data stream will give you weird results which is why you should use CRC to validate the message from the sensor to the PIC.

A common mistake with first time users of these sensors is to forget to use pull up resistors on the clock and data lines to the sensor or, if using the SMD part, forgetting the 0.1uF capacitor which must be mounted as close as possible to the sensor PCB.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Fri Jan 12, 2007 12:18 pm     Reply with quote

The SHTXX series sensors are not completely I2C compliant. The SHT15 is a more precise version of the SHT11. The SHT7X is the same but only in a different packaging.

The SHTXX sensors are not I2C compliant because the Start signal requires both a Start and Stop signal to tell the sensor that you want to talk to it. The address command then tells it what you want to do (write to a register or read a value out of it). I've used this sensor a lot and I have to bit-bang the signals to it. They are quite reliable and I've not had one go bad that was placed into a production environment. The sensor has a register that contains the calibration values for it. The spec. sheet contains the formulas that will ensure the linearity is correct. It also contains a bit that will tell you when the End-of-Life has been reached. You should poll this register once in a while to make sure that the calibration is within spec.

Ronald
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group