HYT 221 from Hygrosens Instruments

Hy

zhx for the example. However why do we need the delay of 100ms since when
I do remove this the sensor does still work???
I know it is written in the manual but I see no difference.

Thx
Andy

If you go to ub8优游登录入口-ub8优游登录入口手机版下载 - 优游国际官网 and click on documentation you'll find an original Arduino example - this only has a delay at the end of loop() to prevent it printing too fast to read... Can safely ignore delays AFAICT.

I saw this code but it is not working, it is printing always the same values messured at the first time.
So the Code from above does work better.

Andy

Ciao,

here You find a library for HYT221 (derived from a library for HYT331).
The library is not well optimized, since it is blocking MCU using delay.
Delay is used to wait for measurement to take effect, otherwise You will read the previous measured value.

It works for me.

HYT221.h

#ifndef _HYT221_H
#define _HYT221_H

#define HYT_DEBUG 0

class HYT221 {

    private:
        int address;
        int rawTemp;
        int rawHum;
        
    public:
        HYT221(int I2Cadr);
        uint8_t begin( void );
        uint8_t read( void );

        int getRawHumidity( void );
        int getRawTemperature( void ) ;
        double getHumidity( void ) ;
        double getTemperature( void );
    
};

extern HYT221 HYT;


#endif

HYT221.cpp

#if ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

#include <Wire.h>
#include "HYT221.h"

#define HYT221_ADDR 0x28
// #define SCALE_MAX 0b100000000000000
#define SCALE_MAX 16384.0
#define TEMP_OFFSET  40.0
#define TEMP_SCALE 165.0
#define HUM_SCALE 100.0

//
// HYT221 
//
// !!! Blocking code
//

HYT221::HYT221(int I2Cadr){
    address = I2Cadr;
}

uint8_t HYT221::begin(void) {
    return 1;
}

uint8_t HYT221::read( void ) {
    Wire.beginTransmission(address);
    Wire.write((byte)0x00);
    Wire.available();
    int Ack = Wire.read(); // receive a byte
    
    // DEBUG
    #if HYT_DEBUG
        Serial.print("ACK: ");
        Serial.println(Ack);
    #endif
    
    Wire.endTransmission();
    
    // DEBUG ////////////////
    //request 4 bytes
    #if HYT_DEBUG
        Wire.requestFrom(address, 4);

        Wire.available();

        int a1 = Wire.read(); // receive a byte
        int a2 = Wire.read(); // receive a byte
        int a3 = Wire.read(); // receive a byte
        int a4 = Wire.read(); // receive a byte
    #endif
    ////////////////////////////////
    
    // delay inteval !!! blocking MCU
    delay(100);

    //request 4 bytes
    Wire.requestFrom(address, 4);

    Wire.available();

    int b1 = Wire.read(); // receive a byte
    int b2 = Wire.read(); // receive a byte
    int b3 = Wire.read(); // receive a byte
    int b4 = Wire.read(); // receive a byte
    
    // DEBUG
    #if HYT_DEBUG
        Serial.print("a1: ");
        Serial.println(a1, BIN);
        Serial.print("b1: ");
        Serial.println(b1, BIN);
        Serial.print("a2: ");
        Serial.println(a2, BIN);
        Serial.print("b2: ");
        Serial.println(b2, BIN);
        Serial.print("a3: ");
        Serial.println(a3, BIN);
        Serial.print("b3: ");
        Serial.println(b3, BIN);
        Serial.print("a4: ");
        Serial.println(a4, BIN);
        Serial.print("b4: ");
        Serial.println(b4, BIN);
    #endif
    

    // combine the bits
    rawHum = ( b1 << 8 | b2 ) & 0x3FFF;

    // Mask away 2 last bits see HYT 221 doc
    rawTemp = b3 << 6 | ( unsigned(b4) >> 2 ) ;
    
    return 1;
}

int HYT221::getRawHumidity( void ) {
    return rawHum;
}

int HYT221::getRawTemperature( void ) {
    return rawTemp;
}

double HYT221::getHumidity( void ) {
    //hum = 100.0 / pow( 2, 14 ) * rawHum;
    return (HUM_SCALE * rawHum) / SCALE_MAX;
}

double HYT221::getTemperature( void ) {
    return ( (TEMP_SCALE * rawTemp) / SCALE_MAX ) - TEMP_OFFSET;
}

keywords.txt

#######################################
# Syntax Coloring Map For HYT221
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

HYT221             KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin            KEYWORD2
read            KEYWORD2
getRawHumidity        KEYWORD2
getRawTemperature    KEYWORD2
getHumidity        KEYWORD2
getTemperature        KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

Example

/*
 Programm to measure and transmit Humidity and Temperature 
 HYT-221 via Serial Communication.
 
 Not optimized for high speed measurement. A minimum delay 
 of 100 ms is currently hard coded in the getData() function
 
 TODO:
 - Add functionalty for high speed measurement. The HYT221
 indicates if a new measurement is ready via the status/stall bit
 see documentation of HYT221
 - Do not use a global variable for temperature and humidty. Use
 a function with an array to return the data.
 - Think on reducing number of variables used.
 
 */

#include <Wire.h>
#include <HYT221.h>

HYT221 HTsens01 = HYT221(0x28);

void setup() {
  
   Serial.begin(57600);
   
   // initialize I2C protocoll
   Wire.begin();

   // initialize the sensor
   HTsens01.begin();
}

