initial DHT lib supports DHT11 and DHT22 devices
This commit is contained in:
commit
cb245105c9
8 changed files with 561 additions and 0 deletions
74
CODE_OF_CONDUCT.md
Normal file
74
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at support@adafruit.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
88
README.rst
Normal file
88
README.rst
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
Introduction
|
||||
============
|
||||
|
||||
.. image:: https://readthedocs.org/projects/adafruit-circuitpython-dhtlib/badge/?version=latest
|
||||
:target: https://circuitpython.readthedocs.io/projects/dhtlib/en/latest/
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image :: https://badges.gitter.im/adafruit/circuitpython.svg
|
||||
:target: https://gitter.im/adafruit/circuitpython?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
||||
:alt: Gitter
|
||||
|
||||
TODO
|
||||
|
||||
Dependencies
|
||||
=============
|
||||
This driver depends on:
|
||||
|
||||
* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_
|
||||
* `Bus Device <https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>`_
|
||||
* `Register <https://github.com/adafruit/Adafruit_CircuitPython_Register>`_
|
||||
|
||||
Please ensure all dependencies are available on the CircuitPython filesystem.
|
||||
This is easily achieved by downloading
|
||||
`the Adafruit library and driver bundle <https://github.com/adafruit/Adafruit_CircuitPython_Bundle>`_.
|
||||
|
||||
Usage Example
|
||||
=============
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
Of course, you must import the library to use it:
|
||||
|
||||
.. code:: python
|
||||
|
||||
import adafruit_dhtlib
|
||||
|
||||
The DHT type devices use single data wire, so import the board pin
|
||||
|
||||
.. code::python
|
||||
|
||||
from board import <pin>
|
||||
|
||||
Now, to initialize the DHT11 device:
|
||||
|
||||
.. code:: python
|
||||
|
||||
dhtDevice = dht.DHT11(<pin>)
|
||||
|
||||
OR initialize the DHT22 device:
|
||||
|
||||
.. code:: python
|
||||
|
||||
dhtDevice = dht.DHT22(<pin>)
|
||||
|
||||
Read temperature and humidity
|
||||
----------------------------
|
||||
|
||||
First you must request data from the device by calling method measure().
|
||||
If success is equal to 0 then data is ready
|
||||
|
||||
.. code::python
|
||||
|
||||
success = device.measure()
|
||||
|
||||
Get the temperure value and the humidity value
|
||||
|
||||
.. code::python
|
||||
|
||||
temperature = device.temperature
|
||||
humidity = device.humidity
|
||||
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
Contributions are welcome! Please read our `Code of Conduct
|
||||
<https://github.com/adafruit/Adafruit_CircuitPython_dhtlib/blob/master/CODE_OF_CONDUCT.md>`_
|
||||
before contributing to help this project stay welcoming.
|
||||
|
||||
API Reference
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api
|
||||
204
adafruit_dhtlib.py
Normal file
204
adafruit_dhtlib.py
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2017 Mike McWethy for Adafruit Industries
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
:mod:`adafruit_dhtlib`
|
||||
====================================================
|
||||
|
||||
TODO(description)
|
||||
|
||||
* Author(s): Mike McWethy
|
||||
"""
|
||||
|
||||
import pulseio
|
||||
import array
|
||||
import time
|
||||
|
||||
|
||||
class dht_base:
|
||||
""" base support for DHT11 and DHT22 devices
|
||||
"""
|
||||
|
||||
hiLev = 51
|
||||
|
||||
def __init__(self, dht11, pin, trigWait):
|
||||
"""
|
||||
:param boolean dht11: devide type. ==True DHT11 ==False DHT22
|
||||
:param ~board.Pin pin: digital pin used for communication
|
||||
:param int trigWait: length of time to hold trigger in LOW state (microseconds)
|
||||
"""
|
||||
self.dht11 = dht11
|
||||
self.pin = pin
|
||||
self.trigWait = trigWait
|
||||
|
||||
|
||||
def plsToBinary(self,r, s, l):
|
||||
""" PulsesToBinary takes r, a list of transition times, and converts
|
||||
them to a 1's or 0's. The r array contains the transition times.
|
||||
r starts with a low transition time followed by a high transistion time.
|
||||
then a low followed by a high and so on. The low transition times are
|
||||
ignored. Only the high transistion times are used. If the high
|
||||
transistion time is greater than hiLev, that counts as a bit=1, if the
|
||||
high transition time is less that hiLev, that counts as a bit=0.
|
||||
|
||||
s is the starting index in r to start converting
|
||||
|
||||
l is the last index + 1 in r to end converting
|
||||
|
||||
Returns an integer containing the converted 1 and 0 bits
|
||||
"""
|
||||
# humidity 16 bits
|
||||
i = 0
|
||||
hiSig = False
|
||||
for e in range(s,l):
|
||||
if hiSig:
|
||||
b =0
|
||||
if r[e] > self.hiLev:
|
||||
b = 1
|
||||
i = i<<1 | b
|
||||
hiSig = not hiSig
|
||||
|
||||
return i
|
||||
|
||||
def getPulses(self):
|
||||
""" getPulses implements the commumication protcol for
|
||||
DHT11 and DHT22 type devices. It send a start signal
|
||||
of a specific length and listens and measures the
|
||||
return signal lengths.
|
||||
|
||||
pin is a board pin connected to the data pin of the device
|
||||
|
||||
trigWait is the amount of time to hold the start signal
|
||||
in the low state. This value varies based on the devide type.
|
||||
|
||||
return r (array.array uint16) contains alternating high and low
|
||||
transition times starting with a low transition time. Normally
|
||||
r will have 81 elements for the DHT11/22 type devices.
|
||||
"""
|
||||
r = array.array('H')
|
||||
t = time.monotonic()
|
||||
|
||||
# create the PulseIn object using context manager
|
||||
with pulseio.PulseIn(self.pin,81,True) as pls:
|
||||
|
||||
# The DHT type device use a specialize 1-wire protocol
|
||||
# The microprocess first sends a LOW signal for a
|
||||
# specific length of time. Then the device send back a
|
||||
# series HIGH and LOW signals. The length the signals
|
||||
# determine the device values.
|
||||
pls.pause()
|
||||
pls.clear()
|
||||
pls.resume(self.trigWait)
|
||||
|
||||
# loop until we get the return pulse we need or
|
||||
# time out after 2 seconds
|
||||
while True:
|
||||
if len(pls)>=80:
|
||||
break
|
||||
if time.monotonic()-t > 2.0: # time out after 2 seconds
|
||||
break
|
||||
|
||||
pls.pause()
|
||||
while len(pls)>0:
|
||||
r.append(pls.popleft())
|
||||
pls.resume()
|
||||
|
||||
return r
|
||||
|
||||
def measure(self):
|
||||
""" measure runs the communications to the DHT11/22 type device.
|
||||
if successful, the class properties tempature and humidity will
|
||||
return the reading returned from the device.
|
||||
|
||||
Returns an integer. ==0 for successful, ==-1 for checksum failure
|
||||
(try again), ==-2 for insuffcient data return from the device (try
|
||||
again)
|
||||
"""
|
||||
success = None
|
||||
|
||||
r = self.getPulses()
|
||||
##print(r)
|
||||
|
||||
if len(r)>=80:
|
||||
bits = array.array('B')
|
||||
for b in range(0,80,16):
|
||||
bits.append(self.plsToBinary(r,b,b+16))
|
||||
#print(bits)
|
||||
|
||||
# humidity 16 bits
|
||||
hum = 0
|
||||
if self.dht11:
|
||||
self.hum = bits[0]
|
||||
else:
|
||||
self.hum = ((bits[0]<<8) | bits[1]) / 10
|
||||
|
||||
# tempature 16 bits
|
||||
self.temp = 0
|
||||
if self.dht11:
|
||||
self.temp = bits[2]
|
||||
else:
|
||||
self.temp = ((bits[2]<<8) | bits[3]) / 10
|
||||
|
||||
# calc checksum
|
||||
ckSum = 0
|
||||
for b in bits[0:4]:
|
||||
ckSum += b
|
||||
|
||||
if ckSum & 0xff == bits[4]:
|
||||
#checksum matches
|
||||
# report temp and humidity
|
||||
success = 0
|
||||
#print("Temp: {} C Humidity: {}% ".format(temp, hum))
|
||||
|
||||
else:
|
||||
success = -1
|
||||
#print("checksum did not match. Temp: {} Hum: {} Checksum:{}".format(temp,hum,bits[4]))
|
||||
|
||||
else:
|
||||
success = -2
|
||||
#print("did not get a full return. number returned was: {}".format(len(r)))
|
||||
|
||||
return success
|
||||
|
||||
@property
|
||||
def temperature(self):
|
||||
return self.temp
|
||||
|
||||
@property
|
||||
def humidity(self):
|
||||
return self.hum
|
||||
|
||||
class DHT11(dht_base):
|
||||
""" Support for DHT11 device.
|
||||
|
||||
:param ~board.Pin pin: digital pin used for communication
|
||||
"""
|
||||
def __init__(self, pin):
|
||||
super().__init__(True, pin, 18000)
|
||||
|
||||
|
||||
class DHT22(dht_base):
|
||||
""" Support for DHT22 device.
|
||||
|
||||
:param ~board.Pin pin: digital pin used for communication
|
||||
"""
|
||||
def __init__(self, pin):
|
||||
super().__init__(False, pin, 1000)
|
||||
5
api.rst
Normal file
5
api.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
.. If you created a package, create one automodule per module in the package.
|
||||
|
||||
.. automodule:: adafruit_dhtlib
|
||||
:members:
|
||||
142
conf.py
Normal file
142
conf.py
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),'BusDevice': ('https://circuitpython.readthedocs.io/projects/bus_device/en/latest/', None),'Register': ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None),'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)}
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'README'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Adafruit DHTLIB Library'
|
||||
copyright = u'2017 Mike McWethy'
|
||||
author = u'Mike McWethy'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = u'1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'1.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#
|
||||
default_role = "any"
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#
|
||||
add_function_parentheses = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
try:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
||||
except:
|
||||
html_theme = 'default'
|
||||
html_theme_path = ['.']
|
||||
else:
|
||||
html_theme_path = ['.']
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'AdafruitDHTLIBLibrarydoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'AdafruitDHTLIBLibrary.tex', u'Adafruit DHTLIB Library Documentation',
|
||||
author, 'manual'),
|
||||
]
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'adafruitDHTLIBlibrary', u'Adafruit DHTLIB Library Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'AdafruitDHTLIBLibrary', u'Adafruit DHTLIB Library Documentation',
|
||||
author, 'AdafruitDHTLIBLibrary', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
46
example.py
Normal file
46
example.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
|
||||
|
||||
# example of reading temperate and humidity from a DHT device
|
||||
# and displaying results to the serial port and a 8 digit 7-segment display
|
||||
import time
|
||||
import dht
|
||||
from board import D2
|
||||
|
||||
from adafruit_max7219 import bcddigits
|
||||
from board import TX, RX, A2
|
||||
import busio
|
||||
import digitalio
|
||||
|
||||
clk = RX
|
||||
din = TX
|
||||
cs = digitalio.DigitalInOut(A2)
|
||||
spi = busio.SPI(clk, MOSI=din)
|
||||
display = bcddigits.BCDDigits(spi, cs, nDigits=8)
|
||||
display.brightness(5)
|
||||
print(D2)
|
||||
device = dht.DHT22(D2)
|
||||
|
||||
while True:
|
||||
success = device.measure()
|
||||
|
||||
if success == 0:
|
||||
print("Temp: {:.1f} F Humidity: {}% ".format(device.temperature*9/5+32, device.humidity))
|
||||
display.clear_all()
|
||||
display.show_str(0,'{:5.1f}{:5.1f}'.format(device.temperature*9/5+32,device.humidity))
|
||||
display.show()
|
||||
elif success == -1:
|
||||
print("The data checksum did not validate. Try again.")
|
||||
elif success == -2:
|
||||
print("The device did not return enough data. Try again.")
|
||||
else:
|
||||
print("Something else bad happened: Error {}".format(success))
|
||||
|
||||
if success == 0:
|
||||
time.sleep(2.0)
|
||||
else:
|
||||
time.sleep(0.4)
|
||||
|
||||
|
||||
|
||||
|
||||
2
readthedocs.yml
Normal file
2
readthedocs.yml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
requirements_file: requirements.txt
|
||||
|
||||
0
requirements.txt
Normal file
0
requirements.txt
Normal file
Loading…
Reference in a new issue