-
Notifications
You must be signed in to change notification settings - Fork 0
/
DFRobot_DHT20.py
137 lines (108 loc) · 3.97 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
# -*- coding: utf-8 -*
# 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
"""
*@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](li.feng@dfrobot.com)
*@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:
self.i2cbus = smbus.SMBus(bus)
self._addr = address
# Sensor initialization function
# @return Return True if initialization succeeds, otherwise return False.
def begin(self) -> bool:
# 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
# Get both temperature and humidity in a single read
# @return Return temperature (C), humidity (%) and CRC result (True if error else False) as tuple
def get_temperature_and_humidity(self) -> tuple[float, float, bool]:
# 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)
# CRC function
# @param message - data from sensor which its CRC-8 is to be calculated
# @return Return calculated CRC-8
def calc_CRC8(self, data: list[int]) -> int:
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