Tags:
create new tag
view all tags

The SHT30 I2C Temperature and Humidity Sensor

Introduction

The SHT30 is a temperature and humidity sensor that communicates over the I2C bus. Typical accuracy for temperature is +- 0.1 C and +- 1.5% relative humidity. Sensirion, the company behind the SHT30 supplies a series of documents including the data sheet, several application notes and sample code, written in C for the STM32F10x micro-controller. You can find them at https://www.sensirion.com/en/download-center/humidity-sensors/digital-humidity-sensors-for-various-applications.

There is also a SHT30 driver written for MicroPython on the ESP8266 but unfortunately it did not work on the ESP32 out of the box. Making it work for the ESP32 is not too difficult however. This is the subject of an exercise on the SHT30 ( The I2C bus and the SHT30 Temperature and Humidity Sensor ). Since the SHT30 driver only implements a small subset of the SHT30 functionality, I developed a driver called SHT3X translating the Sensirion code into MicroPython and taking over some of the SHT30 code.

Here is a list of functions, their command codes and if they are implemented in the SHT30 driver:

Function Repeatability measurement per s Clock Stretching Command Code Implemented in SHT30 driver
Single shot data acquisition High   enabled 0x2C06 no
Medium 0x2C0D no
Low 0x2C10 no
High disabled 0x2400 yes
Medium 0x240B no
Low 0x2416 no
Continuous data acquisition High 0.5 disabled 0x2032 no
Medium 0x2024 no
Low 0x202F no
High 1 0x2130 no
Medium 0x2120 no
Low 0x212D no
High 2 0x2236 no
Medium 0x2220 no
Low 0x222B no
High 4 0x2334 no
Medium 0x2322 no
Low 0x2329 no
High 10 0x2737 no
Medium 0x2722 no
Low 0x272A no
Read serial number       0x3780 no
Fetch Data       0xE000 no
Accelerated Response Time 0x2B32 no
Break continuous acquisition 0x3093 no
Soft Reset 0x30A2 yes
Heater enable 0x306D yes
Heater disable 0x3066 yes
Read out status register 0xF32D yes
Clear status register 0x3041 yes
Read high alert limit set 0xE11F no
clear 0xE114 no
Read low alert limit set 0xE109 no
clear 0xE102 no
Write high alert limit set 0x611D no
clear 0x6116 no
Write low alert limit set 0x610B no
clear 0x6100 no

The SHT30 command codes

The SHt30 uses 16 bit command codes with a 3-bit CRC (cyclic redundancy check) calculated over the upper 13 bit added on the lowest significant 3 bits.
Let us have a look at the "one time measurement" commands in order to understand the command layout. Here is the table from the data sheet:

sht30commandCode.png

If we analyze the codes we get:

Repeatability Clock Stretching Command code bit for clock stretching rest of command code bits for repeatability CRC
High enabled 0010 1 100 0000 0 110
Medium 0010 1 100 0000 1 101
Low 0010 1 100 0001 0 000
High disabled 0010 0 100 0000 0 000
Medium 0010 0 100 0000 1 011
Low 0010 0 100 0001 0 110

As you can see, knowing the repeatability and the clock stretching parameter we can easily construct the command code: Starting from a command code 0x2400 we set bit 11 if clock stretching is enabled and we "or" 01 into bits 3 and 4 for medium and 10 for low repeatability to get the command code. This code we use as a key into a dictionary from where we can pick up the 3 bit checksum, which we or to bits 0..2 .

Methods available in the SHT3X class

Here is a list of the available methods of the SHT3Xclass:

__init__(scl_pin=machine.Pin(22),sda_pin=machine.Pin(21),i2c,address=0x45): creates an instance of the SHT3X object. The default values for scl_pin, sda_pin and i2c_address should be ok for the ESP32 and our version of the SHT30 shield. The method raises an SHT3XError.BUS_ERROR if the sht30 chip is not found on the I2C bus

from sht3x import SHT3X

sht30 = SHT3X()

should therefore work and create the SHT3X object.

sht30.isPresent(): returns True if the sht30 is chip is found on the I2C bus, False otherwise

sht30.serialNumber(): Returns the 32 bit serial number of the sht30 chip

sht30.readStatus(): Returns the status bits (16 bits) from the status register

sht30.printStatus(): Prints the status bits from the sht30 status register in a humanly readable form

sht30.clearStatus(): Clears the status register

sht30.softReset(): Resets the sht30

sht30.enableHeater(): Switches the heater on

sht30.disableHeater(): Switches the heater off

sht30.getTempAndHumi(clockStretching=!SHT3X.CLOCK_STRETCH, repeatability=!SHT3X.REP_S_LOW, raw=False, timeout=100)

gets temperature and humidity in the selected mode. If clock stretching as been selected the corresponding command 0x2cxx is issued followed by a wait until the measurement has been completed. The wait time used is the maximum measurement time for that mode found in table 4 chapter 2.2 of the data sheet.

