In my previous post, I took a look at how to wire up a Spark Core with a very simple analog temperature sensor. I decided to try and upgrade this to use a new sensor, a DHT22, which provides both analog temperature and analog humidity. It does this over the same pin, so reading the values is not only annoying, but it’s so ugly that I had to go searching for someone’s DHT Spark library.

Here’s a look at my prototype wiring:

Spark Core with DHT22 Temperature and Humidity Sensor

Spark Core with DHT22 Temperature and Humidity Sensor

What’s going on here is I’m running the 3.3v power to the far left pin (as you’re facing it) of the DHT22. I run the analog input wire from the second leg to the D2 pin of the Spark Core, and also use a 10k resistor between that pin’s wire and power. This is yet another example of where I have no idea why something works, but there is a magical special sauce recipe here at play. I don’t know why I need that 10k resistor where it is, but I do. Without it, the value of the temp and humidity alternates between 0 and 99999. I think that because of the fact that reading values from the sensor is timing based, you can screw up the timing if the voltage isn’t crisp, clean, and at a specific value. In other words, noisy or excess voltage messes up the timing, which messes up the reading of the sensor values.

I liken this to someone sending the temperature value at night with a flashlight using morse code…except that the recipient blinks at exactly the same time as the sender turns on the flashlight… making it seem like nothing is being transmitted.

In my opinion, this is asinine. The way the code works is it sets the analog pin high, then waits 250ms. It then performs a series of reads on that same pin, spaced by microseconds, pulling a single byte at a time, with a microsecond delay between reads of bytes. This just feels like too much busywork, but my perspective is from years of using high-level software libraries, not low-level hardware. Maybe Arduino folks are used to this kind of thing, but for me, this is 2015, and even cheapass $2 sensors should be able to emit analog results without being so sensitive to timing issues. Of course, since no one has been able to explain why this wiring works the way it does, this is pure conjecture.

Anyway, I then set up two Spark cloud variables so that I can query the value of my sensor remotely from anywhere in the world (provided I have Internet access on said remote, bond-villain island):

Spark.variable("temperature", &t, DOUBLE);
Spark.variable("humidity", &h, DOUBLE);

With these variables in place, I just update them about every second or so inside my loop() function. Also anecdotally, I discovered that you can’t really access the value faster than once per second, because that can also cause problems. And with everything else I’ve found related to this – nobody can seem to agree on the proper wiring or proper code for interfacing with this, nor can people agree on how fast you should access the value. There’s nothing I dislike more than crap that works, but nobody knows why or how it works. Magic bothers me.

While debugging this code, I encountered a number of variants in both wiring and code that resulted in either non-existent or erroneous measurement values. To debug it, I used the Spark core’s serial functions, which allow me to print out values to the “serial port”. The serial port, in this case, is a virtual com port that is created when a Spark Core (that has firmware on it that calls Serial.begin(baudrate)) is plugged into a USB host. If your Spark Core firmware never invokes Serial.begin, then this virtual COM port will not be created when the device is plugged into your computer’s USB port.

In my case, since I’m on a mac, plugging this Spark into my USB created a virtual com port at /dev/tty.usb(stuff) where (stuff) will vary depending on your system, so just look at your directory for tty.usb*.

To watch the output being sent from the Spark on this serial line (on a Mac), just issue this command at the terminal prompt:

screen /dev/tty.usb(Stuff) 9600

Now you can watch the trace/debug output from your core. I’ve found this particular troubleshooting method to be invaluable.