by Floris Wouterlood – The Netherlands
Introduction
Water is everywhere around us, not only in water bodies but also, and very importantly, as moisture in the air that surrounds us and that we breathe. The amount of water vapor inside the atmosphere depends on the air temperature. Hot air can hold much more water than cold air. Moist air that becomes colder reaches a certain temperature threshold: the dew point. As the name suggests, the dew point is the temperature where air is 100% saturated with water vapor. Below this temperature water starts to condense to forms water droplets. The humidity of the atmosphere is therefore tied to the temperature of that air: relative humidity, that is, in relation to the air temperature. In physical terms: the relative humidity of air is the ratio of the partial pressure of water vapor to the equilibrium vapor pressure at a given temperature (wikipedia).
A high relative humidity of the air around us makes us feel uncomfortable because the ability of our skin to dissipate redundant body heat by sweating is diminished. Dry air isn’t comfortable either: when the relative humidity is below 30% our noses start to feel dry and unhappy. Too dry air may damage our respiratory system. The airways in our body are designed to control the humidity of respiratory air.
Relative humidity can be very accurately measured with a big, hand held device called a psychrometer. In many homes old fashioned analog hair hygrometers indicate the humidity. Today, electronics does the work for us, fast and economically. Several devices exist in the Arduino ecosphere with which the relative humidity of the atmosphere can be determined. One of these is the Si7021 (see fig. 1) which contains a thermistor and a humidity sensor that measures resistance over a substrate whose resistance capacity depends on the amount of water absorbed from the air. As most electronic sensors with the same purpose the Si7021 measures the two essential parameters in the surrounding air: temperature and humidity. The Si7021 is sold as a breakout board with four pins of which two serve the I2C communication protocol. The temperature range of a Si7021 is between -40 oC and +125 oC while relative humidities between 0% and 100% are measured.
SI7021: pins and connectivity with an Arduino
Figure 1 shows a Si7021 breakout board. It contains a SHT21 type humidity sensor (the tiny white padded device). Because the Si7021 chip is strictly 3V a voltage level shifter is on board that enables the sensor to work without problems with 5V microcontroller boards (such as the Nano). Four pins stick out from the bottom of the breakout board, labeled VIN, GND, SCL and SDA. VIN delivers 5V DC power to the SI7021. The device will also work with 3V microcontrollers. GND is ground, and SCL and SDA are the I2C pins that are necessary for data exchange with the Arduino.
Connectivity with an Arduino is quite straightforward and is pictured in figure 1. We use in this example an Arduino Nano, but an Arduino Uno has the same pin layout as the Nano and works equally well.
Connectivity table
pin on the SI7021 – connects to ….. | pin on the Arduino marked |
VIN | 5V |
GND | GND |
SCL | pin A5 |
SDA | pin A4 |
Pull up resistor
A 4.7 kΩ resistor must be mounted between SDA and VIN, and between SCL and VIN, in order to keep the signal level high during operation of the SI7021. A 4.7 kΩ pull up resistor is incorporated in the wiring scheme of Figure 1. According to the specs sheet of the Si7021, 10 kΩ pull-up resistors can be used as well.
Figure 1: Connection wiring scheme of a SI7021 and an Arduino, in this example a Nano. VIN is connected to 5V on the Nano, GND to GND, SCL to A5 and SDA to A4. Pull up resistors for SCL and SDA are compulsory. The LED is optional.
Electronics and supplies
1x Arduino Nano microcontroller board, Si7021 breakout board, 2x 4.7 kΩ resistor, breadboard, jumper wires, 1x LED, 1x 220Ω resistor.
Figure 2: Working version of a Nano mounted together with a SI7021 on a breadboard. Note the 4.7 kΩ resistors placed between 5V and pin A4 and between 5V and pin A5.
Sketch
Below is the complete ‘bare’ sketch. An up- and running Arduino IDE on your computer is necessary. Copy-paste the list of instructions below into an empty new file in the Arduino IDE,
// Si_7021_bare
// this sketch reads temperature and relative humidity from a SI7021 I2C sensor
// sketch reports to Serial Monitor
// Floris Wouterlood – February 19, 2018
// public domain
// library
#include <Wire.h>
// declared variables
const int ADDR =0x 40;
int X0,X1,Y0,Y1,Y2,Y3;
float X,Y,X_out,Y_out1,Y_out2;
#define ledpin 8
void setup()
{
Serial.begin (9600);
Wire.begin ();
Serial.println (“*** Si7021 bare ***”);
Serial.println (“=====================”);
pinMode (ledpin,OUTPUT);
delay (100);
}
void loop()
{
// start temperature measurement
Wire.beginTransmission (ADDR);
Wire.write (0xE3);
Wire.endTransmission ();
// read temperature
Wire.requestFrom (ADDR,2);
if(Wire.available ()<=2);
{
X0 = Wire.read ();
X1 = Wire.read ();
X0 = X0<<8;
X_out = X0+X1;
}
// calculate temperature
X=(175.72*X_out)/65536;
X=X-46.85;
// start relative humidity measurement
Wire.beginTransmission (ADDR);
Wire.write (0xE5);
Wire.endTransmission ();
// read relative humidity data
Wire.requestFrom (ADDR,2);
if(Wire.available()<=2);
{
Y0 = Wire.read ();
Y2 = Y0/100;
Y0 = Y0%100;
Y1 = Wire.read ();
Y_out1 = Y2*25600;
Y_out2 = Y0*256+Y1;
}
// calculate relative humidity
Y_out1 = (125*Y_out1)/65536;
Y_out2 = (125*Y_out2)/65536;
Y = Y_out1+Y_out2;
Y = Y-6;
// send temperature and humidity to Serial Monitor
Serial.print (“temperature: “);
Serial.print (X,1);
Serial.println (” *C”);
Serial.print (“humidity: “);
Serial.print (Y,1);
Serial.println (” %”);
Serial.println ();
delay (200);
// blink the led and next wait one second
digitalWrite (ledpin, HIGH);
delay (500);
digitalWrite (ledpin, LOW);
delay (1000);
}
Let’s go through the sketch
#include “Wire.h”
const int ADDR =0x40;
Wire.write (0xE3)
Wire.write (0xE5);
Results
The output of the sketch on Serial Monitor is shown in figure 3. Temperature and humidity are reported with one decimal. Because of the limited accuracy it does not make much sense to display one-hundreds of degrees. One-decimal output is forced with the instruction Serial.print (X,1). The ‘1’ in the expression stands for ‘one decimal’.
Figure 3: Serial Monitor output of the sketch in this Bare Basics article.
Sketch: Si7021_bare.ino