This project is kind of re-inventing the wheel and cost more to build than to buy something similar. But the whole point is to have a little fun building something yourself, gaining experience from it and getting exactly the features you want.
I used to live in upstate NY where the winters were sometimes quite bitter. I am quite hot-blooded and for the most part don’t mind the cold. I would turn the heat down pretty low during the night while I slept as well as during the day while I was at work. Waking up and taking a shower in a frosty house after spending all night nice and toasty beneath the blankets was not something I looked forward to. Likewise coming home to a cold house after being in a warm car on the way home was also a bit uncomfortable. The problem is that it takes some time to get the temperature from one extreme to the other.
The answer is a simple Programmable Thermostat. I could pick one of these units up from Walmart for probably $20.00 or so, depending on the features, but why buy one when I can build my own? This way I get the features I want and the satisfaction of having done it myself. Plus, I can package and control it as I see fit.
Custom Design Time
I always like to build things myself when I can. The main reason is customization. The units I have seen at Walmart have fixed schedules. They have a limited number of on / off times usually grouped into weekday / weekend schedules. To be honest I looked and couldn’t find anything that did exactly what I needed.
What I need to build this thing is a controller for the brains of the unit. A BASIC Stamp 2 is more than sufficient for this task. I’ll also need a display. I’m thinking 4×20 LCD with backlight. I need to be able to display current temperature, set temperature, date, time and some other information such as status and mode. Three buttons for input should be fine. Any standard normally open push-buttons will do.
I’m also going to need something to sense the temperature. For that job I’ll use the DS1620 Digital Thermometer. This device can measure the temperature in units of .5° Centigrade (C) from -55°C to +125°C, and -67°F to +257°F in units of .9° (F). The DS1620 also interfaces quite easily to the BS2, making it a great choice.
Since the Programmable Thermostat needs to know the day / time for my purposes, I’ll also need a clock chip of some type. The DS1302 will work nicely for this task as it too interfaces easily to the BS2 and does not require a lot of effort to use. It will also provide me with some battery-backed RAM to store settings into.
The last component I’ll need is the interface between the thermostat and the furnace. In a typical thermostat (like the one above) there is a mercury switch mounted to a bi-metallic coil. When the coil contracts past the level point you set the mercury switch closes. As the temp rises, the coil expands and tips the mercury switch the other way, opening it. This switch is typically running 24 VAC through it. In my system these are the only two wires that must be connected to the controller, so I will use a relay to switch them. A standard +5 VDC DIP relay will be more than adequate to handle this task.
For prototyping purposes I’ll be assembling most of this on the iNEX NX-1000 development board. There will be two chips mounted on the breadboard area. Since I already have the DS1302 connected on the NX-1000 and already have some existing code, I will leave it connected. The Data I/O line (Pin 6) is connected to P0 through a 1K resistor, the Clock line (Pin 7) is connected to P1 and the Reset line (Pin 5) is connected to P2. VCC2 (Pin 1) is connected to +5 VDC and GND (Pin 4) is connected to Ground on the NX-1000. The 32.768 kHz Crystal is connected to the DS1302’s pins 2 and 3. VCC1 (Pin 8) is connected to a 3 Volt battery pack, which will serve as a battery backup for the clock if the main power should fail.
Next I’ll add the DS1620 and connect it. I’ll reserve the next 3 available ports on the BS2 for this device. The DS1620’s DQ line (Pin 1) is connected to P3 through a 1K resistor. The Clock line (Pin 2) is tied to P4 and the Reset line (Pin 3) is tied to P5. The VDD line (Pin 8) is tied to +5 VDC and the Ground line (Pin 4) is tied to the NX-1000 Ground.
For simplicity, I’ll connect the LCD through a serial interface chip. In this case, Dale Wheat’s PIC-an-LCD, since I am very familiar with it and it’s capabilities. The PIC-an-LCD will require a handful of discrete components, such as a crystal, resistor (for RESET pull-up), and finally a .1 μF capacitor for the power supply leads. The serial in line (Pin 6) is tied to P6.
In this project I’m also going to have control of the LCD backlight. For this task I’ll be tying the backlight (+) lead to VCC. The backlight (-) lead will pass through a resistor to the collector of a 2N3904 NPN transistor (or equivalent). The emitter will be tied to ground, and the base will be tied to P7 through a 1K resistor.
The last section of the prototype I need to assemble is the relay control section, which is what will turn my furnace on and off. This is a simple circuit consisting of a relay, diode, transistor and resistor. One side of the relay coil will connect to VCC, and the other will connect to the collector of a 2N3904 transistor (or equivalent). Once again, the emitter will connect to ground. The base will connect to P7 through a 1K resistor. To protect the transistor from transients produced by the relay coil when it de-energizes, I’ll place a diode in reverse bias across the relay coil. That is, I will connect the cathode of the diode to the side of the coil that connects to VCC, and the anode of the diode to the side of the coil that connects to the transistor’s collector. This will clamp any back EMF from the relay when it is turned off.
Here is a photo of the Prototype assembled on the NX-1000 board. Notice the Duracell batteries which are the backup for the DS1302. Also on this prototype I am cheating and using a pre-assembled LCD platform, where in the final unit I’ll be using discrete parts. But the code will be the same, since it is based on the PIC-an-LCD.
In the first photo above the LCD is showing the furnace to be OFF based on the current temperature. The Threshold (which is adjustable) is currently set at 3 degrees. This means that the temperature must fall 3 degrees below the Set Temp to turn the furnace on. The Set Temp is at 80 degrees, but the current temperature is 78 degrees, so no need to turn on the furnace.
The second photo of the LCD shows the furnace to be ON based on the current temperature. The Set Temp is at 80 degrees, and the current temperature is 75 degrees, so the furnace will be turned on. Notice the Mode currently reads “MAN.” This means the thermostat is in MANUAL Mode, instead of PROGRAM Mode. Some digital thermostats have a “HOLD” feature to temporarily disable the current program. On this one you just switch to MANUAL Mode and the thermostat ignores programming.
Understanding The Code
As for the programming, you should start by familiarizing yourself with the 2 main chips used in this project, the DS1302 and the DS1620. A great way to learn about interfacing these chips to the BS2 is through Parallax’s StampWorks kit. If you cannot afford the whole kit or you have much of what’s in it, then I’d still recommend downloading the StampWorks Manual, just for the sheer amount of information it contains. It covers a lot!
With the DS1302 keeping track of the time and the DS1620 set to keep checking the temperature, all I need to do is read each device and decide what to do based on this information. Obviously the main thing I want to do is turn on the furnace when it gets colder than I have the temperature set to. But the other function will be to have preset programs that can set the temperature to different levels automatically. I have mulled over several ways to do this, and in the end I have decided to hard-code the the event into a subroutine called, Get_Program.
The entire Main section of the program is nothing more than a series of GOSUB statements to subroutines which handle each of the important tasks; Get_Time, Show_Time, Get_Temp, Show_Temp, etc (see source code). Each subroutine does it part, then the program jumps to the next, looping back to the first one after the last has been completed.
The only thing left to do at this point is make a few code updates, as well as find a suitable enclosure. Note that I could have shared some of the I/O pins on the DS1302 and DS1620 since they’re both SPI devices, however I had plenty of free I/O pins and no need to do so in this project. In later projects I will start doing this by default. I also failed to define the button inputs as pin declarations at the beginning of the code. As this was one of my first BASIC Stamp 2 projects, I hadn’t yet polished my coding style yet on this platform.
This project never made it into a final enclosure since I moved to CA and no longer needed it. However the prototype did work at my computer shop for two weeks of testing. I am providing the code as it was left when I last used it. There were actually two programs at that time. One was downloaded and used to set the time. Once the time was set the main program was downloaded. Kind of strange but I never completed to routines to set the date / time from within the main program.
Besides multiple daily temperature settings that could be scheduled (limited only by program memory) I also included a schedule for the backlight on the LCD display. It only comes on at night and is off during the day. I was going to add a feature (using a CdS photocell) so that if it was supposed to be on by schedule and light was sufficient it would turn off, but decided against it (ran out of time).
The future of this project is that it will be integrated, along with security and fire alarm capabilities into a home controller I am currently designing. The customization capabilities of something like what I have planned are staggering. When that project is started it will appear in the project list. I hope some of you find the hardware and/or code somewhat useful.
Digital Thermostat by Chris Savage – Savage///Circuits is licensed under a Creative Commons Attribution 3.0 Unported License.