Introduction

Maintaining humidity at home is very important for the health. Too low humidity can cause dryness of the throat, nose, and skin, which can lead to health problems such as an increased susceptibility to colds and nosebleeds. On the other hand, if the humidity is too high, sweating throughout the body does not function well. In addition, mold can easily grow. Therefore, even when using a humidifier, it is important to frequently check the humidity in the room. Typically, it is a good idea to keep humidity at 40-60%.

Commercial humidity monitor is usually not very accurate. It often show humidity with 5-10 % errors. Therefore it is very hard to maintain the humidity in a room within the desired range by using a commercial humidity monitor. On the other hand, the psychrometer is more accurate than commercial humidity monitor and also used for calibration of humidity monitors and humidistats.

Figure 1. Psychrometer with alcohol glass thermometer.
Figure 1. Psychrometer with alcohol glass thermometer.

The psychrometer is consists of dry- and wet-bulbs of thermometers. Humidity % is calculated from the difference of temperatures of these bulbs. The psychrometer can be constructed with any thermometers, like ethanol-filled glass thermometers (Figure 1). However, to obtain the humidity %, a tedious process is required. 1. Read temperature values of dry- and wet-bulbs. 2. Determine the difference of two values. 3. Use a table to obtain the humidity %.

These tedious steps can be automated by using electric-thermometers and micro-controller. Here I show a project to construct psychrometer with Raspberry Pi Pico, MCP9808, Pico-ePaper-2.13, and 74HC00. After construction of my own DIY psychrometer, I only need to maintain the water in a small container for measuring the accurate humidity in my room.

Components

I chose Microchip MCP9808 as the electric-thermometer. According to Microchip, the typical accuracy is ±0.25 °C and the maximum error is ±0.5 °C. This range of error is acceptable to measure the room temperature. To calculate the humidity, the temperature difference of two chips is important and ±0.5 °C error causes unacceptable error in humidity, but the errors of each chip can be calibrated in advance for accurate humidity determination.

Raspberry Pi Pico is used as the micro-controller for this project. Recently, it is my favorite to construct most electric projects. It is less expensive and has the enough capabilities for my projects. Low power consumption is also good because I prefer battery-powered operation for this type of project.

I chose Waveshare Pico-ePaper-2.13 as the display. The commercial humidity monitors use custom-made LCD for low power consumption, which cannot be applied to DIY project. The ePaper maintains its display even when not powered, so it is a good choice for battery-powered products.

The 74HC00 was used to construct a latch for measuring time by capacitor and resistor. I started the project with this IC in the beginning and am still using it now, but it might be replaced by LMC555 timer in the future.

The schematic
The schematic

The sensors and calibration

I used two  MSOP-8 packages of Microchip MCP9808 as temperature sensors. These have I2C interface, so I assigned 0x1f and 0x1b as I2C addresses for these chips (by coneeting all A0, A1, and A2 pins to Vdd, or connecting A0, A1, and A2 pins to Vdd, Vdd, and GND, respectively). After soldering four wires (Vdd, GND, SDA, and SCL)  to the chip, those were encased in epoxy resin (Figure 2).

Figure 2. Two MCP9808 chips are encased in epoxy resin.
Figure 2. Two MCP9808 chips are encased in epoxy resin.

According to the datasheet, the maximum error of temperature read by this chip is ±0.5 °C, so the maximum error of difference between readings of two sensors is ±1.0 °C. Such error is not acceptable to obtain accurate humidity. Therefore, I calibrated the temperature difference between readings from these two chips.

I don't show the whole source code for measurement, but the key code as follows:

int i,t1,t2;
unsigned char d[2];
// Bulb 1 
i=i2c_read_blocking(IO_I2C_CH,0x1f,d,2,false);
t1=((d[0]&0xf)<<8)|d[1];
t1=10*t1/15;
printf("I2C read 1: %d 0x%x 0x%x %d\n",i,d[0],d[1],t1);
// Bulb 2 
i=i2c_read_blocking(IO_I2C_CH,0x1b,d,2,false);
t2=((d[0]&0xf)<<8)|d[1];
t2=10*t2/15;
printf("I2C read 2: %d 0x%x 0x%x %d\n",i,d[0],d[1],t2);

  The two probes are put into a water bath (Figure 3) and the temperature readings were compared at several temperatures.

