diff --git a/adafruit_dht.py b/adafruit_dht.py index e7e8595..d52d6ed 100644 --- a/adafruit_dht.py +++ b/adafruit_dht.py @@ -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" @@ -101,30 +103,51 @@ 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_micro_sec = int(1000000 * (transitions[i] - transitions[i-1])) + pulses.append(min(pulses_micro_sec, 65535)) return pulses def measure(self): @@ -135,13 +158,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') @@ -176,9 +198,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 diff --git a/examples/dht_simpletest.py b/examples/dht_simpletest.py index 4686c4d..e07c078 100644 --- a/examples/dht_simpletest.py +++ b/examples/dht_simpletest.py @@ -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) diff --git a/examples/dht_to_led_display.py b/examples/dht_to_led_display.py index 3286f3b..d3cb3a9 100644 --- a/examples/dht_to_led_display.py +++ b/examples/dht_to_led_display.py @@ -35,6 +35,6 @@ display.show() except RuntimeError as error: - print(error.args) + print(error.args[0]) time.sleep(2.0)