Yes, I’m still on the electronics kick. This is something I’ve been wanting to do as part of a complete home automation project down the road: monitor the temperature of the different rooms / zones in my house. Now that I’ve got a few Arduinos laying around and some thermal probes (thermistors) from some broken Radio Shack temperature displays, I’ve got the hardware necessary to make it happen! I first installed the thermal probes in the ceilings of the master bedroom, my daughter’s bedroom and our living room in locations that I thought were least affected by vents, fans, lights and other sources of heat. Here’s a picture of the probe in my living room:

Next, I connected the three probes to my Arduino’s Analog Inputs using the thermistors as voltage dividers between +5VDC and Ground.  In order to detect the temperatures and make them accessible via the Arduino’s serial interface, I used a few examples on the Arduino site as the basis for this program, which waits for a character to be sent to the serial port, then outputs the temperatures:

#include <math.h>
//Schematic:
// [Ground] ---- [10k-Resister] -------|------- [Thermistor] ---- [+5v]
//                                     |
//                                Analog Pin 0

double Thermistor(int RawADC) {
// Inputs ADC Value from Thermistor and outputs Temperature in Celsius
//  requires: include <math.h>
// Utilizes the Steinhart-Hart Thermistor Equation:
//    Temperature in Kelvin = 1 / {A + B[ln(R)] + C[ln(R)]^3}
//    where A = 0.001129148, B = 0.000234125 and C = 8.76741E-08
long Resistance;  double Temp;
Resistance=((10240000/RawADC) - 10000);
Temp = log(Resistance);
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
// Convert Kelvin to Celsius
Temp = Temp - 273.15;
// Convert to Fahrenheit
Temp = (Temp * 9.0)/ 5.0 + 32.0;
return Temp;
}

void printDouble(double val, byte precision) {
Serial.print (int(val));  //prints the int part
if( precision > 0) {
Serial.print("."); // print the decimal point
unsigned long frac, mult = 1;
byte padding = precision -1;
while(precision--) mult *=10;
if(val >= 0) frac = (val - int(val)) * mult; else frac = (int(val) - val) * mult;
unsigned long frac1 = frac;
while(frac1 /= 10) padding--;
while(padding--) Serial.print("0");
Serial.print(frac,DEC) ;
}
}

void setup() {
Serial.begin(115200);
}

#define ZoneOne 1   // Analog Pin 0
#define ZoneTwo 2   // Analog Pin 1
#define ZoneThree 3   // Analog Pin 2

double temp;
int inByte = 0;
int sensorDelay = 10;

void loop() {
if (Serial.available() > 0) {
inByte = Serial.read();
Serial.print("Zone1:");
printDouble(Thermistor(analogRead(ZoneOne)),3);
Serial.print(" ");
delay(sensorDelay);
Serial.print("Zone2:");
printDouble(Thermistor(analogRead(ZoneTwo)),3);
Serial.print(" ");
delay(sensorDelay);
Serial.print("Zone3:");
printDouble(Thermistor(analogRead(ZoneThree)),3);
Serial.print(" ");

Serial.println("");
}
}

I had an old laptop with a dead battery that I wasn’t using, so I loaded it with Ubuntu 10.10 x64, Apache, MySQL, PHP and Cacti and put it up in the attic, connected to the Arduino via USB.  I went through the painfully dry Cacti Documentation and wrote a custom Perl script that Cacti uses to poll the Arduino for temperatures:

#!/usr/bin/perl

use Device::SerialPort;
use Time::HiRes qw( usleep );

# Serial Settings
\$PORT = "/dev/ttyUSB0";
\$ob = Device::SerialPort->new (\$PORT) || die "Can't Open \$PORT: \$!";
\$ob->baudrate(115200)   || die "failed setting baudrate";
\$ob->parity("none")    || die "failed setting parity";
\$ob->databits(8)       || die "failed setting databits";
\$ob->handshake("none") || die "failed setting handshake";
\$ob->write_settings    || die "no settings";
\$ob->read_const_time(50);

while(1){
\$ob->write("x");
if(\$_ = \$ob->read(255)){
chomp;
print "\$_\n";
undef \$ob;
exit;
}
usleep(1000 * 10);
}

undef \$ob;

Lastly, I put a nice graph together that shows a comparison of the three temperatures over time, with a composite average of all three.  Now I can see that my daughter’s room spikes to nearly 90 deg when the heat comes on – ouch!  Using this data I am better able to adjust the vents in each room to keep the temperature consistent throughout the house.  Next I want to take one of those cheap LCD picture displays and tie it to the Cacti graph and put it near the thermostat so I can think twice about turning on the heat or AC!