Compare commits

...

6 Commits

10 changed files with 500 additions and 94 deletions

21
DHT11_Python/LICENSE.md Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 Zoltan Szarvas
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

44
DHT11_Python/README.md Normal file
View File

@ -0,0 +1,44 @@
# DHT11 Python library
This simple class can be used for reading temperature and humidity values from DHT11 sensor on Raspberry Pi.
# Installation
To install, just run following:
```
pip install dht11
```
# Usage
1. Instantiate the `DHT11` class with the pin number as constructor parameter.
2. Call `read()` method, which will return `DHT11Result` object with actual values and error code.
For example:
```python
import RPi.GPIO as GPIO
import dht11
# initialize GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()
# read data using pin 14
instance = dht11.DHT11(pin = 14)
result = instance.read()
if result.is_valid():
print("Temperature: %-3.1f C" % result.temperature)
print("Humidity: %-3.1f %%" % result.humidity)
else:
print("Error: %d" % result.error_code)
```
For working example, see `dht11_example.py` (you probably need to adjust pin for your configuration)
# License
This project is licensed under the terms of the MIT license.

View File

@ -0,0 +1,203 @@
import time
import RPi
class DHT11Result:
'DHT11 sensor result returned by DHT11.read() method'
ERR_NO_ERROR = 0
ERR_MISSING_DATA = 1
ERR_CRC = 2
error_code = ERR_NO_ERROR
temperature = -1
humidity = -1
def __init__(self, error_code, temperature, humidity):
self.error_code = error_code
self.temperature = temperature
self.humidity = humidity
def is_valid(self):
return self.error_code == DHT11Result.ERR_NO_ERROR
class DHT11:
'DHT11 sensor reader class for Raspberry'
__pin = 0
def __init__(self, pin):
self.__pin = pin
def read(self):
RPi.GPIO.setup(self.__pin, RPi.GPIO.OUT)
# send initial high
self.__send_and_sleep(RPi.GPIO.HIGH, 0.05)
# pull down to low
self.__send_and_sleep(RPi.GPIO.LOW, 0.02)
# change to input using pull up
RPi.GPIO.setup(self.__pin, RPi.GPIO.IN, RPi.GPIO.PUD_UP)
# collect data into an array
data = self.__collect_input()
# parse lengths of all data pull up periods
pull_up_lengths = self.__parse_data_pull_up_lengths(data)
# if bit count mismatch, return error (4 byte data + 1 byte checksum)
if len(pull_up_lengths) != 40:
return DHT11Result(DHT11Result.ERR_MISSING_DATA, 0, 0)
# calculate bits from lengths of the pull up periods
bits = self.__calculate_bits(pull_up_lengths)
# we have the bits, calculate bytes
the_bytes = self.__bits_to_bytes(bits)
# calculate checksum and check
checksum = self.__calculate_checksum(the_bytes)
if the_bytes[4] != checksum:
return DHT11Result(DHT11Result.ERR_CRC, 0, 0)
# ok, we have valid data
# The meaning of the return sensor values
# the_bytes[0]: humidity int
# the_bytes[1]: humidity decimal
# the_bytes[2]: temperature int
# the_bytes[3]: temperature decimal
temperature = the_bytes[2] + float(the_bytes[3]) / 10
humidity = the_bytes[0] + float(the_bytes[1]) / 10
return DHT11Result(DHT11Result.ERR_NO_ERROR, temperature, humidity)
def __send_and_sleep(self, output, sleep):
RPi.GPIO.output(self.__pin, output)
time.sleep(sleep)
def __collect_input(self):
# collect the data while unchanged found
unchanged_count = 0
# this is used to determine where is the end of the data
max_unchanged_count = 100
last = -1
data = []
while True:
current = RPi.GPIO.input(self.__pin)
data.append(current)
if last != current:
unchanged_count = 0
last = current
else:
unchanged_count += 1
if unchanged_count > max_unchanged_count:
break
return data
def __parse_data_pull_up_lengths(self, data):
STATE_INIT_PULL_DOWN = 1
STATE_INIT_PULL_UP = 2
STATE_DATA_FIRST_PULL_DOWN = 3
STATE_DATA_PULL_UP = 4
STATE_DATA_PULL_DOWN = 5
state = STATE_INIT_PULL_DOWN
lengths = [] # will contain the lengths of data pull up periods
current_length = 0 # will contain the length of the previous period
for i in range(len(data)):
current = data[i]
current_length += 1
if state == STATE_INIT_PULL_DOWN:
if current == RPi.GPIO.LOW:
# ok, we got the initial pull down
state = STATE_INIT_PULL_UP
continue
else:
continue
if state == STATE_INIT_PULL_UP:
if current == RPi.GPIO.HIGH:
# ok, we got the initial pull up
state = STATE_DATA_FIRST_PULL_DOWN
continue
else:
continue
if state == STATE_DATA_FIRST_PULL_DOWN:
if current == RPi.GPIO.LOW:
# we have the initial pull down, the next will be the data pull up
state = STATE_DATA_PULL_UP
continue
else:
continue
if state == STATE_DATA_PULL_UP:
if current == RPi.GPIO.HIGH:
# data pulled up, the length of this pull up will determine whether it is 0 or 1
current_length = 0
state = STATE_DATA_PULL_DOWN
continue
else:
continue
if state == STATE_DATA_PULL_DOWN:
if current == RPi.GPIO.LOW:
# pulled down, we store the length of the previous pull up period
lengths.append(current_length)
state = STATE_DATA_PULL_UP
continue
else:
continue
return lengths
def __calculate_bits(self, pull_up_lengths):
# find shortest and longest period
shortest_pull_up = 1000
longest_pull_up = 0
for i in range(0, len(pull_up_lengths)):
length = pull_up_lengths[i]
if length < shortest_pull_up:
shortest_pull_up = length
if length > longest_pull_up:
longest_pull_up = length
# use the halfway to determine whether the period it is long or short
halfway = shortest_pull_up + (longest_pull_up - shortest_pull_up) / 2
bits = []
for i in range(0, len(pull_up_lengths)):
bit = False
if pull_up_lengths[i] > halfway:
bit = True
bits.append(bit)
return bits
def __bits_to_bytes(self, bits):
the_bytes = []
byte = 0
for i in range(0, len(bits)):
byte = byte << 1
if (bits[i]):
byte = byte | 1
else:
byte = byte | 0
if ((i + 1) % 8 == 0):
the_bytes.append(byte)
byte = 0
return the_bytes
def __calculate_checksum(self, the_bytes):
return the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3] & 255

