In this article we look at the SI7021 Temperature Sensor with examples for the Arduino and Raspberry Pi
The Si7021 I2C Humidity and Temperature Sensor is a monolithic CMOS IC integrating humidity and temperature sensor elements, an analog-to-digital converter, signal processing, calibration data, and an I2C Interface. The Si7021 offers an accurate, low-power, factory-calibrated digital solution ideal for measuring humidity, dew-point, and temperature, in applications ranging from HVAC/R and asset tracking to industrial and consumer platforms.
Features
- Relative Humidity Sensor:
- Si7013/21: ± 3% RH (maximum) @ 0-80% RH
- Si7020: ± 4% RH (maximum) @ 0-80% RH
- Si7006: ± 5% RH (maximum) @ 0-80% RH
- Temperature Sensor:
- Si7013/20/21: ±0.4°C accuracy (maximum) @ -10 to +85°C
- Si7006: ±1.0°C accuracy (maximum) @ -10 to +85°C
- 0 to 100% RH operating range
- Up to -40 to +125°C operating range
- Wide operating voltage range (1.9 to 3.6V)
- Low Power Consumption: 2.2µW average power at 3.3V and 1 sample per second
- I2C host interface
- Integrated on-chip heater
- 3mm x 3mm QFN package
- Excellent long term stability
- Factory calibrated
- Optional factory-installed filter/cover
- Lifetime protection during reflow and in operation
- Protects against contamination from dust, dirt, household chemicals and other liquids
- AEC-Q100 automotive qualified (Si7013/20/21)
Raspberry Pi and Si7021
Parts List
Schematics and Connections

Code
Python example
Save the following as SI7021.py
[codesyntax lang=”python”]
import smbus import time # Get I2C bus bus = smbus.SMBus(1) bus.write_byte(0x40, 0xF5) time.sleep(0.3) # SI7021 address, 0x40 Read 2 bytes, Humidity data0 = bus.read_byte(0x40) data1 = bus.read_byte(0x40) # Convert the data humidity = ((data0 * 256 + data1) * 125 / 65536.0) - 6 time.sleep(0.3) bus.write_byte(0x40, 0xF3) time.sleep(0.3) # SI7021 address, 0x40 Read data 2 bytes, Temperature data0 = bus.read_byte(0x40) data1 = bus.read_byte(0x40) # Convert the data and output it celsTemp = ((data0 * 256 + data1) * 175.72 / 65536.0) - 46.85 fahrTemp = celsTemp * 1.8 + 32 print "Relative Humidity is : %.2f %%" %humidity print "Temperature in Celsius is : %.2f C" %celsTemp print "Temperature in Fahrenheit is : %.2f F" %fahrTemp
[/codesyntax]
Run the code by typing – sudo python SI7021.py on the command line, you will see the following

Java example
This time we explore the world of Java on the Raspberry Pi
First you need to install PI4j – http://pi4j.com/install.html . I’ll sum it up as its easy to install from a terminal
The simplest method to install Pi4J on your RaspberryPi is to execute the following command directly on your RaspberryPi.
curl -s get.pi4j.com | sudo bash
Now for the java code – this is courtesy of a controleverything example
[codesyntax lang=”java”]
// Distributed with a free-will license. // Use it any way you want, profit or free, provided it fits in the licenses of its associated works. // SI7021 // This code is designed to work with the SI7021_I2CS I2C Mini Module available from ControlEverything.com. // https://www.controleverything.com/content/Humidity?sku=SI7021_I2CS#tabs-0-product_tabset-2 import com.pi4j.io.i2c.I2CBus; import com.pi4j.io.i2c.I2CDevice; import com.pi4j.io.i2c.I2CFactory; import java.io.IOException; public class SI7021 { public static void main(String args[]) throws Exception { // Create I2C bus I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1); // Get I2C device, SI7021 I2C address is 0x40(64) I2CDevice device = bus.getDevice(0x40); // Send humidity measurement command device.write((byte)0xF5); Thread.sleep(300); // Read 2 bytes of humidity data, msb first byte[] data = new byte[2]; device.read(data, 0, 2); // Convert humidity data double humidity = (((((data[0] & 0xFF) * 256) + (data[1] & 0xFF)) * 125.0) / 65536.0) - 6; // Send temperature measurement command device.write((byte)0xF3); Thread.sleep(300); // Read 2 bytes of temperature data, msb first device.read(data, 0, 2); // Convert temperature data double cTemp = (((((data[0] & 0xFF) * 256) + (data[1] & 0xFF)) * 175.72) / 65536.0) - 46.85; double fTemp = (cTemp * 1.8 ) + 32; // Output data to screen System.out.printf("Relative Humidity : %.2f %% %n", humidity); System.out.printf("Temperature in Celsius : %.2f C%n", cTemp); System.out.printf("Temperature in Fahrenheit : %.2f F%n", fTemp); } }
[/codesyntax]
Now you have to compile and run the program like this
$> sudo pi4j SI7021.java

Arduino and Si7021
The good thing about the Arduino example is that this will work with many boards if you have enabled support in the IDE. I have tried this on an ESP32, ESP8266 and Micro:bit
Parts List
Schematics and Connections

Code
[codesyntax lang=”cpp”]
#include <Wire.h> const int ADDR =0x40; int X0,X1,Y0,Y1,Y2,Y3; double X,Y,X_out,Y_out1,Y_out2; void setup() { Serial.begin(9600); Wire.begin(); delay(100); Wire.beginTransmission(ADDR); Wire.endTransmission(); } void loop() { /**Send command of initiating temperature measurement**/ Wire.beginTransmission(ADDR); Wire.write(0xE3); Wire.endTransmission(); Serial.print("Temp"); Serial.print("\t"); Serial.println("Humidity"); /**Read data of temperature**/ Wire.requestFrom(ADDR,2); if(Wire.available()<=2); { X0 = Wire.read(); X1 = Wire.read(); X0 = X0<<8; X_out = X0+X1; } /**Calculate and display temperature**/ X=(175.72*X_out)/65536; X=X-46.85; Serial.print(X); Serial.print("C"); Serial.print("\t"); /**Send command of initiating relative humidity measurement**/ Wire.beginTransmission(ADDR); Wire.write(0xE5); Wire.endTransmission(); /**Read data of relative humidity**/ 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 and display relative humidity**/ Y_out1 = (125*Y_out1)/65536; Y_out2 = (125*Y_out2)/65536; Y = Y_out1+Y_out2; Y=Y-6; Serial.print(Y); Serial.println("%"); delay(300); Serial.println(); delay(1000); }
[/codesyntax]
Output
Open the serial monitor, you should see something like this
Temp Humidity
23.12C 52.83%
Temp Humidity
24.04C 53.13%
Temp Humidity
26.28C 53.83%
Temp Humidity
27.42C 54.57%
Temp Humidity
28.27C 55.32%
Temp Humidity
27.94C 56.11%