Luftfeuchtesensor HTS221

Gepostet von am 21. Februar 2018, 08:03

Die Luftfeuchte hat unter anderem großen Einfluss auf unser Wohlbefinden. Es werden aber auch viele physikalische und chemische Prozesse von ihr beeinflusst. Somit ist es durchaus interessant, sie zu messen.

HTS221 von ST

Mit dem HTS221 von ST ist das möglich. Er kann im Bereich von 0 bis 100% relative Luftfeuchte messen und bietet im Bereich von 20 bis 80% eine Genauigkeit von 3,5%. Zusätzlich ist im gleichen Gehäuse noch ein Temperatursensor verbaut.

Der Sensor kann über I2C oder SPI angesteuert und ausgelesen werden. Wir beschränken uns hier auf die Ansteuerung über I2C.

Der elektrische Anschluss ist sehr einfach. Er benötigt nur einen zusätzlichen 100 nF Filterkondensator.

Auslesen über I2C

Der HTS221 hat die I2C-Adresse 0×5f. Bevor der Sensor Werte liefert, muss man ihn aktivieren und zum Beispiel in einen continous mode mit einer Update-Rate von 1 Hz setzen. Dies geschieht, indem man den Wert 0×81 in das Registe 0×20 schreibt.

Der Sensor liefert die Luftfeuchte und die Temperatur als Messwerte leider nicht direkt, sondern sie müssen erst berechnet werden. Dies geschieht über eine lineare Annäherung. Dazu sind im Sensor zwei Punkte der Geraden als Referenzwerte gespeichert. Beim Luftfeuchtesensore sind das (H0_T0_OUT/H0_rH_x2) und (H1_T0_OUT/H1_rH_x2). Aus dem Sensor liest man den Wert HUMIDITY_OUT aus. Mit folgender Formel kann man daraus die Luftfeuchte berechnen:

mh=((float)(h1_rh_x2-h0_rh_x2)/2.0)/(float)(h1_t0_out-h0_t0_out);
th=(float)(h0_rh_x2)/2.0-(float)h0_t0_out*mh;
humidity=(float)humidity_out*mh+th;

HUMIDITY_OUT muss bei jeder Messung ausgelesen werden, die Referenzwerte bleiben immer gleichen und müssen deshalb nicht jedes Mal ausgelesen werden.

Beim Temperatursensor verhält es sich analog.

Programm zum Auslesen des Sensors

Hier ist ein Programm, mit dem man den Sensor auf einem Raspberry Pi oder BeagleBone auslesen kann.