26
DHT11_Python/example.py Normal file
View File

@ -0,0 +1,26 @@
import RPi.GPIO as GPIO
import dht11
import time
import datetime
# initialize GPIO
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
# read data using pin 14
instance = dht11.DHT11(pin=14)
try:
while True:
result = instance.read()
if result.is_valid():
print("Last valid input: " + str(datetime.datetime.now()))
print("Temperature: %-3.1f C" % result.temperature)
print("Humidity: %-3.1f %%" % result.humidity)
time.sleep(6)
except KeyboardInterrupt:
print("Cleanup")
GPIO.cleanup()

23
DHT11_Python/setup.py Normal file
View File

@ -0,0 +1,23 @@
from setuptools import setup, find_packages
with open("README.md", "r") as fh:
long_description = fh.read()
setup(
name="dht11",
version="0.1.0",
author="Zoltán Szarvas",
author_email="",
description="Pure Python library for reading DHT11 sensor on Raspberry Pi",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/szazo/DHT11_Python",
packages=find_packages(),
install_requires=["RPi.GPIO"],
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)

View File

@ -1,6 +1,6 @@
# DHT Humidity Sensing on Raspberry Pi
This project is a uses the AdaFruit libraries for sensing temperature using DHT11 sensor and a Raspberry Pi.
This project is a uses the basic DHT11 python library (main method) and AdaFruit libraries (alternative method) for sensing temperature using DHT11 sensor and a Raspberry Pi.
---
@ -10,13 +10,13 @@ This project is a uses the AdaFruit libraries for sensing temperature using DHT1
## Main method
> [!NOTE]
> This is the main method, using AdaFruit library. For an easier method, checkout [## Alternative method](https://git.kska.io/notkshitij/DHT11#alternative-method)
> Main method uses the `DHT11` python library for reading the sensor data.
> This is a pure Python library for reading DHT11 sensor on Raspberry Pi.
1. Install some prerequisite packages:
1. Install prerequisites:
```shell
sudo apt update &&\
sudo apt install git -y
sudo apt install -y git
```
2. Clone the project:
@ -44,28 +44,31 @@ source setup.sh
## Alternative method
> [!NOTE]
> This alternative method uses the `DHT11` python library for reading the sensor data.
> This is a pure Python library for reading DHT11 sensor on Raspberry Pi.
> This is the alternative method, using **AdaFruit library**. This method has been tested on Raspberry Pi 3B. For easier setup, checkout [## Main method](https://git.kska.io/notkshitij/DHT11#main-method)
1. Install prerequisites:
1. Install prerequisite packages:
```shell
sudo apt update &&\
sudo apt upgrade -y &&\
sudo apt install python3 python3-pip -y
sudo apt install git -y
```
2. Setup a virtual environment & install the library:
2. Clone the project:
```shell
mkdir /home/$(whoami)/temp-sensor
cd /home/$(whoami)/temp-sensor
python3 -m venv .
source bin/activate
pip install dht11 setuptools RPi.GPIO
git clone https://git.kska.io/notkshitij/DHT11.git
```
3. **Download** and **run** the code [alt-temp.py](https://git.kska.io/notkshitij/DHT11/src/branch/main/alt-temp.py)
> Alternatively, you can also [download the zip file](https://git.kska.io/notkshitij/DHT11/archive/main.zip)
3. Change the current working directory to the folder in which the project was cloned:
```shell
cd ./DHT11
```
4. Run the `ada-setup.sh` script:
```shell
source ada-setup.sh
```
> [!IMPORTANT]
> After running the code, and completing the execution, run `deactivate` in the terminal to exit the virtual environment.

96
ada-setup.sh Executable file
View File

@ -0,0 +1,96 @@
#!/bin/bash
cat << "EOF"
__| |______________________________________________________________________| |__
__ ______________________________________________________________________ __
| | | |
| | | |
| | ____ _ _ _ | |
| | | _ \ ___ ___(_) __ _ _ __ ___ __| | __ _ _ __ __| | | |
| | | | | |/ _ \/ __| |/ _` | '_ \ / _ \/ _` | / _` | '_ \ / _` | | |
| | | |_| | __/\__ \ | (_| | | | | __/ (_| | | (_| | | | | (_| | | |
| | |____/ \___||___/_|\__, |_| |_|\___|\__,_| \__,_|_| |_|\__,_| | |
| | |___/ | |
| | _____ _ _ _ | |
| | | ____|_ __ __ _(_)_ __ ___ ___ _ __ ___ __| | | |__ _ _ | |
| | | _| | '_ \ / _` | | '_ \ / _ \/ _ \ '__/ _ \/ _` | | '_ \| | | | | |
| | | |___| | | | (_| | | | | | __/ __/ | | __/ (_| | | |_) | |_| | | |
| | |_____|_| |_|\__, |_|_| |_|\___|\___|_| \___|\__,_| |_.__/ \__, | | |
| | |___/ |___/ | |
| | _ __ _ _ _ _ _ | |
| | | |/ /___| |__ (_) |_(_)(_) | |
| | | ' // __| '_ \| | __| || | | |
| | | . \\__ \ | | | | |_| || | | |
| | |_|\_\___/_| |_|_|\__|_|/ | | |
| | |__/ | |
| | | |
__| |______________________________________________________________________| |__
__ ______________________________________________________________________ __
| | | |
EOF
# Declaring variables
line="=================================="
# Update and upgrade packages
echo -e "$line\nUpdating and upgrading packages.\n$line\n"
sudo apt update && sudo apt upgrade -y
echo -e "$line\nFinished updating and upgrading packages.\n$line\n"
# Check if python3-pip is installed
echo -e "$line\nChecking for python3-pip.\n$line\n"
if ! dpkg -l | grep -q python3-pip; then
echo -e "$line\npython3-pip is not installed,\nInstalling python3-pip.\n$line\n"
sudo apt install python3-pip -y
else
echo -e "$line\npython3-pip already installed, moving on...\n$line\n"
fi
# Check if libgpiod2 is installed
echo -e "$line\nChecking for libgpiod2.\n$line\n"
if ! dpkg -l | grep -q libgpiod2; then
echo -e "$line\nlibgpiod2 is not installed,\nInstalling python3-setuptools.\n$line\n"
sudo apt install libgpiod2 -y
else
echo -e "$line\nlibgpiod2 already installed, moving on...\n$line\n"
fi
# Create project folder
USER=$(whoami)
PROJECT_DIR="/home/$USER/Desktop/temp-sensor"
if [ ! -d "$PROJECT_DIR" ]; then
echo -e "$line\nCreating 'temp-sensor' in Desktop directory for current user.\n$line\n"
mkdir -p "$PROJECT_DIR"
cp "./alt-temp.py" "./blinka-test.py" "$PROJECT_DIR/"
echo -e "$line\nCreated '$PROJECT_DIR' directory.\n$line\n"
else
echo -e "$line\n$PROJECT_DIR already exists.\n$line\n"
fi
# Create and activate Python virtual environment
cd "$PROJECT_DIR/"
chmod 775 ./alt-temp.py ./blinka-test.py
python3 -m venv . --system-site-packages
echo -e "$line\nVirtual environment created.\n$line\n"
echo -e "$line\nActivating virtual environment...\n$line\n"
source $PROJECT_DIR/bin/activate
echo -e "$line\nInstalling dependencies...\n$line\n"
pip3 install --upgrade setuptools click adafruit-python-shell adafruit-circuitpython-dht RPi.GPIO adafruit-blinka board
echo -e "$line\nSetting up raspiberry pi...\n$line\n"
sudo raspi-config nonint do_i2c 0
sudo raspi-config nonint do_spi 0
sudo raspi-config nonint do_serial_hw 0
sudo raspi-config nonint do_ssh 0
sudo raspi-config nonint do_camera 0
sudo raspi-config nonint disable_raspi_config_at_boot 0
sudo apt install -y i2c-tools libgpiod-dev python3-libgpiod
python3 blinka-test.py
echo -e "$line\nBlinka works!\n$line\n"
echo -e "\n\n\n$line$line$line\nSetup completed.\nExecute the command 'python3 alt-temp.py' to calculate the temperature.\n# DESIGNED AND ENGINEERED BY KSHITIJ.\n# END OF SCRIPT\n$line$line$line\n\n\n"

View File

@ -1,21 +1,35 @@
# NOTE: GPIO PIN 16 used
import time
import board
import adafruit_dht
import RPi.GPIO as GPIO
import dht11
# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT11(board.D16) # by default I'm using GPIO PIN 16 for data/signal transmission of DHT11
# initialize GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()
# you can pass DHT22 use_pulseio=False if you wouldn't like to use pulseio.
# This may be necessary on a Linux single board computer like the Raspberry Pi,
# but it will not work in CircuitPython.
# dhtDevice = adafruit_dht.DHT22(board.D18, use_pulseio=False)
# read data using pin 16
instance = dht11.DHT11(pin = 16)
result = instance.read()
while True:
try:
# Print the values to the serial port
temperature_c = dhtDevice.temperature # Celsius
temperature_f = temperature_c * (9 / 5) + 32 # Fahrenheit
humidity = dhtDevice.humidity
print(
"Temp: {:.1f} F / {:.1f} C Humidity: {}% ".format(
temperature_f, temperature_c, humidity
)
)
if result.is_valid():
print("Temperature: %-3.1f C" % result.temperature)
print("Humidity: %-3.1f %%" % result.humidity)
else:
print("Error: %d" % result.error_code)
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
dhtDevice.exit()
raise error
time.sleep(2.0)
GPIO.cleanup()

View File

@ -48,50 +48,35 @@ else
echo -e "$line\npython3-pip already installed, moving on...\n$line\n"
fi
# Check if libgpiod2 is installed
echo -e "$line\nChecking for libgpiod2.\n$line\n"
if ! dpkg -l | grep -q libgpiod2; then
echo -e "$line\nlibgpiod2 is not installed,\nInstalling python3-setuptools.\n$line\n"
sudo apt install libgpiod2 -y
else
echo -e "$line\nlibgpiod2 already installed, moving on...\n$line\n"
fi
# Create project folder
USER=$(whoami)
PROJECT_DIR="/home/$USER/Desktop/temp-sensor"
PROJECT_DIR="/home/$USER/Desktop/dht11-sensor"
if [ ! -d "$PROJECT_DIR" ]; then
echo -e "$line\nCreating 'temp-sensor' in Desktop directory for current user.\n$line\n"
echo -e "$line\nCreating 'dht11-sensor' in Desktop directory for current user.\n$line\n"
mkdir -p "$PROJECT_DIR"
cp "./temp-calc.py" "./blinka-test.py" "$PROJECT_DIR/"
cp "./temp-calc.py" "$PROJECT_DIR/"
cp -r "./DHT11_Python/" "$PROJECT_DIR/DHT11_Python"
echo -e "$line\nCreated '$PROJECT_DIR' directory.\n$line\n"
else
echo -e "$line\n$PROJECT_DIR already exists. Please delete the folder before running this script.\n$line\n\nExiting..."
exit 1
echo -e "$line\n$PROJECT_DIR already exists.\n$line\n"
fi
# Create and activate Python virtual environment
cd "$PROJECT_DIR/"
chmod 775 ./temp-calc.py ./blinka-test.py
python3 -m venv . --system-site-packages
chmod 775 ./temp-calc.py
python3 -m venv .
echo -e "$line\nVirtual environment created.\n$line\n"
echo -e "$line\nActivating virtual environment...\n$line\n"
source $PROJECT_DIR/bin/activate
echo -e "$line\nInstalling dependencies...\n$line\n"
pip3 install --upgrade setuptools click adafruit-python-shell adafruit-circuitpython-dht RPi.GPIO adafruit-blinka board
echo -e "$line\nSetting up raspiberry pi...\n$line\n"
sudo raspi-config nonint do_i2c 0
sudo raspi-config nonint do_spi 0
sudo raspi-config nonint do_serial_hw 0
sudo raspi-config nonint do_ssh 0
sudo raspi-config nonint do_camera 0
sudo raspi-config nonint disable_raspi_config_at_boot 0
sudo apt install -y i2c-tools libgpiod-dev python3-libgpiod
python3 blinka-test.py
echo -e "$line\nBlinka works!\n$line\n"
pip install --upgrade RPi.GPIO setuptools
# Alternatively, instead of executing the next four lines, you can also run "pip install dht11"
# but I've decided to keep the files for "dht11" package locally available for installation in the script.
cd "$PROJECT_DIR/DHT11_Python"
pip install .
pip show dht11
cd "$PROJECT_DIR/"
echo -e "\n\n\n$line$line$line\nSetup completed.\nExecute the command 'python3 temp-calc.py' to calculate the temperature.\n# DESIGNED AND ENGINEERED BY KSHITIJ.\n# END OF SCRIPT\n$line$line$line\n\n\n"

View File

@ -1,35 +1,26 @@
# NOTE: GPIO PIN 16 used
import RPi.GPIO as GPIO
import dht11
import time
import board
import adafruit_dht
# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT11(board.D16) # by default I'm using GPIO PIN 16 for data/signal transmission of DHT11
# initialize GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()
# you can pass DHT22 use_pulseio=False if you wouldn't like to use pulseio.
# This may be necessary on a Linux single board computer like the Raspberry Pi,
# but it will not work in CircuitPython.
# dhtDevice = adafruit_dht.DHT22(board.D18, use_pulseio=False)
while True:
try:
# Print the values to the serial port
temperature_c = dhtDevice.temperature # Celsius
temperature_f = temperature_c * (9 / 5) + 32 # Fahrenheit
humidity = dhtDevice.humidity
print(
"Temp: {:.1f} F / {:.1f} C Humidity: {}% ".format(
temperature_f, temperature_c, humidity
)
)
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
dhtDevice.exit()
raise error
time.sleep(2.0)
while True:
# read data using pin 16
instance = dht11.DHT11(pin = 16)
result = instance.read()
if result.is_valid():
print("Temperature: %-3.1f C" % result.temperature)
print("Humidity: %-3.1f %%" % result.humidity)
else:
print("Error: %d" % result.error_code)
time.sleep(3)
except KeyboardInterrupt:
print("Program stopped by user.")
GPIO.cleanup()