Figure 3. Test of two temperature probes.
Figure 3. Test of two temperature probes.
Figure 4. Difference of temperature readings of two MCP9808 sensors.
Figure 4. Difference of temperature readings of two MCP9808 sensors.

The difference of temperature reading between two sensors are between 0.1 to 0.3 °C (Figure 4). In the normal room temperature range (between 20 °C and 30 °C), the difference is approximately 0.2 °C. Therefore, calibrations were done as follows: for bulb 1, 0.1 °C was added to the reading and for bulb 2, 0.1 °C was subtracted.

Calculation of humidity %

The C function for obtaining humidity % is as follows:

int humidity(float Td, float Tw){
    if (Td>=Tw) {
        float e_sd=6.1078 * pow(10.0, 7.5 * Td / (Td + 237.3));
        float e_sw=6.1078 * pow(10.0, 7.5 * Tw / (Tw + 237.3));
        float e=e_sw-0.67077 * (Td-Tw); // 0.67077 = 0.000662 * 1013.25
        return (int)(100.0*e/e_sd);
    } else {
        // Dry bulb and wet bub are opposite
        float e_sd=6.1078 * pow(10.0, 7.5 * Tw / (Tw + 237.3));
        float e_sw=6.1078 * pow(10.0, 7.5 * Td / (Td + 237.3));
        float e=e_sw-0.67077 * (Tw-Td); // 0.67077 = 0.000662 * 1013.25
        return (int)(100.0*e/e_sd);
    }
}

 In this code, two equations are used: Tetens equation for determining saturated water vapor pressure from temperature and Sprung's formula for determining humidity.

Temperature: T degree-C
Saturated water vapor pressure: e(T) hPa
e(T)=6.1078 x 10 ^ (7.5 x T / (T + 237.3))
Note that 10 ^ 7.5 = e ^ 17.27

Sprung's formula:
e=e_sw - A x p x (Td - Tw)
, where
    e: water vapor partial pressure
    e_sw: saturated water vapor pressure of wet bulb
    A=0.000662 (K^-1)
    p: atmospheric pressure (=1013.25 hPa)
    Td: temperature of dry bulb
    Tw: temperature of wet bulb

 As the error in difference temperature between two sensors is less than 0.1 °C, the error in humidity % is less than 1 % by considering above equations.

Construction

This project consists of four layers (Figure 5).

Figire 5. Four layer circuit: base, socket, RP-Pico, and ePaper layers.
Figire 5. Four layer circuit: base, socket, RP-Pico, and ePaper layers.

The base layer contains power cable, 74HC00, MOSFET, and sockets for the other components. The second layer contains sockets between base and RP-Pico. The third layer is RP-Pico. The top layer is ePaper. This architecture was designed for fitting to a project box. The temperature sensors were covered by the cut twisting balloons. The finished product is as follows:

Figure 6. Psychrometer in a box.
Figure 6. Psychrometer in a box

Power control

This circuit is powered by battery. It's not required to power on RP-Pi and display all the time because the ePaper maintain the display without power. Therefore, I supplied the power periodically to Raspberry Pi Pico and ePaper. The circuit contain 10k ohm resistor and 47 μF capacitor connected to 74HC00 latch (see schematic). This time-measuring system produces power-on state about every 20 seconds.

Source code

The program for automation of humidity calculation is written in C. The source code is uploaded to a GitHub repository.

The "main.c" file controls periodic power control. Measurement of humidity is done every 8 power on event. To count the number of power on, flash memory-based counter is used. As a result, the humidity is measured about every 3 minutes.

The "get_t_data()" function in "io.c" file measures humidity. The key code to calculate humidity is shown above. This file also contain "check_battery()" function to determine battery capacity remaining (4.5 V is full; 3.6 V is empty).

The "EPD_2in13_V4_draw()" function in "EPD_2in13_V4.c" file draws the information in an ePaper. This function calls the library functions provided by Waveshare. I made the large fonts (font107, font94, and font82) for this project. I also made battery fonts (battery32 and battery16).