Skip to main content

5.1 Reading Temperature and Humidity

The goal of this example is to measure the temperature and the humidity of the room with the kit's SHTC3 sensor, and print both to the Serial Monitor. One chip the size of a grain of rice measures both at once, accurately enough that you will see the numbers move when you breathe on it.

This is the second Qwiic module in the kit, after the ultrasonic sensor in section 3. That means the wiring is again a single cable, and again there is nothing to get wrong.

In this documentation you will learn:

  • How one sensor measures both temperature and relative humidity.
  • What relative humidity is a percentage of, and why that matters.
  • How to connect a second kind of Qwiic module, and why it needs no pin numbers.
  • Why one reading takes two function calls, and what happens if you skip the first.
  • How millis() paces the measurements without ever freezing the board.

Hardware required:

  • 1x Soldered NULA MINI board
  • 1x Breadboard
  • 1x Soldered SHTC3 temperature and humidity sensor
  • 1x Qwiic cable
  • 1x USB-C cable
ℹ️
No resistors and no jumper wires. Like the ultrasonic sensor in 3.1, this is a Qwiic module, so one cable carries power and data together and it only fits one way round. If you have just finished 3.1, the build is identical except for which module hangs off the end of the cable.

Putting the components together

Four steps, and only one of them is a connection.

1. Insert the NULA MINI board on the breadboard

Push the board into one end of the breadboard so that its two rows of pins sit on either side of the centre channel. In the photos it occupies rows 25 to 30.

NULA MINI board seated on the breadboard
Step 1: the board seated on the breadboard
ℹ️
As in 3.1, the breadboard does no electrical work here. Nothing at all connects to the board's pins. It is holding the board flat and steady so that you can push a cable into it without it skating across the desk.

2. Plug the Qwiic cable into the board

The NULA MINI has one Qwiic connector, on the edge of the board between the USER and RST buttons, marked qwiic on the silkscreen. Push the cable in until it clicks.

Qwiic cable plugged into the NULA MINI board, with the other end still loose
Step 2: the cable in the board's Qwiic connector, other end still free
⚠️
Do not confuse it with the smaller two-contact connector on the opposite edge, marked - and +. That one is the battery connector, and a Qwiic cable will not fit it.

If you would like to see exactly which connector this is on a bare board, it is highlighted here:

The NULA MINI board with its Qwiic connector highlighted
The Qwiic connector on the NULA MINI, highlighted in blue

3. Plug the other end into the sensor

The sensor is a small purple board silkscreened SHTC3 BREAKOUT. It has two Qwiic connectors, one at each end, with the word qwiic printed beside both. They are wired together, so plug the free end of the cable into either one. The spare is there so you can chain a further module onwards.

Qwiic cable running from the NULA MINI board to the SHTC3 sensor
Step 3: the cable joining the board to the sensor. That is the entire circuit

Here is the sensor board on its own, close up:

Close-up of the SHTC3 breakout board showing the sensor, the two qwiic connectors and the SCL, SDA, VCC and GND pads
The SHTC3 breakout: two qwiic connectors, four solder pads, and the sensor itself in the middle

Worth noticing on this board:

  • The sensor itself is the tiny black component in the middle. Both the thermometer and the humidity icon on the silkscreen point at it, because it really does measure both.
  • It sits on a narrow tongue of circuit board with slots cut on either side of it. Those slots are deliberate: they make it harder for warmth from the rest of the board to travel along the copper and reach the sensor, which would otherwise report the board's own temperature rather than the room's.
  • The four pads marked SCL, SDA, VCC and GND carry the same four signals as the Qwiic cable, brought out for anyone who would rather solder wires than plug a cable in. You do not need them here.
  • The JP1 to JP4 pads are factory settings. Leave them as they came.

4. Connect the USB-C cable

Plug the USB-C cable into the board and into your computer. The purple PWR light beside the RST button comes on, and the sensor is powered too, taking what it needs through the Qwiic cable.

The finished build: NULA MINI on the breadboard with USB-C attached and the SHTC3 sensor on the Qwiic cable
Step 4: the finished build, powered up
ℹ️
You may notice the USB cable is already attached in the step 2 photo and absent again in step 3. It genuinely does not matter when you connect it. Qwiic modules are safe to plug in and unplug either way about, powered or not.

What the sensor actually measures

Temperature is the straightforward half, reported in degrees Celsius.

