@mdma, the first delay in acquire() is an 18ms “blocking” delay followed by a short 40us delay that essentially pulses the DHT22 to “wake up”. Acquire could be written so that it does not block but it would have to be called continuously until it finishes waking the DHT22. The timing of enabling the interrupt after the wakeup event is critical so there is a risk of not calling acquire() often enough and missing the window. So the delay method was the safest.
After that, the timing is entirely dependent on the data since 0’s and 1’s are differentiated by pulse durations. Falling edge to falling edge durations between 60 and 145usec is considered valid, over 100usec is a ‘1’ and under that is a ‘0’. Generally, your timing assumption is correct.
Wouldn’t it be possible to set up a timer interrupt in acquire() - that goes off after 18ms, When that is called, it does what the current code does after the 18ms wait?
@mdma, if sacrificing a timer and the pin functions it affects is a possibility then yes, that could be done. My IntervalTimer library could be modified to do “one shot” timing instead or continuous running. Then you could do a simple state machine to do the 18ms/40us timings with the DHT22 data pin output and pinmode changes.
The IntervalTimer library “allocates” a timer resource from one of the three usable timers. A simpler library that uses a specific timer (eg. TMR2) would make the code a bit smaller.
For the aquireAndWait() call, there is no benefit obviously.
I’m trying to use this library with the spark-cli compile command. Where should idDHT22.cpp/h files go in the source tree? Where did “void dht22_wrapper();” come from? What is the “Cakefile” and can I have some too? but only if there are no nuts…
@ronm, all you need to do is put all the files in the firmware and examples directories in a single directory like "iddht22". Then you can compile the code with the CLI using:
spark cloud compile iddht22 where iddht22 is the name of the directory
If all works as it should, it will return a firmware_xxxx.bin (where xxxx is a unique identifier) file that you can then flash to your core using:
spark cloud flash coreid firmware_xxxx.bin where coreid is the name you gave your core or the core ID
Just curious. Does any one else have issues with the sampling just stopping at random.
When I load the DHT22 example code everything runs smoothly and then the sampling just stops at random.
I could be running for 5 minutes and stop or as long as an hour.
@kropbj, I am running a test that makes the Spark into a Smartthing device reading temperature and humidity. I also print both readings out every 2 seconds. In my case, the core lost its cloud connection and did not get it back. So I will be testing with and without wifi/cloud to see if there are interrupt issues when the CC3000 is active. Stay tuned
UPDATE: With wifi/cloud disabled, the idDHT22 code ran for 12 hrs without any hickups. Now, I am running the code with wifi on ONLY. So far it has been running for 2 hrs. However, during this test, I do not running anything using the wifi so the CC3000 is basically idling. I will add some code to use the CC3000 for the next test (but without cloud connection).
I am trying to use your library (modified to use the DHT11 which the only difference is the decode and less resolution) but I am seeing that the cloud and wifi connection drops and never comes back up after a few seconds of the code running. Well, I say never, it actually goes back to slow pulsing cyan but I can never programme it or receive the UDP data. I am using UDP to send data as a broadcast. This same UDP code is working on my fridge monitor but that uses DS18B20 sensors.
I have to factory reset the core to be able to reprogramme it again.
I’ll try your test with cloud only and np UDP and see if that works.
That’s fantastic to here that your making some progress. I think I’m having similar issues. It seems to loose connectivity and once it reconnects to the cloud the temperature readings stop. I wish I could help more but I’m afraid that my electronic troubleshooting skills are limited. I’m more of a programmer at best.
@kropbj, after a lot of digging and testing around the code, it finally came down to realizing that somehow, the DHT22 locks up and will refuse to output pulses unless it is powered off and on again! I found an rPi user who had the same issue. He said sometimes it would work fine for 200K reads and then lock up.
So the first question is why does it lockup. In my tests I was powering the DHT22 via Vin and no pull-up resistor. I will run the tests again with 3.3v and no pull-up and see if that helps. Then I will try a pull-up. Stay tuned
@kropbj, I have been running the DHT22 at 3.3v without a failure so far. I also added a timeout so I am not stuck waiting for a response from acquire(). I have a two second sampling timer in loop and if I don’t get a response from acquire() after 1sec, I ignore that request. At the next 2sec interval, another request is sent.
I have observer at least one timeout (I turn on an LED at the first timeout) but the DHT22 has not hung and reading continue. Note that I am powering the DHT22 from the Spark 3.3v line and no pull-up resistor is used.
I am using it on 3.3V too but with a pullup. I don’t wait on acquire, I check this in the loop with a timeout. I set some flags when I have read the device so I know when to start a new acquire and then do this 2 seconds later. This way I never wait and it allows my loop to run and do other tasks.
The issue is that I can not get a stable network connection when I am doing this. If I disable the DHT22 code and never call acquire, the system stays connected to the network. Once I start acquire and after about 2-3 reads, the LED starts to flash cyan and then eventually goes to green. It appears to reconnect but it is not properly connected as I can’t reflash it from the IDE.
@v8dave, your approach is why I ported this library to the Spark! Oddly when I do acquireAndWait(), publishing works just fine and I don’t lose the cloud connection. However, the DHT22 seems to stall and stops responding until I power it off and on again. I will try the acquire() only code to see if I get similar results to yours.
The idDHT22 ISR code does not disable interrupts and the ISR service time is 1.5us and 5us, the longest being the assembly of the temperature and humidity values. Looking at the interrupt frequency, they fire at intervals between 70 and 125us (or so) so there is nothing ridiculous there. More digging I guess
What about storing the values received and then setting a flag to indicate that there is an updated reading?
A separate call from the loop to a function to read the temperature would then assemble the reading. This way there is no maths in the interrupt handler.
@v8dave, that is possible and would keep the floating point math out of the ISR which is never a bad thing. The class has two private float numbers (_hum, _temp) which should be of type int16_t and the floating point stuff could be done in the getCelcius(),etc. functions instead. I will definitely test that.
The question still remains as to why the DHT22 stalls. The other question, which I have not tested yet, is why you are losing your cloud connection. Normally that happens when you are not allowing the background task to run at regular intervals.
I’ve modified the code and I now get updates and UDP is working and seems to be a bit more stable but it does still lose connection but not as often as it did before. The issue though is that once is does connect again, the UDP does not work but this may need to be reset after a lost connection.
I removed the floating point calcs out of the code and copied the results to a volatile byte array of 4 bytes. The calcs are then done when you call getCelcius() etc.
I should add that although it works, I am seeing the loop freeze every so often and then eventually the cyan flashing and then green appears. There is nothing in my code that is called in loop that would cause a freeze to happen.
When it eventually starts the loop again, there is no connection as I don’t see any UDP broadcasts now but I am seeing a slow pulsing cyan.
@v8dave, I changed the ISR to only handle integer values and to the float calculations in the get functions as discussed. The ISR service time for the “assembly” portion of the code is now down to 4us.
So that leaves two other items (IMO) that may cause the problem. First, the detachInterrupt() function can be interrupted and I am not sure what that implies. Second, I am not sure what the implication of having any other higher level (system) interrupt will have on the ISR. None of these explain why the DHT22 stalls. Odly, if I disable the cloud connection, I don’t see a stall.