void loop() {

   HTsens01.read();
   double h = HTsens01.getHumidity();
   double t = HTsens01.getTemperature();
   int hraw =  HTsens01.getRawHumidity() ;
   int traw =  HTsens01.getRawTemperature() ;
   Serial.print(t);
   Serial.print(" C, ");
   Serial.print(traw);
   Serial.print(" , ");
   Serial.print(h);
   Serial.print(" %, ");
   Serial.println(hraw);

   delay(30000);

}

Beware that making readings at high frequency will self heat the sensor too much, giving wrong higher temperature values.

This part of code is major difference from the code posted before in this post.

rawTemp = b3 << 6 | ( unsigned(b4) >> 2 ) ;

There is a variable defined in the header file to print the pre measurement and post measurement byte values.

Ciao,
Marco.

thx but hmm for which version of the Arduino is this since for my Arduino IDE 0022 it doesn't work...

HYT221.cpp: In member function 'uint8_t HYT221::read()':
HYT221.cpp:33: error: 'class TwoWire' has no member named 'write'

andy

ok found the problem. It does work with Arduino v1.
In 0022 you have to cahnge wire.read to wire.receive and wire.write to wire.send and then it does work :slight_smile:

However I got another question.
Does someone know how to change the Adress of one sensor?

Thx
Andy

GekoCH:
thx but hmm for which version of the Arduino is this since for my Arduino IDE 0022 it doesn't work...

HYT221.cpp: In member function 'uint8_t HYT221::read()':
HYT221.cpp:33: error: 'class TwoWire' has no member named 'write'

andy

hi i want to know your expiriens with this sensor.... i just bought an SHT/! and can no get it work so maybe you could give me a recommendation for a sensor for temperature and humidity messure........ i´ve treid to seach this HYT 221 on ebay and mouser and can´t find it

just take any HYT they 221 is an old one so use the 271.
I'm currently using this one too.

do you know where to buy it???

pls google since I don't know where you're from in europe you get it from every electronic store...

ok i will try to search im not in Europe, but in my country can not buy one so i will searh on USA... thx

Ciao,

I have both Sensirion and IST (Hygrosens) sensors.

IST one has better accuracy and is I2C (easier to use), Sensirion has better control over data sent (CRC).

Since the products are in IST AG portfolio these sensors are easier to find (IST is the Swiss company that produce thin film sensors).
Thery also produce great digital temperature sensors with better accuracy than Dallas 18B20.

In USA You can find IST prodcuts at www.servoflo.com .

In Europe from

Schukat.com

Beware that prices variation in very high.

http://www.conrad.com/DIGITAL-HUMIDITY-SENSOR-HYT-221.htm?websale7=conrad-int&pi=505671&ci=SHOP_AREA_14741_0231310

I had my I2C address changed directly by the manufacturer last year (I purchased 3 for a project), anyway I have been said that there is a procedure to change it.
Maybe You can contact IST.

Ciao,
Marco.

I got a document where it is described how to change the address however I can't managed it to get
work....
Maybee you can help me since you are somehow familiar with the I2C interface and the HYR Sensors.

here is the link:
www.ibrutech.ch/Change_Address.pdf

Andy

do you have a code and also a sckematic of hoe did you get STH to work??? this could be my last test beforore buy another, if with this donesnt work well i have to change the sensor cuase probably its bad

Ciao,

@ GekoCH
I will, if I have time, make a test later.

@ copachino
for Sensirion sensors You can take a look at this to articles

and use this library

Remeber to put the rigth pullup resistors and remeber that are not I2C, so don't use I2C pins or, if you use it, disable I2C.

Ciao,
Marco.

thanks i tried it but no luck for me so i will have to buy a new one like HYT 271

i tested the code from Marco Benini for a HYT271 and i get strange data...
for his shown example i get -40.01 C and 99.99 % (raw data: -1 and 16383)
if i switch to debug mode, i get following:

ACK: -1
a1: 11111111111111111111111111111111
b1: 11111111111111111111111111111111
a2: 11111111111111111111111111111111
b2: 11111111111111111111111111111111
a3: 11111111111111111111111111111111
b3: 11111111111111111111111111111111
a4: 11111111111111111111111111111111
b4: 11111111111111111111111111111111

i am sure i did all the wiring correct and the sensor ist new.
because i am really new in arduino programming i don't know if i just did something wrong or if the sensor is defect.

thanks in advance

edit:
apparently my wiring was not that perfect :smiley:
after checking every connection i found a broken cable connection and replaced it.
now everything works as a charm.

thx Marco for your code!

oh, quick question: is there a posibility to display only one decimal digit instead of two after the decimal point? ( 22.9 instead of 22.88) or even better if it is possible to round to .5 (22.5 instead of 22.37)

Ciao,

You can use Print function with the number of digits You want

You can also check the following code
http://arduino.cc/playground/Code/PrintFloats

To verfy if a I2C device is wired in the rigth way I usually use a simple sketch like this

// Verify addresse and access to I2C devices
#include <Wire.h>

void setup(void)
{
  Serial.begin(57600);
  Serial.println("Start I2C ...");
  Wire.begin();
  delay(5);
  for (uint8_t add = 0X0; add < 0X80; add++) {
    Wire.requestFrom(add, (uint8_t)1);
    if (Wire.available()) {
      Serial.print("Found: ");
      Serial.println(add, HEX);
    }
  }
  Serial.println("Done"); 
  
}

void loop(void){

}

Ciao,
Marco.

THX
i thought it is much more complex, so i didn't look up the basic functions :wink:

maybe you can add your lib to the playground. I think it would be easier for beginners to find it instead of searching the forum for your code.