Sensing Humidity With The SHT15 + Arduino

Tuesday, November 27 th , 2012

The SHT15 is a digital humidity sensor that outputs a fully calibrated humidity reading. And… because what we are measuring is actually relative humidity, and relative humidity being relative to temperature, the SHT15 has a builtin digital thermometer. This makes things much easier to work with than sensors without a thermometer onboard. You can pick one up from sparkFun here.

Hooking it up

The SHT15 uses a two-wire connection for communication that is similar to, but not, I2C. So we wont be able to use the Arduino’s dedicated lines for this. The down side is it is a bit slower to get readings from, the plus side is that you can connect it to any 2 digital pins you want. We are using pins 2 and 3 on our arduino.

BEFORE YOU SOLDER IT UP… Note that this board can not be washed! So if you are using flux, or solder that you normally clean up, don’t (They actually recommend to use “no-clean” solder just so you don’t have to worry about it). And be extremely careful not to get it wet at all.

AFTER YOU SOLDER IT UP… To get a clean reading, the sensor needs to be stored at >75% humidity for at least 12 hours to allow the polymer to re-hydrate (just what the doc says). If you don’t, your SHT15 may read an offset that slowly disappears if exposed to ambient conditions. Alternatively the re-hydration process may be performed at ambient conditions (>40% Humidity) for 5 + days.

Im not exactly sure how you do that… But someone noted that they put it in a ziplock with a wet towel (not touching) for 12H.

Code

The code for this is a bit wacky (as with most digital sensors), but it is split up pretty nicely, and is as easy to read as it can be.

Note that the readings are a bit slow to return a value (100+ ms).


//Based of the wiring code at http://wiring.org.co/learning/basics/humiditytemperaturesht15.html

int SHT_clockPin = 3; // pin used for clock
int SHT_dataPin = 2; // pin used for data

void setup(){
Serial.begin(9600); // open serial at 9600 bps
}

void loop(){
//these can take a bit to get the values (100ms or so)
float temperature = getTemperature();
float humidity = getHumidity();

Serial.print(temperature);
Serial.print(" | ");
Serial.println(humidity);

}

float getTemperature(){
//Return Temperature in Celsius
SHT_sendCommand(B00000011, SHT_dataPin, SHT_clockPin);
SHT_waitForResult(SHT_dataPin);

int val = SHT_getData(SHT_dataPin, SHT_clockPin);
SHT_skipCrc(SHT_dataPin, SHT_clockPin);
return (float)val * 0.01 - 40; //convert to celsius
}

float getHumidity(){
//Return Relative Humidity
SHT_sendCommand(B00000101, SHT_dataPin, SHT_clockPin);
SHT_waitForResult(SHT_dataPin);
int val = SHT_getData(SHT_dataPin, SHT_clockPin);
SHT_skipCrc(SHT_dataPin, SHT_clockPin);
return -4.0 + 0.0405 * val + -0.0000028 * val * val;
}

void SHT_sendCommand(int command, int dataPin, int clockPin){
// send a command to the SHTx sensor
// transmission start
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
digitalWrite(clockPin, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, LOW);

// shift out the command (the 3 MSB are address and must be 000, the last 5 bits are the command)
shiftOut(dataPin, clockPin, MSBFIRST, command);

// verify we get the right ACK
digitalWrite(clockPin, HIGH);
pinMode(dataPin, INPUT);

if (digitalRead(dataPin)) Serial.println("ACK error 0");
digitalWrite(clockPin, LOW);
if (!digitalRead(dataPin)) Serial.println("ACK error 1");
}

void SHT_waitForResult(int dataPin){
// wait for the SHTx answer
pinMode(dataPin, INPUT);

int ack; //acknowledgement

//need to wait up to 2 seconds for the value
for (int i = 0; i < 1000; ++i){ delay(2); ack = digitalRead(dataPin); if (ack == LOW) break; } if (ack == HIGH) Serial.println("ACK error 2"); } int SHT_getData(int dataPin, int clockPin){ // get data from the SHTx sensor // get the MSB (most significant bits) pinMode(dataPin, INPUT); pinMode(clockPin, OUTPUT); byte MSB = shiftIn(dataPin, clockPin, MSBFIRST); // send the required ACK pinMode(dataPin, OUTPUT); digitalWrite(dataPin, HIGH); digitalWrite(dataPin, LOW); digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW); // get the LSB (less significant bits) pinMode(dataPin, INPUT); byte LSB = shiftIn(dataPin, clockPin, MSBFIRST); return ((MSB << 8) | LSB); //combine bits } void SHT_skipCrc(int dataPin, int clockPin){ // skip CRC data from the SHTx sensor pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); digitalWrite(dataPin, HIGH); digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW); }

Sensing Humidity With The HIH-4030 + Arduino

Sunday, November 25 th , 2012

Humidity is weird. Even though we experience it all the time, it’s not something we can normally guess with any accuracy. This is probably because when we talk about humidity, we are talking about relative humidity. Relative humidity is relative to temperature, so a change in temperature alone is enough to change the relative humidity. This makes guessing the humidity extremely hard.

Well luckily measuring relative humidity is pretty simple with the HIH-4030. The HIH-4030 is a low-power, analog output sensor.

Hooking It Up

Hooking up the HIH-4030 to your arduino is super simple, just power it with 5V / Ground, and connect the out to an analog pin on the arduino. You may be able to run it with 3.3v, I haven’t tried it. But if you do, you need to change the “supplyVolt” value in the code from 5.0 to 3.3.

Code

Note that because determining relative humidity requires knowing an accurate temperature, you are going to want to use this in conjunction with a thermometer. To simplify things for you, the code just has a hard coded temperature that we pass to a function to get the humidity. You will want to replace that value with the value from your thermometer.

Also note that the sensor is sensitive to light, so for best performance, shield it from bright light.

Suggested Thermometers (with article):
TMP102
DS18B20


//From the bildr article https://bildr.org/2012/11/hih4030-arduino/

int HIH4030_Pin = A0; //analog pin 0

void setup(){
Serial.begin(9600);
}

void loop(){

//To properly caculate relative humidity, we need the temperature.
float temperature = 25; //replace with a thermometer reading if you have it
float relativeHumidity = getHumidity(temperature);

Serial.println(relativeHumidity);

delay(100); //just here to slow it down so you can read it
}

float getHumidity(float degreesCelsius){
//caculate relative humidity
float supplyVolt = 5.0;

// read the value from the sensor:
int HIH4030_Value = analogRead(HIH4030_Pin);
float voltage = HIH4030_Value/1023. * supplyVolt; // convert to voltage value

// convert the voltage to a relative humidity
// - the equation is derived from the HIH-4030/31 datasheet
// - it is not calibrated to your individual sensor
// Table 2 of the sheet shows the may deviate from this line
float sensorRH = 161.0 * voltage / supplyVolt - 25.8;
float trueRH = sensorRH / (1.0546 - 0.0026 * degreesCelsius); //temperature adjustment

return trueRH;
}