Great advice! 
Thank you, Dennis.

On Wednesday, August 19, 2020 at 9:11:16 AM UTC-7 Dennis Bieber wrote:

> On Tue, 18 Aug 2020 14:29:43 -0700 (PDT), in
> gmane.comp.hardware.beagleboard.user Ren W
> <[email protected]> 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/beagleboard/199175ee-2942-41eb-84b7-b785000f9db4n%40googlegroups.com.

Reply via email to