-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDFRobot_DHT20.py
163 lines (124 loc) · 4.52 KB
/
DFRobot_DHT20.py
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# -*- coding: utf-8 -*
"""
### Raspberry Pi Python library for DHT20 Temperature and Humidity Sensor with CRC verification.
### https://github.com/cjee21/RPi-DHT20
Originally from https://github.com/DFRobot/DFRobot_DHT20/tree/master/python/raspberrypi
| Modified by https://github.com/cjee21/
| MIT License
| Copyright (c) 2022-2023 cjee21
Modifications:
- 25 February 2022
- use `smbus2`
- add decimal to temperature formula
- add `get_temperature_and_humidity` function for getting temperature and humidity in a single read
- 16 January 2023
- correct sensor initialization check and clean up init (begin) function
- improve `get_temperature_and_humidity` function
- add CRC-8 checking
- remove functions no longer needed
- add debug logging
Note:
Sensor initialization and CRC-8 calculation is based on Aosong sample code from
http://aosong.com/userfiles/files/software/AHT20-21%20DEMO%20V1_3(1).rar
Original:
*@file DFRobot_DHT20.py
*@brief Define the basic structure of class DFRobot_DHT20
*@copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
*@licence The MIT License (MIT)
*@author [fengli]([email protected])
*@version V1.0
*@date 2021-6-25
*@get from https://www.dfrobot.com
*@https://github.com/DFRobot/DFRobot_DHT20
"""
import time
import smbus2 as smbus
import logging
# debug logging
logging.basicConfig()
logger = logging.getLogger(__name__)
# uncomment line below this to enable debug logging
#logger.setLevel(logging.DEBUG)
class DFRobot_DHT20(object):
''' Conversion data '''
def __init__(self, bus: int, address: int) -> None:
"""Initialize the class.
Args:
bus: The I2C bus that DHT20 is connected to. For example:
0x01
address: The I2C address of DHT20. It is:
0x38
"""
self.i2cbus = smbus.SMBus(bus)
self._addr = address
def begin(self) -> bool:
"""Sensor initialization.
Returns:
True if initialization succeeds, otherwise False.
"""
# after power-on, wait no less than 100ms
time.sleep(0.5)
# check and return initialization status
data = self.__read_reg(0x71,1)
if (data[0] & 0x18) != 0x18:
return False
else:
return True
def get_temperature_and_humidity(self) -> tuple[float, float, bool]:
"""Get both temperature and humidity in a single read.
[!] Do not call this function more often than 2 seconds as recommended by the
datasheet to prevent rise in sensor temperature that will affect its accuracy.
Returns:
The temperature (±0.5℃), humidity (±3%) and
CRC result (True if error else False) as a tuple.
"""
# trigger measurement
self.__write_reg(0xac,[0x33,0x00])
# wait 80 ms and keep waiting until the measurement is completed
while True:
time.sleep(0.08)
data = self.__read_reg(0x71,1)
if (data[0] & 0x80) == 0:
break
# read sensor data
data = self.__read_reg(0x71,7)
# extract and convert temperature and humidity from data
temperature_rawData: int = ((data[3]&0xf) << 16) + (data[4] << 8) + data[5]
humidity_rawData: int = ((data[3]&0xf0) >> 4) + (data[1] << 12) + (data[2] << 4)
temperature: float = float(temperature_rawData) / 5242.88 - 50
humidity: float = float(humidity_rawData) / 0x100000 * 100
# check CRC
crc_error: bool = self.__calc_CRC8(data) != data[6]
# debug logging
if logger.isEnabledFor(logging.DEBUG):
logger.debug("Raw data : 0x" + ''.join(format(x, '02x') for x in data))
logger.debug("Read CRC : " + hex(data[6]))
logger.debug("Calculated CRC: " + hex(self.__calc_CRC8(data)))
logger.debug("Temperature : %f\u00b0C", temperature)
logger.debug("Humidity : %f %%", humidity)
# return results
return (temperature, humidity, crc_error)
def __calc_CRC8(self, data: list[int]) -> int:
"""Calculate CRC-8.
Args:
data: Data from sensor which its CRC-8 is to be calculated.
Returns:
Calculated CRC-8
"""
crc: int = 0xFF
for i in data[:-1]:
crc ^= i
for _ in range(8):
if crc & 0x80:
crc = (crc << 1)^0x31
else:
crc = crc << 1
return (crc & 0xFF)
def __write_reg(self, reg: int, data: list[int]) -> None:
time.sleep(0.01)
self.i2cbus.write_i2c_block_data(self._addr,reg,data)
def __read_reg(self, reg: int, len: int) -> list[int]:
time.sleep(0.01)
rslt: list[int] = self.i2cbus.read_i2c_block_data(self._addr,reg,len)
#print(rslt)
return rslt