Skip to content

add raspberry pi and other fast-gpio device support when no pulseio #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 57 additions & 33 deletions adafruit_dht.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@

import array
import time
from digitalio import DigitalInOut, Pull, Direction
_USE_PULSEIO = False
try:
import pulseio
except ImportError as excpt:
print("adafruit_dht requires the pulseio library, but it failed to load."+
" Note that CircuitPython does not support pulseio on all boards.")
raise excpt
_USE_PULSEIO = True
except ImportError:
pass # This is OK, we'll try to bitbang it!


__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DHT.git"
Expand Down Expand Up @@ -101,30 +103,50 @@ def _get_pulses(self):
"""
pulses = array.array('H')

# create the PulseIn object using context manager
with pulseio.PulseIn(self._pin, 81, True) as pulse_in:

# The DHT type device use a specialize 1-wire protocol
# The microprocessor first sends a LOW signal for a
# specific length of time. Then the device sends back a
# series HIGH and LOW signals. The length the HIGH signals
# represents the device values.
pulse_in.pause()
pulse_in.clear()
pulse_in.resume(self._trig_wait)

# loop until we get the return pulse we need or
# time out after 1/4 second
tmono = time.monotonic()
while True:
if time.monotonic()-tmono > 0.25: # time out after 1/4 seconds
break

pulse_in.pause()
while pulse_in:
pulses.append(pulse_in.popleft())
pulse_in.resume()

if _USE_PULSEIO:
# create the PulseIn object using context manager
with pulseio.PulseIn(self._pin, 81, True) as pulse_in:

# The DHT type device use a specialize 1-wire protocol
# The microprocessor first sends a LOW signal for a
# specific length of time. Then the device sends back a
# series HIGH and LOW signals. The length the HIGH signals
# represents the device values.
pulse_in.pause()
pulse_in.clear()
pulse_in.resume(self._trig_wait)

# loop until we get the return pulse we need or
# time out after 1/4 second
tmono = time.monotonic()
while time.monotonic() - tmono > 0.25:
pass # time out after 1/4 seconds
pulse_in.pause()
while pulse_in:
pulses.append(pulse_in.popleft())
pulse_in.resume()
else:
with DigitalInOut(self._pin) as dhtpin:
# we will bitbang if no pulsein capability
transitions = []
# Signal by setting pin high, then low, and releasing
dhtpin.direction = Direction.OUTPUT
dhtpin.value = True
time.sleep(0.1)
dhtpin.value = False
time.sleep(0.001)

timestamp = time.monotonic() # take timestamp
dhtval = True # start with dht pin true because its pulled up
dhtpin.direction = Direction.INPUT
dhtpin.pull = Pull.UP
while time.monotonic() - timestamp < 0.1:
if dhtval != dhtpin.value:
dhtval = not dhtval # we toggled
transitions.append(time.monotonic()) # save the timestamp
# convert transtions to microsecond delta pulses:
for i in range(1, len(transitions)):
pulses.append(int(1000000 * (transitions[i] - transitions[i-1])))
return pulses

def measure(self):
Expand All @@ -135,13 +157,12 @@ def measure(self):
Raises RuntimeError exception for checksum failure and for insuffcient
data returned from the device (try again)
"""
delay_between_readings = 0.5
if self._dht11:
delay_between_readings = 1.0
delay_between_readings = 2 # 2 seconds per read according to datasheet
if time.monotonic()-self._last_called > delay_between_readings:
self._last_called = time.monotonic()

pulses = self._get_pulses()
#print(len(pulses), "pulses:", [x for x in pulses])

if len(pulses) >= 80:
buf = array.array('B')
Expand Down Expand Up @@ -176,9 +197,12 @@ def measure(self):
# check sum failed to validate
raise RuntimeError("Checksum did not validate. Try again.")

else:
elif len(pulses) >= 10:
# We got *some* data just not 81 bits
raise RuntimeError("A full buffer was not returned. Try again.")

else:
# Probably a connection issue!
raise RuntimeError("DHT sensor not found, check wiring")
@property
def temperature(self):
""" temperature current reading. It makes sure a reading is available
Expand Down
17 changes: 10 additions & 7 deletions examples/dht_simpletest.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import time
from board import D2
import board
import adafruit_dht

#initial the dht device
dhtDevice = adafruit_dht.DHT22(D2)
# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT22(board.D18)

while True:
try:
# show the values to the serial port
temperature = dhtDevice.temperature * (9 / 5) + 32
# Print the values to the serial port
temperature_c = dhtDevice.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = dhtDevice.humidity
print("Temp: {:.1f} F Humidity: {}% ".format(temperature, humidity))
print("Temp: {:.1f} F / {:.1f} C Humidity: {}% "
.format(temperature_f, temperature_c, humidity))

except RuntimeError as error:
print(error.args)
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])

time.sleep(2.0)
2 changes: 1 addition & 1 deletion examples/dht_to_led_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@
display.show()

except RuntimeError as error:
print(error.args)
print(error.args[0])

time.sleep(2.0)