Skip to content

Instantly share code, notes, and snippets.

@creeper6530
Last active December 10, 2023 17:35
Show Gist options
  • Save creeper6530/70738f3fc68b0023ab75670154b84273 to your computer and use it in GitHub Desktop.
Save creeper6530/70738f3fc68b0023ab75670154b84273 to your computer and use it in GitHub Desktop.
Python code for reading DHT20 sensor from Raspberry Pi (improved)
#!/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