I see implementing this sensor is tricky for more people than me, so I wanted to post the program I have to use the sensor from a raspberry pi; I'm sure it will be useful for someone:
#include <sys/ioctl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <linux/i2c-dev.h.kernel>
#include <linux/i2c.h>
static int fd;
unsigned short i2c_read(unsigned char addr,
unsigned char reg,
int delay)
{
static struct i2c_msg msgs[1];
int r;
struct i2c_rdwr_ioctl_data msgset =
{
msgs, sizeof(msgs) / sizeof(*msgs)
};
unsigned char buf[4];
buf[0] = reg;
msgs[0].addr = addr;
msgs[0].flags = 0;
msgs[0].buf = (void *)buf;
msgs[0].len = 1;
r = ioctl(fd, I2C_RDWR, &msgset);
if (r<0) return 0xffff;
if (delay) usleep(delay);
msgs[0].addr = addr;
msgs[0].flags = I2C_M_RD;
msgs[0].buf = (void *)buf;
msgs[0].len = 2;
r = ioctl(fd, I2C_RDWR, &msgset);
if (r<0) return 0xffff;
return buf[0]*256 + buf[1];
}
int main(int argc, char *argv[])
{
fd=open("/dev/i2c-1", O_RDWR);
unsigned short temp = i2c_read(0x40,0,20000);
unsigned short hum = i2c_read(0x40,1,20000);
if (temp!=0xffff)
printf("temperature: %.3f C\n", temp * (160.0/65536.0) - 40);
if (hum!=0xffff)
printf("humidity: %.3f %%RH\n",hum * (100.0/65536.0));
return 0;
}
It does not check the i2c line to see if the sensor is ready, but instead just waits 20ms (the 20000 number) and then read the data.
(License: Use in any way you want - just don't blame me for anything).