Monday, March 2, 2015

Electric imp temperature sensors

After experiencing many burst pipes (in our baseboard heaters) I decided to build some temperature sensors.  My friend Phil recommended using the electric imp microcontroller and quickly found a tutorial on how to use it to make a temperature sensor:   https://plot.ly/electric-imp/tmp36-temperature-tutorial/

In the above the general concept & required components are spot on, but some of the specifics / details are off.  Here's what I did, which is the same in outline but differs in some specifics (which I hope are accurate).

Parts:
Bought electric imps, electric imp breakout boards, tmp36 temperature sensors, bread boards, wire jumpers from sparkfun.

Digression / background:  the electric imp communicates via wifi mainly (only?) and you configure it to use your wifi network using a "blinkup".  You install the electric imp blinkup app on your phone, and then when you're ready, you hold the powered on electric imp against the screen of your phone, which then blinks wildly.  The blinks encode the wifi connection info (SSID, password, encryption system in use, etc.), and an optical sensor in the imp measures the series of on off bits, and then the electric imp attempts to connect.

Attached a jumper / wire across ports to cause the breakout board use the mini-USB port as the power source (see the image below, the blue-insulated wire is the jumper).  Plugged the electric imp into the breakout board and plugged in the USB power, and the electric imp began to blink red.  Attempted to run blinkup to connect electric imp to wifi network several times, varying conditions, did not work.  Eventually changed SSID of network to remove dash from name, then the blinkup work.

Ran basic "hello world" program on electric imp via IDE.
server.log("hello world!");
On the breadboard, plug in the tmp36 chip.  The spec sheet has a diagram indicating the pin layout from below:
Used jumpers to make these connections between the tmp36 chip and the electric imp breakout board:

  • tmp36 pin 1 to breakout 3V3
  • tmp36 pin 2 to breakout pin 9
  • tmp36 pin 3 to breakout GND
Used this code
server.log("Hello from the device!")
// initialize pins
local tmp36 = hardware.pin9;
tmp36.configure(ANALOG_IN);
function takeReadings() {
   local hw = hardware.voltage();
   local r = tmp36.read();
   local t = time()
   server.log(hw);
   server.log(r);
   server.log(t);
   imp.wakeup(2, takeReadings);
}
takeReadings();
The line "local r = tmp36.read();" makes the measurement of the voltage output from the tmp36 temperature sensing microchip.  It reports an integer from 0 to 65536 (2 to 16th power) which is proportional to the measured voltage.  The analog to digital converters (ADC) in the electric  imp are 16 bit ... in grad school we had a circuit board that was as long as my laptop is wide to do the same thing...

The spec sheet for the tmp36 sensor indicates that the temperature is linearly related to the output voltage, and the integer reading that the electric imp makes is linearly proportional to the output voltage, therefore the integer reading is linearly proportional to the temperature.

I was immediately able to observe readings from the above, but they seemed very noisy, and when I tested it by applying a hot air gun (OK, my wife's hair dryer on the hottest setting), there was no change in the read variable r.  I discovered that the jumpers between the pins in the electric imp breakout board were not well connected, after securing these, the reads were much less noisy and the hair dryer test worked - applying the hot air caused the numbers to increase immediately and substantially.

After getting the above to work in the breakout board, plugged the pins of the tmp36 sensor directly into the correct pins of the electric imp breakout board and soldered them into place:



I extended the code to send data to electric imp agent, then send that on to a service:
https://github.com/dllahr/home_control/tree/eimp_blog_posts/electric_imp/temperature_sensing

The basic idea is that the electric imp makes a temperature measurement once per second, and every minute sends the raw data to the server.  The server calculates the average over those measurements and logs them immediately (in case anything downstream goes wrong, at least this log can be consulted), and then sends the data on to a server.

Setup nginx and node on a raspberry pi to host that service and receive the data.  A future post will detail those adventures.

Placed against baseboard heater water pipe in garage to monitor what is potentially the coldest location:


Note that the hole in the ceiling was cut previously by plumbers repairing a burst pipe, hence the available access location and knowledge that it gets cold there.

Here's a plot of the measured data, with the read integers converted into temperature in degrees Farenheit on the y-axis, and the x-axis time in seconds:


Not the gaps in the data - this is where an error in my hosted service caused it to stop recording the data.

Also notice points below -15 F (and close to -65 F), and a few above 185 F.  I'm guessing the low points are from spurious reads of 0.  I'd like to check the hardware and soldering connections to reduce the noise.  Also it should be possible to make many more measurements per second and possibly reject outliers (e.g. 0 reads) at the device level, but I kind of like to keep them in to remind me of the "real" nature of the data.  In the future when I want to add an automatic alert system, I will need to filter them out.

Here's a zoomed in version of the above:

It is interesting to note the occasional, longer decay curves.  I investigated the first one and found that it coincided with the warmest part of the day (in this case, it got up to around 32 F outside), which probably caused the room where the thermostat was located to stay warm quite a bit longer and hence the heat did not come on for a much longer period of time, causing the temperature of the heating pipe to decrease for a longer period of time - and reach a colder temperature.

1 comment:

  1. This comment has been removed by a blog administrator.

    ReplyDelete