The first reading
Four wires, one library and about twenty lines. The build is genuinely this short. The work is in getting the four wires right, because several of the ways this board fails look identical from the serial monitor.
The four wires
GND first. It is the pin on the square pad, and it is the one whose absence produces the most confusing failure — the power light can still come on, borrowing a return path through the signal lines, so the board looks alive while nothing answers.
Then VCC, and it is 3V3 on anything that is not an Uno. The board's two pull-ups tie SDA and SCL to VCC, so a 5 V supply idles both signal lines at 5 V against pins rated for 3.3 V.
Then SDA and SCL, to whichever pins your board's I²C hardware lives on. Get these two swapped and everything still looks right: both lines idle high, because both have a pull-up on them. Nothing is wrong except that your board is clocking the sensor's data pin.
Scan before you sketch
Run an I²C scanner once, before the sensor sketch. It is the single most useful thirty seconds in this whole chapter, because it separates "the wiring is wrong" from "the code is wrong" — two problems that look the same from the serial monitor and have nothing to do with each other.
A working board reports one device at 0x44. Anything else and the sketch below cannot help you: go to when the scan finds nothing.
The sketch
Two lines in it are worth reading twice.
sht.begin(SHT31_ADDR) returns a bool, and checking it is the difference
between a clear message now and a stream of NaNs later. It brings the I²C bus
up itself, on whatever pins your board calls SDA and SCL by default, so there
is no Wire.begin() in the sketch at all.
sht.readBoth(&celsius, &humidity) takes one measurement and gives you
both numbers out of it. The obvious alternative — readTemperature() then
readHumidity() — takes two, twenty milliseconds apart, and nothing anywhere
warns you. That is one measurement or
two.
What you should see
Something close to the room, arriving every two seconds:
SHT31 found
22.59 C 48.29 %
22.61 C 48.27 %
22.60 C 48.34 %Two decimal places, because that is the resolution. Roughly one of them is trustworthy, because that is the accuracy. Breathe on the board and the humidity climbs within a few seconds and takes a good deal longer to come back down — which is the 8-second response time doing exactly what it says.
If the temperature reads a degree or two above the room, that is not the sketch. It is where the board is sitting.
The code
One library, one address and one call that fetches both numbers. Install Adafruit SHT31 Library from the Library Manager and accept Adafruit BusIO when the IDE offers it.
/*
SHT31 - first reading TK120 / /p/tk120
Wiring. Count from the square pad on the TinkerBlock board, sensor
side up, header at the bottom:
GND -> GND
VCC -> 3V3 (5V on an Arduino Uno. Never 5V beside a 3.3 V board:
the board's pull-ups put VCC on both signal lines.)
SDA -> GPIO 8 (Uno A4, ESP32 GPIO 21, ESP32-S3 GPIO 8, Pico GP4)
SCL -> GPIO 9 (Uno A5, ESP32 GPIO 22, ESP32-S3 GPIO 9, Pico GP5)
Arduino IDE
Tools > Board ESP32S3 Dev Module
Tools > Port the one that appears when you plug in
Tools > USB CDC On Boot Enabled
Library Manager "Adafruit SHT31 Library" by Adafruit,
and accept "Adafruit BusIO" with it
*/
#include <Adafruit_SHT31.h>
// 0x44 is what a board answers to straight out of the bag, because R3
// holds the sensor's ADDR pin at ground. Bridge the ADDR pads on the
// back and it becomes 0x45.
#define SHT31_ADDR 0x44
Adafruit_SHT31 sht;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // native-USB boards: wait for the monitor
// begin() brings up Wire itself, on whatever this board's default SDA
// and SCL pins are. For other pins, call Wire.begin(sda, scl) first.
if (!sht.begin(SHT31_ADDR)) {
Serial.println("no SHT31 at 0x44 - check GND first, then SDA and SCL");
while (true) delay(100);
}
Serial.println("SHT31 found");
}
void loop() {
float celsius, humidity;
// One command, one wait, one set of six bytes, both numbers.
if (sht.readBoth(&celsius, &humidity)) {
Serial.print(celsius);
Serial.print(" C ");
Serial.print(humidity);
Serial.println(" %");
} else {
// A checksum that did not match, or nothing on the bus at all. One
// failure now and then is normal; every time is the wiring.
Serial.println("read failed");
}
delay(2000);
}readBoth is doing the work here, and it is deliberate: it takes one measurement and hands back both numbers. Calling readTemperature and then readHumidity would take two, and the article 'One measurement or two' is about why that is not obvious. The bool it returns is the failed read, which is why there is no isnan check anywhere in this sketch.
When it does not work
Nothing acknowledged. Check GND first, because without it the sensor has no reference and may still light its power LED. Then check that SDA and SCL are not swapped — both lines idle high either way, so the board looks perfectly normal. Then check VCC is on a rail that is actually powered rather than a spare hole.
Almost always the library. Make sure it is Adafruit SHT31 Library and that Adafruit BusIO installed with it — begin returns false if the I²C device cannot be created, not only if the sensor is absent. Reinstall both from the Library Manager and recompile.
On an ESP32-S3 or any native-USB board, set Tools > USB CDC On Boot to Enabled and reflash. Without it the USB serial port is not brought up at boot and the sketch is running perfectly with nowhere to print. Check the monitor's baud rate is 115200 too.
The sensor answered the address and its six bytes are not surviving the wires — one of the two checksums failed. Shorten the jumper wires, take it off a breadboard if you can, and if you set the bus to 400 kHz put it back to 100 kHz. Occasional failures are normal and worth retrying; constant ones are the bus.
On an ESP32 or ESP32-S3, yes — call Wire.begin(sdaPin, sclPin) before sht.begin() and any two free GPIOs will do. On an Uno or a Pico the I²C hardware is wired to particular pins, and those are the ones in the comment header.
What that one library call put on the bus, and why almost all of the time it took was spent waiting.
One command, six bytes →Edit this page — content/books/sht31/the-first-reading.mdx
Questions about this product
See what other owners have asked, and read their solutions.
SHT31 Temperature and Humidity Sensor
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.