-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsht41.py
More file actions
102 lines (85 loc) · 3.17 KB
/
sht41.py
File metadata and controls
102 lines (85 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# SHT41 Driver Library
import time
from machine import I2C
class SHT41:
# Device address
ADDRESS = 0x44
# Commands
CMD_RESET = b'\x94'
CMD_SERIAL = b'\x89'
CMD_MEASURE_HIGH = b'\xFD'
CMD_MEASURE_MED = b'\xF6'
CMD_MEASURE_LOW = b'\xE0'
def __init__(self, i2c: I2C):
self.i2c = i2c
self.reset() # Reset on initialization
time.sleep(0.01) # Wait after reset
def reset(self):
"""Soft reset the sensor"""
try:
self.i2c.writeto(self.ADDRESS, self.CMD_RESET)
time.sleep(0.01) # Wait for reset to complete
return True
except Exception as e:
print(f"Reset error: {e}")
return False
def _crc8(self, data):
"""Calculate CRC8 checksum"""
crc = 0xFF
for byte in data:
crc ^= byte
for _ in range(8):
if crc & 0x80:
crc = (crc << 1) ^ 0x31
else:
crc <<= 1
crc &= 0xFF
return crc
def read_serial(self):
"""Read the sensor serial number"""
try:
self.i2c.writeto(self.ADDRESS, self.CMD_SERIAL)
time.sleep(0.01)
data = self.i2c.readfrom(self.ADDRESS, 6)
return data
except Exception as e:
print(f"Serial read error: {e}")
return None
def read(self, precision="high"):
"""
Read temperature and humidity from the sensor
precision: "high", "medium", or "low" (affects measurement time)
"""
# Select command based on precision
if precision == "medium":
cmd = self.CMD_MEASURE_MED
elif precision == "low":
cmd = self.CMD_MEASURE_LOW
else: # Default to high precision
cmd = self.CMD_MEASURE_HIGH
# Delay times for different precision levels
delays = {"high": 0.01, "medium": 0.005, "low": 0.002}
try:
# Send measurement command
self.i2c.writeto(self.ADDRESS, cmd)
# Wait for measurement to complete
time.sleep(delays[precision])
# Read 6 bytes: temp (2) + CRC (1) + humidity (2) + CRC (1)
raw = self.i2c.readfrom(self.ADDRESS, 6)
# Parse data
temp_raw = raw[0:2]
temp_crc = raw[2]
hum_raw = raw[3:5]
hum_crc = raw[5]
# Verify checksums
if self._crc8(temp_raw) != temp_crc or self._crc8(hum_raw) != hum_crc:
raise ValueError("CRC check failed")
# Convert raw values to temperature and humidity
temp_ticks = (temp_raw[0] << 8) | temp_raw[1]
hum_ticks = (hum_raw[0] << 8) | hum_raw[1]
# Apply conversion formulas from datasheet
temperature = -45 + (175 * temp_ticks / 65535.0)
humidity = 100 * hum_ticks / 65535.0
return temperature, humidity
except Exception as e:
raise Exception(f"Measurement error: {e}")