SHT31/Getting a reading/07. One command, six bytes
Getting a reading · 07 of 11

One command, six bytes

One library call is two separate conversations with a twelve-millisecond gap in the middle. Almost none of the time a reading takes is spent moving data, which is the fact the rest of this chapter and the next one both rest on.

Two conversations, not one

One command, six bytes
Traffic at 100 kHz
0.90 ms
Sensor measuring
12.5 ms
Bus plus measuring
0.00 ms
Nothing has happened yet. Press the button and watch where the time goes.

readBoth() looks like one function call and is two exchanges on the bus with a wait between them.

First, your board writes three bytes: the sensor's address with the write bit, then the two halves of one 16-bit command. 0x2400 means measure once, at high repeatability, and do not stretch the clock. The sensor acknowledges each byte, and the acknowledgement of the command is what starts the measurement.

Then the bus goes quiet. The sensor is busy. It has up to 15 ms and typically takes 12.5; Adafruit's library simply waits 20 ms, which is safely past the maximum.

Finally your board writes the address again, this time with the read bit, and the sensor sends six bytes.

Where the time goes

At the 100 kHz every Arduino core starts Wire at, one byte costs nine clock pulses — eight of data and one for the acknowledge — so it takes 90 µs.

BytesTime
Command out30.27 ms
Six bytes back, plus the address70.63 ms
The wait12.5 ms

The traffic is under a millisecond. The wait is more than ten times all of it put together, and it is the sensor's own physics rather than anything about the bus — so running the bus at 400 kHz makes a reading about 0.7 ms faster out of 21, which is nothing.

That ratio is why the library's twenty-millisecond wait is worth knowing about, and why taking two measurements when you needed one costs so much.

The order the bytes come in

Six bytes, in this order:

  1. Temperature, high byte
  2. Temperature, low byte
  3. A checksum over those two
  4. Humidity, high byte
  5. Humidity, low byte
  6. A checksum over those two

Temperature comes first. This catches people out constantly, because nearly every library, example and tutorial prints humidity first — so the order in the serial monitor is the reverse of the order on the wire. If you ever decode the six bytes yourself, that is the mistake to expect.

The clock-stretching alternative

The sensor offers each measurement command twice: once with clock stretching and once without.

With stretching, the sensor answers the read header immediately and then holds SCL down until the measurement is finished. Your read blocks, the sensor releases the line when it is ready, and nobody has to guess a delay.

It sounds strictly better and is not. A device holding the clock down is something the host's I²C hardware has to be prepared for, and not every implementation is — the failure is a hang rather than an error. Adafruit's library sends the non-stretching command and waits, and that is why it works on everything.

Two more commands worth knowing

Beyond measuring, three commands come up:

  • Soft reset, 0x30A2. The only reset this board has, since nRESET is not brought out to the header. sht.reset() sends it.
  • Read status, 0xF32D. A 16-bit register with a heater bit, an alert bit and a flag saying whether the last command was accepted. sht.readStatus().
  • Heater on and off, 0x306D and 0x3066. There is a heating element inside the sensor and the datasheet is emphatic that it is for plausibility checking only — switch it on, watch the temperature rise a few degrees and the humidity fall, and you have proved both elements are alive. It is not a way to dry the sensor out, and leaving it on makes every reading wrong. It is off after a reset.

When it does not work

Why can I not just read the sensor without sending anything?

Because there is nothing to read until you ask. The sensor is idle between measurements — a fifth of a microamp idle — and takes a measurement only when a command tells it to. Reading it without a command gets a NACK, which the library reports as a failed read.

What is clock stretching, and do I want it?

An alternative to waiting. With stretching enabled the sensor holds SCL down until the measurement is finished, so your read blocks instead of you timing it. Adafruit's library always sends the non-stretching command and waits 20 ms, which is the safer choice: not every microcontroller's I²C hardware handles a device holding the clock, and the ones that do not simply hang.

Can I ask for the faster, noisier measurement instead?

The sensor can — there are commands for low and medium repeatability, 2.5 ms and 4.5 ms — but this library cannot. readTempHum always sends 0x2400, the high-repeatability one, whatever you do. Getting the others means writing the two command bytes yourself with Wire.

Does it keep measuring in the background?

Not in this mode. Single-shot means one command produces exactly one data pair and then the sensor goes idle again. The sensor also has a periodic mode where one command starts a stream at up to ten readings a second, and this library does not use it.

Where this goes next

Two bytes, one straight line and a checksum that turns a corrupted reading into no reading at all.

From bytes to degrees

Edit this page — content/books/sht31/one-command-six-bytes.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

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.

Browse Modules and blocks on the forum