I2C Humidity Monitoring on the Raspberry Pi

First published: 17th July 2013

So, as discussed in my introduction to humidity monitoring on the RPi, I had chosen to connect a HIH-6120-021-001 to the RPi's I2 bus.

Hardware

Honeywell's datasheet shows how simple it is, just the chip, a 0.22µF capacitor and a couple of pullup resistors. However, the RPi already has 1.8KΩ pullups on the I2C bus. Construction was just a matter of adding two components to the matrix board with a 26-pin header socket already used for my 1-wire interface.

The limitation of the I2C bus is that it was designed for short distances - for example, on a motherboard. This discussion points out that the maximum cable capacitance is limited to 500pf and a cat5 cable has the capacitance of 17pf/feet, so 29 feet is the maximum network length. I chose to just put the sensor on the matrix board, and therefore inside the RPi case.

Software

Adafruit has some simple instructions for configuring the I2C bus. The kernel modules to support the bus must be added to /etc/modules:

i2c-bcm2708 
i2c-dev

Also, the I2C utilities are not installed by default:

sudo apt-get install python-smbus
sudo apt-get install i2c-tools
(Change to -y 1 for newer raspberry pi) "the maximum number of I2C devices used at any one time is 112"

Once the kernel modules are loaded, the buses can be seen:

ls -l /dev/i2c*
crw------- 1 root root 89, 0 Jul 10 20:10 /dev/i2c-0
crw------- 1 root root 89, 1 Jul 10 20:10 /dev/i2c-1

The devices present can be listed, I have an old RPi, for newer models, replace the 'o' with '1':

i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --        

A Honeywell technical note describes communications with the HIH-6120-021-001, and that says the default sensor address is 0x27, so i2cdetect has found the sensor. The note also describes how to read data from the device, and calculate the temperature and humidity from it.

Being lazy, I don't want to reinvent the wheel and write my own low-level routines to access the device drivers. Fortunately, there is a Perl module to access the kernel driver for the I2C bus. Installing it is easy, the --hipi-wx=0 switch tells it not to install the GUI, I wasn't planning on attaching a monitor to this RPi.

wget http://raspberry.znix.com/hipifiles/hipi-install
perl hipi-install --hipi-wx=0

This little Perl script reads and prints the temperature and relative humidity from the device:

#!/usr/bin/perl

use HiPi::Device::I2C;

my $devaddress= 0x27;
my $dev = HiPi::Device::I2C->new( address => $devaddress );
# Write nothing to the device... (initiates measurement)
$dev->i2c_write_error();

my @data= $dev->i2c_read( 4);
printf "%x %x %x %x\n", @data;
my $status= ($data[0] & 0xc0) >> 6;
my $humid= (($data[0] & 0x3f) * 256 + $data[1]) / 0x3fff * 100;
my $temp= (($data[2] *256 + $data[3]) >> 2) / 0x3fff * 165 - 40;

print "Status $status\tHumidity $humid %RH\tTemperature $temp celsius\n";

exit;

With this result:

./humidtest.pl
54 49 6c 7d
Status 1        Humidity 31.6974913019593 %RH   Temperature 29.9258377586523 celsius

When using this, I found the temperature was generally higher than expected, and the humidity was lower. This is a consequence of putting the sensor inside the RPi case, where it is warm. The readings are correct for conditions inside the case, but, if you are trying to monitor the general environment the sensor must be moved away from heat sources like the RPi.

I conclude that, along with the limited network length, there are two more disadvantages to using this sensor for a humidity monitoring network. First, the default sensor address is fixed at 0x27, the Honeywell technical note says to ask their Customer Service about custom addresses, so I don't think they will be easy to get hold of in small quantities. This limits the number of sensors to one per I2C network. Second, I2C devices do not have unique identifiers. This does not matter on a motherboard, where you know all the devices and their addresses when the board is manufactured and they will never change, but it makes building a variable network of sensors more difficult. In comparison, every 1-Wire device has a family code, defining the type of device, and a 48 bit serial number. The master on a 1-Wire network can discover what types of device are attached, and whether it has seen those particular devices before.


Gallery

I<sup>2</sup>C network schematicI2C network schematic
Share