If no clock stretching is selected, the method will poll the sht30 every ms for the result data. It within "timeout ms" the sht30 does not return the result an SHT3X.TIMEOUT error is raised.

After the wait, the data are read out and the checksum checked. If the checksum received is wrong an SHT3X.CRC_ERROR is raised.

If raw mode has been selected, the 6 byte result (16 bits for temperature, 16 bits humidity and 2*8 bits checksums) is returned. Otherwise the raw values are converted to physical temperature values (in C) and relative humidity (in %) which are returned to the caller.

sht30.Celsius2Fahrenheit(tempC): takes a temperature value in C and converts it to F

sht30.startPeriodicMeas(mps=0.5,repeatability=self.REP_P_HIGH): starts repetitive measurements in the selected mode. In "continuous mode" clock stretching is not done. Here I wait for the period selected before the data are read out.

sht30.stopPeriodicMeas(): Stops "continuous measurement mode"

sht30.measPeriodic(self,mps=0.5, repeatability=REP_P_HIGH, raw=False, noOfMeas=50, callback=None): Starts continuous measurements using sht30.startPeriodicMeas(), reads out the data after each measurement and stops continuous measurements using stopPeriodicMeas() as soon as "noOfMeas" measurements have been reached. You can specify a callback function which is called with [tempC,humi], the temperature in C and the humidity value in % as parameter if raw is False or with the raw data [tempRaw,humiRaw,checksum] as parameter if raw is True.

sht30.readAlert(high=True,set=True,raw=False): Reads the alert limits. Returns temperature and humidity limits for alerts in C and % or the raw data read out if raw == True.

sht30.writeAlert(self,tempC,humi,high=True,set=True): Write the alert limits

Here you find the driver itself:

https://afnog.iotworkshop.africa/pub/UCC_Course_2021/SHT30NopI2CTemperatureAndHumiditySensor/sht3x.py.txt

and here some test code exercising the driver:

https://afnog.iotworkshop.africa/pub/UCC_Course_2021/SHT30NopI2CTemperatureAndHumiditySensor/sht3xTest.py.txt

And here is the result printed out by the test program:

>>> %Run -c $EDITOR_CONTENT
Serial number: 0x317d411
Measure with clock stretching, the delay between writing the cmd and reading back the result
is calculated from the repeatabilty parameter (see data sheet)
Temperature: 24.26994 C, Humidity: 61.74011 %
Measure without clock stretching
After sending the command the SHT30 is polled for the result every 1ms
Generates a timeout exception if the SHT30 does not respond in time
Temperature: 24.28329 C, Humidity: 61.75385 %
Read and print the alert settings: High limit to set the alert
The data sheet says that this should be 60C and 80%
Temperature limit high: 59.93164 C Humidity limit high: 79.6875 %
Set accelerated response time
Print the current status register contents
--------------------------------------------------
Status register content: 0x2060
--------------------------------------------------
No alert pending
Heater is enabled
Last command succeeded
Checksum of last write command was correct
Clear the status register, switch on the heater and print the values again
Switch on the heater
--------------------------------------------------
Status register content: 0x20a0
--------------------------------------------------
No alert pending
Heater is enabled
Last command succeeded
Checksum of last write command was correct
Start periodic measurement
We pass the function printContinuousValues as callback routine, printing the temperature and humidity values
read out in each measurement cycle
Period measurement will take 20.0 s
Interval: 2.0
Temperature: 24.21387 C, Humidity: 61.6684 %
Temperature: 24.26994 C, Humidity: 61.78131 %
Temperature: 24.28329 C, Humidity: 61.79504 %
Temperature: 24.24057 C, Humidity: 61.80878 %
Temperature: 24.25392 C, Humidity: 61.83167 %
Temperature: 24.24057 C, Humidity: 61.82861 %
Temperature: 24.22722 C, Humidity: 61.85608 %
Temperature: 24.24057 C, Humidity: 61.91101 %
Temperature: 24.22722 C, Humidity: 61.92932 %
Temperature: 24.21387 C, Humidity: 61.90643 %
--------------------------------------------------
Status register content: 0x2000
--------------------------------------------------
No alert pending
Heater is enabled
Last command succeeded
Checksum of last write command was correct
>>>

-- Uli Raich - 2020-05-22

Comments

Topic attachments
I Attachment History Action Size Date Who Comment
PNGpng sht30commandCode.png r1 manage 24.8 K 2020-05-24 - 18:11 UliRaich  
Texttxt sht3x.py.txt r1 manage 18.5 K 2020-05-23 - 19:48 UliRaich  
Texttxt sht3xTest.py.txt r1 manage 2.7 K 2020-05-23 - 19:48 UliRaich  
Edit | Attach | Watch | Print version | History: r6 < r5 < r4 < r3 < r2 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r6 - 2020-10-12 - UliRaich
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2021 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback