Skip to content

Commit cdfba0b

Browse files
committed
drivers/sensor/sht: Add driver for SHT3x/SHT4x sensors.
1 parent 66fa62b commit cdfba0b

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
metadata(description="SHT3x/SHT4x temperature/humidity sensor driver.", version="0.1.0")
2+
3+
module("sht.py", opt=3)

micropython/drivers/sensor/sht/sht.py

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Micropython driver for temperature/humidity sensors SHT3x/SHT4x
2+
#
3+
# Example usage on picoboard:
4+
# @code{.py}
5+
# from machine import Pin, I2C
6+
# from sht import SHT
7+
# import time
8+
# i2c = I2C(0, scl=Pin(5), sda=Pin(4))
9+
# sensor = SHT(i2c)
10+
# sensor.start_measure(2)
11+
# while True:
12+
# time.sleep(0.01)
13+
# t_raw, t_val, h_raw, h_val, isvalid = sensor.get_measure_results()
14+
# if isvalid is not None:
15+
# break
16+
# print(f"{t_raw}, {t_val} °C, {h_raw}, {h_val} %RH, {isvalid}")
17+
# @endcode
18+
#
19+
20+
from machine import I2C
21+
import time
22+
23+
24+
class SHT:
25+
SHT3x = 0x30
26+
SHT4x = 0x40
27+
28+
# Init SHT
29+
# @param i2c I2C interface
30+
# @param addr I2C addr (default = 0x44)
31+
# @param sht SHT type
32+
# 0x00 (autodetect SHT type)
33+
# self.SHT3x
34+
# self.SHT4x
35+
def __init__(self, i2c, addr=0x44, sht=0x00):
36+
self.i2c = i2c
37+
self.i2c_addr = addr
38+
self.sht = sht
39+
if self.sht == 0x00:
40+
self.sht = self.detect_sht_type()
41+
else:
42+
self.sht = sht
43+
44+
# Verify checksum
45+
# @param data data bytes
46+
# @param checksum received crc
47+
# @return crc status
48+
# 0 = crc does not match
49+
# 1 = crc ok
50+
def _check_crc(self, data, checksum):
51+
crc = 0xFF
52+
for byte in data:
53+
crc ^= byte
54+
for _ in range(8):
55+
if crc & 0x80:
56+
crc = (crc << 1) ^ 0x31
57+
else:
58+
crc = crc << 1
59+
crc = crc & 0xFF
60+
return checksum == crc
61+
62+
# Autodetect SHT type
63+
# @return SHT type
64+
# self.SHT3x = SHT30/31/35
65+
# self.SHT4x = SHT40/41/45
66+
# 0xFF = unknown
67+
def detect_sht_type(self):
68+
sht = 0xFF
69+
# try reading status of SHT3x
70+
try:
71+
self.i2c.writeto(self.i2c_addr, b"\xf3\x2d", False)
72+
time.sleep(0.01)
73+
response = self.i2c.readfrom(self.i2c_addr, 3)
74+
if self._check_crc(response[0:2], response[2]):
75+
sht = self.SHT3x
76+
except OSError:
77+
pass
78+
if sht == 0xFF:
79+
# try reading serial number of SHT4x
80+
try:
81+
self.i2c.writeto(self.i2c_addr, b"\x89", False)
82+
time.sleep(0.01)
83+
response = self.i2c.readfrom(self.i2c_addr, 6)
84+
if self._check_crc(response[3:5], response[5]):
85+
sht = self.SHT4x
86+
except OSError:
87+
pass
88+
return sht
89+
90+
# Start measurement
91+
# @param precision 0..2 [Low, Medlium, High]
92+
# @return None
93+
def start_measure(self, precision):
94+
if self.sht == self.SHT3x:
95+
p_byte = [b"\x16", b"\x0b", b"\x00"]
96+
self.i2c.writeto(self.i2c_addr, b"\x24" + p_byte[precision], False)
97+
if self.sht == self.SHT4x:
98+
cmd = [b"\xe0", b"\xf6", b"\xfd"]
99+
self.i2c.writeto(self.i2c_addr, cmd[precision], False)
100+
101+
# Get the measurement values
102+
# @details
103+
# As long as no values available all return parameter are None.
104+
# If values not equal None are returned the measurement has been completed
105+
# and needs to be restarted again for a new measurement.
106+
# @return temperature[raw], temperature[°C], humidity[raw], humidity[%RH], valid
107+
def get_measure_results(self):
108+
try:
109+
response = self.i2c.readfrom(self.i2c_addr, 6)
110+
t_bytes = response[0:2]
111+
t_raw = int.from_bytes(t_bytes, "big")
112+
t_val = (175 * t_raw) / 0xFFFF - 45
113+
isvalid = self._check_crc(t_bytes, response[2])
114+
h_bytes = response[3:5]
115+
h_raw = int.from_bytes(h_bytes, "big")
116+
h_val = (100 * h_raw) / 0xFFFF
117+
isvalid &= self._check_crc(h_bytes, response[5])
118+
return t_raw, round(t_val, 2), h_raw, round(h_val, 2), bool(isvalid)
119+
except OSError:
120+
# OSError: [Errno 5] EIO as long as measurement has not completed
121+
return None, None, None, None, None

0 commit comments

Comments
 (0)