Last active
December 10, 2023 17:35
-
-
Save creeper6530/70738f3fc68b0023ab75670154b84273 to your computer and use it in GitHub Desktop.
Python code for reading DHT20 sensor from Raspberry Pi (improved)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# Import stuff | |
import smbus | |
from time import sleep | |
from os import remove | |
class Lock: | |
# Constructor - define class-wide variables | |
def __init__(self, path): | |
self.path = path | |
self.fd = None # File descriptor | |
# Locking function - attempt to create lockfile, return success | |
def lock(self): | |
try: | |
self.fd = open(self.path, "x") | |
except FileExistsError: | |
return False | |
else: # If no exception is raised | |
return True | |
# Unlocking function - delete lockfile, call destructor | |
def unlock(self): | |
self.__del__() | |
remove("/var/lock/dht20") | |
# Destructor - close lockfile, change file descriptor to null | |
def __del__(self): | |
if self.fd != None: | |
self.fd.close() | |
self.fd = None | |
class DHT20: | |
def __init__(self): | |
# Initialize lock | |
self.lock = Lock("/var/lock/dht20") | |
# Open I2C bus, handle permission error | |
try: | |
self.bus = smbus.SMBus(1) # We assume you are connected to the first I2C bus | |
except PermissionError: | |
print("Could not open I2C bus: Permission denied.") | |
print("Try re-running the script as root.") | |
exit(1) | |
def read(self): | |
# Acquire lock on device | |
if self.lock.lock() == False: | |
print("Could not acquire lock. The device is currently in use.") | |
print("Please try again later.") | |
exit(1) | |
# Get raw data from device, close I2C bus | |
self.bus.write_i2c_block_data(0x38, 0xAC, [0x33, 0x00]) # I2C address, start register, data - list of bytes | |
sleep(0.1) # Give it some time to measure | |
raw_data = self.bus.read_i2c_block_data(0x38, 1, 7) # I2C address, start register, block length | |
# Release lock, close I2C bus | |
self.lock.unlock() | |
self.bus.close() | |
return self.calculate(raw_data) | |
def calculate(self, raw_data): | |
# Perform some fancy calculations I copied from the Internet :) | |
temp = 0 | |
temp = (temp | raw_data[3]) << 8 | |
temp = (temp | raw_data[4]) << 8 | |
temp = temp | raw_data[5] | |
temp = temp & 0xfffff | |
temp = (temp * 200 * 10 / 1024 / 1024 - 500)/10 | |
humidity = 0 | |
humidity = (humidity | raw_data[1]) << 8 | |
humidity = (humidity | raw_data[2]) << 8 | |
humidity = humidity | raw_data[3] | |
humidity = humidity >> 4 | |
humidity = (humidity * 100 * 10 / 1024 / 1024)/10 | |
return temp, humidity | |
# Print output if the program is not imported itself | |
if __name__ == "__main__": | |
# Initialize sensor, do measurement | |
sensor = DHT20() | |
temp, humidity = sensor.read() | |
# Print result rounded to 3 decimals | |
print(f"Temperature: {round(temp, 3)} °C") | |
print(f"Humidity: {round(humidity, 3)} % RH") | |
exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment