On Tue, 18 Aug 2020 14:29:43 -0700 (PDT), in gmane.comp.hardware.beagleboard.user Ren W <rwaldura-re5jqeeqqe8avxtiumw...@public.gmane.org> wrote:
> >AdaFruit sells such a thing (AM2302 <https://www.adafruit.com/product/393>), >but the protocol looks iffy (I'm using Bonescript, not Python). SparkFun >has a bunch of options also, but they all look like "internal" sensors, >i.e. not meant for exposure. >I've seen other projects go with an all-in-one weather sensor kit sold by >Davis; it looks like a bit much. And rather pricey. > >I'm curious to hear what other enthusiasts use... Thanks! Pretty much ANY sensors will need you to provide a suitable housing (even that AM2302 is not warded against splashes. You want a white housing (white to reflect sunlight) with downward slanting louvers on all sides for air-flow, but which will block rain splatters from the stuff on the inside (obviously a rain gauge will be outside -- most of them work on a trip system that counts each time a bucket exceeds some mass and empties). You likely won't want to run all that many wires either -- especially if each sensor is using a different protocol*. I really think what I'd do is obtain an Arduino (or Adafruit Circuit Python Metro card), as both are microcontrollers capable of strict timing tasks. Wire all sensors to this card, and use a simple program that just loops reading each sensor, and then formatting the data into a simple string that could be sent over a serial port. The Arduino/Metro would be mounted in the top of the sensor housing, and would require a source of power, and a (long run) serial line (due to length, one might want to run a slow baud rate to reduce line noise effects). Four wires: 5V, GND, Tx, Rx. (Actually, if you have the unit continuously sending data, and have not command mode, you could drop one of the serial lines). * The protocol used by DHT-type sensors is rather timing critical. I'm pretty sure Python will not keep up on its own, and suspect Bonescript will have the same problem. I vaguely recall once trying to code a bit-banged version in C, and I'm not certain I was able to get reliable readings on a BBB -- the OS overhead and process swapping got in the way. You could write something that runs on a PRU to get reliable timing. The basic/simplest reading process consists of sending the START signal, then timing (simple loop counting loop cycles) the first signal transition from the DHT. This gives you the timing baseline, late 1s and 0s tend to be longer or shorter than the baseline (check spec sheet). Each bit transition needs to be counted/timed. After you've obtained the timing for all bits you can make the determination of 1 or 0, package them into bytes, and return them as a value. If one has access to a system clock, it does remove the need to count loop cycles. I can't locate my C attempt; my Python attempt -- which as I recall wasn't fast enough -- years ago, was: -=-=-=- """ DHT11.py Simple Humidity and Temperature Sensor April 2, 2016 Dennis L Bieber This file defines a class to read DHT11 sensors using the Adafruit_BBIO library. Minimal error checking is performed, timeout testing is performed as CPU-hog polling loops are being used to detect transitions (the Adafruit_BBIO wait_for_edge() block indefinitely and seemed to be hanging on some calls) NOTE: time.clock() appears to have a very coarse resolution, so timeouts need be significant """ import Adafruit_BBIO.GPIO as IO import time class DHTError(Exception): def __init__(self, value): self.value = value def __str__(self): return "DHT Sensor Error: %s" % value class DHT11(object): def __init__(self, pinStr, timeout=1.0): self._pinStr = pinStr self._timeout = timeout def readC(self): # return humidity and degC # spec sheet recommends reading twice as the first # might return stale data (h, t) = self._read() return self._read() def readF(self): # return humidity and degF (h, t) = self.readC() return (h, (t * 9.0) / 5.0 + 32.0) def _read(self): time.sleep(2.0) #to ensure device cycles # prepare receive buffer data = [0, 0, 0, 0, 0] # wait, if needed, for bus to go high # (if it is low, some device has it) # this is the only timeout check implemented ts = time.clock() IO.setup(self._pinStr, IO.IN) while not IO.input(self._pinStr): if (time.clock() - ts) > self._timeout: raise DHTError("Timeout waiting for bus available") # send wake-up signal; spec is minimum 18msec IO.setup(self._pinStr, IO.OUT) IO.output(self._pinStr, IO.LOW) time.sleep(0.020) IO.output(self._pinStr, IO.HIGH) IO.setup(self._pinStr, IO.IN) # wait for start of response ts = time.clock() while IO.input(self._pinStr): if (time.clock() - ts) > self._timeout: raise DHTError("Timeout waiting for start of response") # wait for return to high ts = time.clock() while not IO.input(self._pinStr): if (time.clock() - ts) > self._timeout: raise DHTError("Timeout waiting for end of response") # wait for start of bit indicator ts = time.clock() while IO.input(self._pinStr): if (time.clock() - ts) > self._timeout: raise DHTError("Timeout waiting for start of bit indicator") # loop over the data bytes for (i, d) in enumerate(data): # get 8 bits per byte for b in range(8): # wait for bit itself ts = time.clock() while not IO.input(self._pinStr): if (time.clock() - ts) > self._timeout: raise DHTError("Timeout waiting for start of bit") # capture time time tbit = time.clock() # wait for end of bit (start of next) ts = time.clock() while IO.input(self._pinStr): if (time.clock() - ts) > self._timeout: raise DHTError("Timeout waiting for end of bit") # determine duration dur = time.clock() - tbit if dur > 0.000045: d = (d << 1) + 1 else: d = (d << 1) #+ 0 data[i] = d # checksum validation, and conversion to floating point if sum(data[:3]) % 256 != data[4]: raise DHTError("Checksum Mismatch") # good checksum, convert values humidity = data[0] + (data[1] / 10.0) temperature = data[2] + (data[3] / 10.0) return (humidity, temperature) def closeIO(): IO.cleanup() if __name__ == "__main__": mySensor = DHT11("P8_15") # GPIO 48 try: while True: (h, t) = mySensor.readF() print("Humidity: %s \%\tTemperature: %s degF\n" % (h, t)) time.sleep(5.0) except KeyboardInterrupt: closeIO() except: # nasty naked except closeIO() raise # but we reraise the exception -=-=-=- I don't know if using Adafruit_blinka and a CircuitPython library to read a DHT sensor might be feasible. I should maybe see what's now available and try. -- Dennis L Bieber -- For more options, visit http://beagleboard.org/discuss --- You received this message because you are subscribed to the Google Groups "BeagleBoard" group. To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/dvgqjfl3mkj8g0hmi2m6c3ac2dogeo5036%404ax.com.