Relative humidity is the half that catches people out. It is reported as a percentage, but it is not a percentage of the air's volume or of its weight. It is a percentage of the most water vapour the air could hold at its current temperature, so 47 % means the air is carrying a little under half of what it currently could.

The catch is that the capacity itself moves. Warm air holds far more water vapour than cold air. So if you heat a room without adding or removing a single drop of water, the relative humidity falls: the same vapour is now a smaller share of a larger maximum. That is why a heated room in winter feels dry, and it is why these two numbers are far more useful together than either is alone.

ℹ️
The quickest way to see the sensor respond is to breathe gently on it from a few centimetres away. Your breath is warm and nearly saturated, so the humidity figure climbs steeply within a second or two, then drifts back down over the next half minute as that air mixes back into the room.

Why there are no pin numbers

As with the ultrasonic sensor, the sensor object is created with empty hands:

SHTC3 shtcSensor;

The reason is the one explained in 3.1 Measuring Distance: a Qwiic cable is a fixed bundle of four conductors: 3.3 V, ground, and the two signal lines of the I2C bus. On the NULA MINI those two signal lines are permanently wired to IO6 and IO7. They are not brought out to the pin headers at all. There is nothing to choose, so there is nothing to tell the library.

What does differ from one module to the next is the address it answers to, since I2C lets several modules share one pair of wires. The ultrasonic sensor answers to 0x30. This one answers to 0x70. The library already knows that, which is why begin() takes no arguments either.

ℹ️
Because their addresses differ, this sensor and the LCD from section 4 can sit on the same two wires at the same time without interfering with each other. That is exactly what example 7.1 Smart Weather Station does.

Installing the library

This example needs the SHTC3 Soldered Library. If you followed Setting up the Arduino environment you already have it. If not, open Tools → Manage Libraries, search for SHTC3, and install the one published by Soldered Electronics.

⚠️
If the IDE reports fatal error: SHTC3-SOLDERED.h: No such file or directory, the library is not installed. Install it and compile again. Nothing is wrong with the wiring or the board.

One reading, two function calls

Collecting a measurement is a two-step affair, and the order matters:

shtcSensor.sample();
float temperature = shtcSensor.readTempC();
float humidity = shtcSensor.readHumidity();

sample() is the only one of the three that talks to the sensor at all. It wakes the chip, asks it to measure, collects the raw numbers, and puts the chip back to sleep. readTempC() and readHumidity() then simply convert the numbers sample() already brought back.

That has a consequence worth remembering. If you call readTempC() without calling sample() first, you get no error and no warning. You get the previous measurement over again, which looks exactly like a sensor that has frozen.

ℹ️
The chip spends nearly all its time asleep, waking only for the few milliseconds each measurement takes. That is part of how a sensor this small measures air temperature accurately at all. A chip that stayed awake would warm itself and report its own heat instead.

Measuring without stopping

The sketch does not use delay() to wait two seconds between readings. It uses millis(), which reports how long the board has been running, and takes a new measurement only once the remembered lastUpdate moment is UPDATE_MS in the past:

unsigned long now = millis();

if (now - lastUpdate >= UPDATE_MS) {
lastUpdate = now;
// ...take a measurement...
}

delay(2000) would have been shorter to write, but it stops the board dead for two seconds at a time. Written this way, the board races around loop() thousands of times a second and only occasionally finds that a measurement is due, which leaves it free to do other things in between. As soon as a sketch has two jobs, reading a sensor and watching a button, this is the pattern that lets both happen.

ℹ️
millis() counts up in an unsigned long and, after roughly 50 days of continuous running, overflows back to zero. The subtraction now - lastUpdate is written the way it is because it stays correct even across that rollover.

Code

/**
**************************************************
*
* @file 5.1_Reading_Temperature_and_Humidity.ino
* @brief Example that shows how to measure temperature and humidity using the Soldered SHTC3 sensor.
* The sensor communicates with the board over easyC, so only one cable is needed and no pins have to
* be defined. The measured values are printed to the Serial Monitor.
* For details, connection diagram and more, check out the example documentation at: <link placeholder>
* @author Soldered
***************************************************
*/

/*
Including a library gives us access to ready-made functions that do the hard work for us. Here we include the
Soldered library for the SHTC3 sensor. If the Arduino IDE reports that this file cannot be found, install the library
through Sketch -> Include Library -> Manage Libraries and search for "Soldered SHTC3".
*/
#include "SHTC3-SOLDERED.h"

