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:
//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:
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!
« Arduino Parking Assistant Understanding a Mouse Scroll Wheel »




this is awesome!
Thanks! I’m working on version 2 right now
Did you ever release any code or schematics for the Arduino thermostat you mention in this post on the Arduino forums?
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293587840
I am very interested in building a thermostat like this plus some wireless temperature sensors.
I never released any code because I never noticed the replies on the forum
I’ve just opened up a GitHub repo for the code here: https://github.com/kamermans/Arduino-Thermostat
The Thermostat_V3 is a fully operational thermostat that is running my Heat/AC in my house. It has three thermisters for input, a 4-line Backlight auto-dimmed LCD for the user interface, four buttons to navigate menus up/down and make selections and three relays to control Heat, AC and Fan.
Can you try contact the other people that were interested and point them to my repo?
Thanks!
Here’s the new thread I just started at the new Arduino forum: http://arduino.cc/forum/index.php/topic,67423.0.html
Wow, that was fast!!! Thanks for posting the code! More in the forum.
Do you have a pair of wires from each thermistor coming all the way back to the Arduino?
I have one GND wire running up to my attic, and one signal wire for each thermister for a total of four wires. In the attic I split the GND for each of the thermisters and added pulldown resistors to get the signal to a good range. I was considering putting an analog IC in the attic to collect the data from the thermistors and a digital signal from the analog IC to the Arduino, but after some bad experiences with the serial data loss over 10+ feet from the Arduino, I opted for the thermistors. It should be noted that the thermistors I used came with 20 foot leads, so the loss/interference was probably mitigated by those wires. Also, even though two-wire serial only needs two wires for signalling, you’ll need a GND and Vcc reference at the other end, so you’ll still end up with 4 wires also. I used a single Cat-5E Ethernet cable that I had lying around for the Thermister < -> Arduino run.
Actually, my response doesn’t make much sense – I just moved so I don’t have this setup right now. I must have had Vcc in the attic since that’s what the analog input will measure, not GND.
Hi Steve,
I found your site and is very very helpfull and your software is awsome and it’s just the thing I needed (I am at my first arduino and have very few experience with programming). I would also like to ask you, if you can, to give me a hint how you configured the graphs in cacti becouse all I get from the log is the output: U partial result. I am on cacti 0.8.7g, last version in ubuntu. In the shell everithing works just fine. Tried combinations with spaces and new lines but it’s not helping.