#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
	int file;
	int addr=0x5f;		// adress of HTS221
	char a=0;

	signed short int temp_out=0,humidity_out=0; // output registers
	unsigned char h0_rh_x2=0,h1_rh_x2=0;	// calibration registers
	unsigned short t0_degC_x8=0,t1_degC_x8=0;
	signed short h0_t0_out=0,h1_t0_out=0,t0_out=0,t1_out=0;

	float mt,tt,temp;	// calculated values for temperature
	float mh,th,humidity;	// calculated values for humidty

	printf("HTS221\n");
	if((file=open("/dev/i2c-1",O_RDWR))<0)	// open i2c-bus
	{
		perror("cannot open i2c-1");
		exit(1);
	}
	if(ioctl(file, I2C_SLAVE, addr)<0)	// open slave
	{
		perror("cannot open slave address");
		exit(1);
	}

	a=i2c_smbus_read_byte_data(file,0x0f);	// read WHO_AM_I
	printf("WHO_AM_I:     %02X\n",a);
	a=i2c_smbus_read_byte_data(file,0x20);	// read CTRL_REG1
	printf("CTRL_REG1:    %02X\n",a);
	if(a!=0x81)	// check if device active
	{
		printf("setting device to active and continous mode\n");
		i2c_smbus_write_byte_data(file,0x20,0x81);	// setting device to active and continous mode
		a=i2c_smbus_read_byte_data(file,0x20);	// read CTRL_REG1
		printf("CTRL_REG1:    %02X\n",a);
	}
	a=i2c_smbus_read_byte_data(file,0x27);	// read STATUS_REG
	printf("STATUS_REG:   %02X\n",a);

	h0_t0_out=i2c_smbus_read_word_data(file, 0xb6);	// read H0_T0_OUT
	printf("H0_T0_OUT:    0x%04X = %i\n",(unsigned short)h0_t0_out,h0_t0_out);
	h1_t0_out=i2c_smbus_read_word_data(file, 0xba);	// read H1_TO_OUT
	printf("H1_T0_OUT:    0x%04X = %i\n",(unsigned short)h1_t0_out,h1_t0_out);
	t0_out=i2c_smbus_read_word_data(file, 0xbc);	// read T0_OUT
	printf("T0_OUT:       0x%04X = %i\n",(unsigned short)t0_out,t0_out);
	t1_out=i2c_smbus_read_word_data(file, 0xbe);	// read T1_OUT
	printf("T1_OUT:       0x%04X = %i\n",(unsigned short)t1_out,t1_out);
	t0_degC_x8=i2c_smbus_read_byte_data(file, 0x32);	// read T0_degC_x8
	t0_degC_x8+=((i2c_smbus_read_byte_data(file, 0x35)&0x03)<<8);
	printf("T0_degC_x8:   0x%04X = %i\n",(unsigned short)t0_degC_x8,t0_degC_x8);
	t1_degC_x8=i2c_smbus_read_byte_data(file, 0x33);	// read T1_degC_x8
	t1_degC_x8+=((i2c_smbus_read_byte_data(file, 0x35)&0x0c)<<6);
	printf("T1_degC_x8:   0x%04X = %i\n",(unsigned short)t1_degC_x8,t1_degC_x8);
	h0_rh_x2=i2c_smbus_read_byte_data(file, 0x30);	// read H0_rh_x2
	printf("H0_rH_x2:     0x%04X = %i\n",(unsigned short)h0_rh_x2,h0_rh_x2);
	h1_rh_x2=i2c_smbus_read_byte_data(file, 0x31);	// read H1_rH_x2
	printf("H1_rH_x2:     0x%04X = %i\n",(unsigned short)h1_rh_x2,h1_rh_x2);

	humidity_out=i2c_smbus_read_word_data(file, 0xa8);	//read HUMIDITY_OUT
	printf("HUMIDITY_OUT: 0x%04X = %i\n",(unsigned short)humidity_out,humidity_out);
	temp_out=i2c_smbus_read_word_data(file, 0xaa);	// read TEMP_OUT
	printf("TEMP_OUT:     0x%04X = %i\n",(unsigned short)temp_out,temp_out);

	// temperature and humidity calculations
	printf("\n");
	mt=((float)(t1_degC_x8-t0_degC_x8)/8.0)/(float)(t1_out-t0_out);
	tt=(float)(t0_degC_x8)/8.0-(float)t0_out*mt;
	temp=(float)temp_out*mt+tt;
	printf("mt=%f - tt=%f - temp=%f\n",mt,tt,temp);

	mh=((float)(h1_rh_x2-h0_rh_x2)/2.0)/(float)(h1_t0_out-h0_t0_out);
	th=(float)(h0_rh_x2)/2.0-(float)h0_t0_out*mh;
	humidity=(float)humidity_out*mh+th;
	printf("mh=%f - th=%f - humidity=%f\n",mh,th,humidity);

	close(file);

	return 0;
}

Bei mir wurden dann folgende Werte ausgelesen:

Ausgabe vom HTS221

Verfügbarkeit und Evalboards.

Der HTS221 ist auf dem Sense HAT von Raspberry Pi verbaut. Somit kann man seinen Raspberry Pi auf einfache Art und Weise um einen Luftfeuchtesensor ergänzen. Außerdem ist der Sensor auf dem Motion MEMS and environmental sensor expansion board for STM32 Nucleo von ST verbaut. Von dem Board gibt es zwei Versionen, X-NUCLEO-IKS01A1 und X-NUCLEO-IKS01A2, der HTS221 ist aber auf beiden Versionen verbaut.

Probleme

Beim Sense HAT wird der HTS221 vom Nahe darunter liegenden Prozessor erwärmt, zumindest wenn man einen Raspberry Pi 3 in normaler Konfiguration verwendet. Beim Raspberry Pi Zero und mit niedrigerer Frequenz wird der Effekt wahrscheinlich nicht so groß sein. Daher zeigen die Temperaturwerte einen etwa 5 Grad zu hohen Wert an. Da die relative Luftfeuchte auch von der Temperatur abhängt, weißt auch sie einen zu niedrigen Wert auf.

Außerdem ist ein HTS221 bei mir schon immer defekt. Er liefert seine Werte ganz normal, aber der Wert für die Luftfeuchte ist etwa 25 % rH zu hoch. Bisher konnte ich noch nicht feststellen, woran das liegt, also gehe ich davon aus, dass der Sensor einfach kaputt ist. Der Temperatursensor funktioniert aber ganz normal. Wenn jemand das gleiche Problem hat, würde ich mich über einen Kommentar freuen.


Kategorien ,

Stichworte HTS221,Luftfeuchte,Temperatur,Raspberry Pi,Sense HAT,I2C,MEMS,Sensor


Kommentare

Kommentarfunktion für diesen Artikel geschlossen.