DHT22Gen3_RK
|
There's been a problem with DHT22 libraries on Gen 3 devices (Argon, Boron, Xenon). Interrupt latency causes it to misinterpret bits for interrupt-based libraries (like PietteTech_DHT) and bit-banging isn't much better. The narrowest pulse is 26-28 us.
I created a new library, DHT22Gen3_RK, that takes an entirely different approach. It uses the nRF52 I2S peripheral not to capture sound data, but as a DMA-based digital signal sampler. It can grab a full DHT22 sample into a 360 byte buffer at a 512 kHz sampling rate. It doesn't require any interrupts, no timers are required, and it's completely non-blocking. It doesn't have to disable interrupts or thread swapping.
I ran a test overnight and captured 14,703 samples every 2.5 seconds with no checksum errors. The library will retry on error, but didn't have to at all.
It can sample multiple sensors (sequentially, not at the same time), one per GPIO pin. There one annoying caveat: You need to allocate two spare GPIO pins. The I2S peripheral requires that you expose SCK and LRCK on physical GPIO pins or it doesn't work. These signals are of no use for capturing DHT22 samples, but they still need to be allocated. Most people have a few GPIO left, so hopefully that's OK.
The API is callback/lambda based, as it takes about 24 milliseconds to query a DHT22. The callback allows the loop to flow freely during this time, but the callback is dispatched from the loop context so you can still do things like Particle.publish from the callback. The callback is particularly helpful if a retry is required because of a bad checksum. Since the DHT22 can only be queried every 2 seconds, retries take a long time.
The getSample()
method can also take a C++11 lambda, which is handy for calling member functions or implementing the method inline:
Include the DHT22Gen3_RK
library and include its header file:
Add a global variable. There should only be one instance of this object, and it should be in a global scope.
The two parameters are unused GPIO pins. These can be A pins, D pins, even unused special port pins that you are not otherwise using (TX, RX, SCK, MISO, MOSI). They do need to be valid pins, however, and not the same pin. The output will be 512 kHz signal on the first pin and a 32 kHz signal on the second. You shouldn't connect anything to these pins. They're necessary because the I2S peripheral that's used to decode the DHT22 signal requires the pins.
From setup()
call dht.setup()
:
From loop()
call dht.loop()
:
You should call dht.loop() on every loop call even if you are not currently sampling data. It uses very little processor time when not active.
Use the dht.getSample()
method above to query the sensor. It will take 24 milliseconds normally, but could take up to 9 seconds to get a result.