Learn

An SHT31 on an Arduino: temperature and humidity

Intermediate

Or see every lesson.

  • 505parts on the bench
  • 45boards running now
  • 1.00xreal time, on every board
Arduino Uno: an SHT31 in an air quality monitorlive0.000 s 0.00x
Click to open it in the editor
An SHT31, an SGP30 and an HT16K33 display on one I2C bus, on a simulated ATmega328P.

The SHT31 is a temperature and humidity sensor from Sensirion, sold on small breakouts as the SHT31-D. It is the sensor people move to when a DHT22 is not good enough: it talks over I2C, so it shares two wires with a display or a gas sensor, and every reading comes with a checksum.

The circuit above is an Uno running a home air quality monitor. An SHT31, an SGP30 gas sensor and a four-digit display share one I2C bus, and the display takes turns showing the CO2 level, the temperature and the humidity. Press Run, wait for the 15 second warm-up, then drag the SHT31’s sliders and watch the display follow. Below is the short serial example most SHT31 guides use.

What you need

  • An Arduino Uno
  • An SHT31-D breakout
  • For the full monitor: an SGP30 breakout, an HT16K33 four-digit display and a red LED with a 220 ohm resistor
  • A breadboard and jumper wires

Wiring

Part and pinGoes toNote
SHT31 VIN5 VThe board takes 2.15 to 5.5 V
SHT31 GNDGND
SHT31 SDAA4Shared with the SGP30 and the display
SHT31 SCLA5Shared with the SGP30 and the display
Red LED, through 220 ohmPin 8Lights above 1000 ppm of CO2

How the SHT31 talks

The SHT31 has no registers to read. The Arduino sends a 16-bit command to start a measurement, waits, and then reads six bytes: the temperature, a checksum, the humidity and a second checksum. The chip sits at I2C address 0x44 with its ADDR pin low, which is how the boards ship, or 0x45 with it high.

A measurement takes up to 15 milliseconds at high repeatability. Ask for the result too soon and the sensor refuses the read. The Adafruit library waits 20 milliseconds for you, so you never see this unless you write your own driver.

The raw numbers are 16 bits each. The datasheet turns them into degrees and percent with two short sums: T = -45 + 175 x S / 65535 and RH = 100 x S / 65535.

The Adafruit SHT31 example

Install "Adafruit SHT31 Library" from the Library Manager in the Arduino IDE. In Mokxi it is built in. begin(0x44) resets the sensor and checks that it answers. readTemperature() and readHumidity() each take a fresh measurement and return a float, or NaN if the checksum fails.

Run this sketch with the sensor at 23 degrees and 48 percent and it prints "Temp *C = 22.99" and "Hum. % = 47.99". The sensor only has 65,536 steps across its range, and 23.00 falls between two of them, so the reading lands a hundredth under. Drag the temperature to 31.5 and the next line says "Temp *C = 31.49".

Change begin(0x44) to begin(0x45) on a board whose ADDR pin is low and the sketch prints "Couldn't find SHT31" and stops. That one line is the first thing to check when a sensor does not show up.

SHT31 example sketch
#include <Wire.h>
#include "Adafruit_SHT31.h"

Adafruit_SHT31 sht31 = Adafruit_SHT31();

void setup() {
  Serial.begin(9600);
  if (!sht31.begin(0x44)) {
    Serial.println("Couldn't find SHT31");
    while (1) delay(1);
  }
}

void loop() {
  float t = sht31.readTemperature();
  float h = sht31.readHumidity();
  if (!isnan(t)) {
    Serial.print("Temp *C = ");
    Serial.println(t);
  }
  if (!isnan(h)) {
    Serial.print("Hum. % = ");
    Serial.println(h);
  }
  delay(1000);
}

Open this sketch in the editorThe code alone: the editor places the board and the parts it can read from the sketch.

The air quality monitor

The monitor at the top uses the same library a different way. measure() takes one reading of both values, and getTemperatureCentis() and getHumidityCentis() return it in hundredths, as whole numbers. The sketch rounds those to whole degrees and percent for the display.

For the first 15 seconds the display counts down from "--15" while the gas sensor warms up. Then it shows " 650" for the CO2 in ppm, "23*C" for the temperature and "48rh" for the humidity, in turns. Drag the SHT31 to 31.5 degrees and 65.5 percent and the display shows "31*C" and "65rh". It says 31, not 32, because the sensor reads 31.49 and the sketch rounds to the nearest degree.

The SHT31 also helps the SGP30: the gas sensor is more accurate when it knows how much water is in the air, so the sketch works that out from the temperature and humidity and passes it on with setHumidity().

From the air quality monitor sketch
#include <Wire.h>
#include "Adafruit_SHT31.h"

Adafruit_SHT31 sht31 = Adafruit_SHT31();

void loop() {
  bool climate = sht31.measure();
  int32_t centiC = sht31.getTemperatureCentis();
  int32_t centiRh = sht31.getHumidityCentis();
  if (climate) sgp.setHumidity(absoluteHumidity(centiC, centiRh));
}

SHT31 or DHT22

A DHT22 needs a pin of its own, a timing-sensitive protocol and two seconds between readings. An SHT31 shares the I2C bus, answers in 15 milliseconds and checks every reading with a CRC. Sensirion rates it at about 2 percent humidity and 0.3 degrees, better than the DHT22.

The SHT30 and SHT35 are the same family with the same commands, so the same library and wiring work for them.

Every reading carries a checksum. If one fails, from a long or noisy wire, the library returns NaN instead of a wrong number, and the example’s isnan() checks simply skip that line. The chip also has a small heater for drying off condensation, switched with heater(true). Mokxi keeps the setting, so isHeaterEnabled() reports it, but the simulated sensor does not warm up.

Common mistakes

The wrong address: 0x44 in the sketch when the board’s ADDR pin is high, or 0x45 when it is low.

Reading straight after the command in a hand-written driver. The sensor needs up to 15 milliseconds and refuses an early read.

Mounting it next to the Uno’s regulator or a warm display. The SHT31 measures the air right at the chip, so a warm neighbor reads as a warm room.

Two sensors at the same address. Two SHT31 boards on one bus need one at 0x44 and one at 0x45.

Open this circuit in the editor. Arduino Uno: an SHT31 in an air quality monitor, wired as it runs at the top of this page. Change a part or a value and run it again.

Open the circuit

Questions

Which library should I use for the SHT31 on Arduino?

Adafruit SHT31 Library (Adafruit_SHT31.h) is the one most examples use. It works for the SHT30 and SHT35 too.

What is the SHT31 I2C address?

0x44 with the ADDR pin low, the default on most boards, or 0x45 with it high.

What is the difference between the SHT31 and the SHT31-D?

SHT31-D is the name on the common breakout boards, such as Adafruit’s. The chip on them is the same SHT31, with its digital I2C output.

Can the SHT31 run on 5 V?

Yes. It takes 2.15 to 5.5 V, so it runs on an Uno’s 5 V or a 3.3 V board.

Can I use two SHT31 sensors on one Arduino?

Yes, on the same two wires, as long as they have different addresses. Tie one board’s ADDR pin high so it answers at 0x45, keep the other at 0x44, and make two objects, one started with begin(0x44) and one with begin(0x45).

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.