Monday, July 15, 2019

Interfacing HH10D humidity sensor with Arduino

by / Sunday, 17 June 2012 / Published in Arduino


HH10D is capacitive-type relative air humidity sensor. It is cheap (~$8) and relatively precise (±3%).

In this article I’ll describe how to connect and use it with your Arduino board.

You can download the datasheet from


First of all, pay your attention to that fact that sensor’s output signal is frequency – frequency of the square wave, in range between 5 and 10 kHz, like shown on image: squarewave

In fact, the capacitive sensor is connected to ICM7555 timer IC, which outputs the wave signal, depending on sensor’s value.

To get actual RH (Relative Humidity) reading, in percents, we must calculate using the formula described in datasheet:

RH = (Offset - F)*Sensitivity/212,

where F is frequency in Hz measured on FOUT pin.

This formula includes two calibration values - Offset and Sensitivity. They are individual to each unit, and are stored in tiny on-board I2C EEPROM, so you need to read them before you can use the sensor. However, if your are not going to replace the sensor or build several devices based on your project, reading calibration values may be done just once. After that you can throw out I2C code and wiring and include calibration values to your sketch as constants, saving program memory for other things.


Measuring frequency with Arduino may be relatively simple, thanks to FreqCounter library. However, if you need more than 2 PWM outputs in your project, things come a bit more complicated. If you need not more that 2 PWM outputs, then just ignore this section, but if you need, then either consider choosing another sensor – or read the following article: . It's an alternative way to measure frequency, however, it is not as accurate as using hardware timers.

FreqCounter affects 2 of 3 ATMega’s timers, and PWM duty cycles on Arduino pins 10, 9, 6 will significantly change. Pin 5 will be taken by FreqCounter – this cannot be changed, due to hardware restrictions. The only outputs available for PWM are  pins 11 and 3.

Also I’ve heard that FreqCounter may conflict with Servo library, but I cannot say that for sure.


If you look on the top side of you sensor (the one which has ICs), you will see the following:

hh100d pins

Connects them to your Arduino, as shown on the wiring diagram:

public HH100D bb

  • SCL goes to pin A5
  • SDA to A4 (these are pins for I2C, they cannot be changed)
  • FOUT to digital pin 5
  • VDD to +3V3
  • GND to GND
  • Also you should attach two 4.7 kOhm pullup resistors between 3V3 line and SCL\SDA lines.

VERY IMPORTANT: This sensor is 3.3v device, and you will probably need a level shifter on SCL and SDA to connect it to 5V-Arduino via I2C . In my case, everything worked normally without it, but this gives no warranty that your sensor will not be damaged. Read more here:
I’m not responsible for any damage or loss if you decide to follow my way, without level shifting.

You can use I2C+SMBus Voltage Translator or TI PCA9306 for this.


This code relies on FreqCounter library.

 HH10D humidity sensor sample code.
 (C) Semyon Tushev, 2011.
 License: CC-BY-SA
 The circuit:
 * SCL to A5 via level-shifter (5V-3V3)
 * SDA to A4 via level-shifter (5V-3V3)
 * FOUT to digital pin 5
 * VDD to 3V3
 * GND to GND
 + pullup resistors for i2c(4k7, 10k) (
 HH10D real I2C address is 81 (the datasheet contains error).
#include <FreqCounter.h>
#include <Wire.h>
int freq, offset, sens;
void setup(){
 sens   =  i2cRead2bytes(81, 10); //Read sensitivity from EEPROM
 offset =  i2cRead2bytes(81, 12); //Same for offset
void loop(){
 //Get Frequency
 FreqCounter::f_comp= 8;             // Set compensation to 12
 FreqCounter::start(1000);            // Start counting with gatetime of 1000ms
 while (FreqCounter::f_ready == 0)         // wait until counter ready 
 freq=FreqCounter::f_freq;            // read result
 //Calculate RH
 float RH =  (offset-freq)*sens/4096; //Sure, you can use int - depending on what do you need
int i2cRead2bytes(int deviceaddress, byte address)  
 Wire.send(address); // address for sensitivity
 Wire.requestFrom(deviceaddress, 2);
 int rv = 0;
 for (int c = 0; c < 2; c++ )
 if (Wire.available()) rv = rv * 256 + Wire.receive();
 return rv;

 This code was tested with Arduino 0022. It has not been tested with more recent versions

Read 4330 times Last modified on Sunday, 08 March 2015 21:11

Do you like this? Please share!

Simon Tushev

Simon is IT professional with interests in web design, electronics, photography and astronomy. He writes about PHP, Yii, Joomla!, Arduino and several other topics.


Here I publish articles related to my areas of interest, my brief notes that may save some time to others, as well as some of my works.

This site is a work in progress. I will add more sections in the future, such as

  • More photos to photogallery
  • More Joomla!-related articles
  • ...



New Posts

Spam/Forgery Notice

If you've received a spam email from, please know that this emails are...

07-03-2019 in Blog


Using dynamic GeoIP module with nginx (CentOS)

nginx introduced dynamic module support in v. 1.9.11. This brief article provides step-by-step procedure...

13-04-2016 in Linux, BSD, Unix


Visual difference between pseudo and true random data

This is is "random" image generated using PHP rand() function: And this is an image...

20-11-2015 in Blog

Scroll to top

We use cookies, just to track visits to our website, we store no personal details Privacy policy