/*
Here we create our sensor object, which we named "shtcSensor". An object is our way of talking to the sensor: every
function we call on it, we call through this name. Notice that we do not pass any pin numbers this time. The SHTC3
uses easyC, which is Soldered's name for an I2C connection over a single cable, and I2C always uses the same two
pins on the board (IO6 and IO7 on the NULA board), so the library already knows where to find the sensor.
*/
SHTC3 shtcSensor;

/*
This variable defines how much time passes between two measurements, in milliseconds. 2000 milliseconds is two
seconds. Feel free to experiment with this value.
*/
const unsigned long UPDATE_MS = 2000;

/*
This variable remembers the moment when we took the last measurement. We compare it against the current time to know
when the next measurement is due. It has to be an unsigned long because the numbers the clock gives us grow large.
*/
unsigned long lastUpdate = 0;

void setup() {

/*
Serial.begin() establishes serial communication between your board and your computer via a USB cable. We use it
here so we can display the temperature and humidity readings on the Serial Monitor.
*/
Serial.begin(115200);

/*
begin() prepares the sensor for use and starts the I2C communication. It also tells us whether the sensor answered:
the function returns true on success and false on failure. We check the result and print a message either way, so
that if nothing shows up later we know whether the problem is the cable or the code.
The "!" in front of the call means "not", so this if statement reads as "if the sensor did not start".
*/
if (!shtcSensor.begin()) {
Serial.println("SHTC3 initialization failed!");
} else {
Serial.println("SHTC3 sensor ready!");
}
}

void loop() {

/*
millis() is a function that returns the number of milliseconds passed since the board began running the current
program. We use it instead of delay() so that the board stays free to do other work between measurements, which
matters as soon as your program has more than one job. This number will overflow (go back to zero) after
approximately 50 days.
*/
unsigned long now = millis();

/*
Here we check how much time has passed since the last measurement. Only when UPDATE_MS milliseconds have gone by do
we take a new reading, and we immediately remember the current time as the new starting point.
*/
if (now - lastUpdate >= UPDATE_MS) {
lastUpdate = now;

/*
sample() tells the sensor to perform a fresh measurement and store the result inside itself. We have to call it
before reading the values, otherwise we would keep getting the result of the previous measurement.
*/
shtcSensor.sample();

/*
readTempC() returns the temperature from the last measurement in degrees Celsius, and readHumidity() returns the
relative humidity in percent. Both are decimal numbers, which is why we store them in float variables.
*/
float temperature = shtcSensor.readTempC();
float humidity = shtcSensor.readHumidity();

/*
Serial.print() prints data without skipping to the next line, while Serial.println() prints the data and then
skips to the next line. By combining them we build one readable line out of several pieces. The number 2 after a
value tells the function how many decimal places to show.
*/
Serial.print("Temperature: ");
Serial.print(temperature, 2);
Serial.print(" °C, Humidity: ");
Serial.print(humidity, 2);
Serial.println(" %");
}
}

What you should see

Upload the sketch, then open the Serial Monitor and set it to 115200 baud.

The first line to appear is SHTC3 sensor ready!, printed once from setup(). After that a new line arrives every two seconds:

Serial Monitor at 115200 baud showing temperature around 24.7 degrees Celsius and humidity around 47 percent
Readings arriving every two seconds. The startup line has already scrolled off the top

Both values are printed to two decimal places. In this screenshot the room is at about 24.7 °C and 47 % relative humidity, and successive readings differ only in the last decimal or two: 24.70, then 24.73, then 24.68. That small wobble is the sensor being honest about its own precision, not a fault.

Now breathe gently on the sensor and watch the humidity column. It should climb hard, well past 60 %, and then settle back over the next half minute. If it does, the sensor is genuinely measuring the air rather than repeating a stored number.

⚠️
If you see SHTC3 initialization failed! instead, begin() could not get an answer from the sensor. There are two likely causes, in this order. First, the Qwiic cable is not pushed fully home at one of its two ends. Second, and much easier to miss: the wrong board is selected in the IDE. Every Soldered library takes its I2C pins from whichever board you picked, so selecting anything other than Soldered NULA Mini ESP32C6 sends the I2C traffic to the wrong pins. It still compiles and still uploads, and the sensor still never answers.
ℹ️
If nothing appears at all, check the baud rate before anything else. At any setting other than 115200 the Serial Monitor prints unreadable symbols or stays blank.

Full example

Check out the full example code on the link below:

5.1_Reading_Temperature_and_Humidity.ino

Example that shows how to measure temperature and humidity using the Soldered SHTC3 sensor and display the readings on the Serial Monitor.