Introduction: Cheap Web-connected Thermostat
One of the first Internet of Things products that found its way into a lot of households is the smart thermostat. They can learn when you like your house to get warm and what room temperature is usually required.
The cool thing is that they can also be used to turn the heater on and off using your mobile, even when you are outside of the home. Very handy when you forgot to turn if off when you left or when you want to get home to a nice and warm house.
The problem is that these thermostats like Nest and Ecobee are quite pricey. But why pay 250 dollars for something you can build yourself, right? Let me show you how to make your own smart, online DIY thermostat for less than 30 bucks. As a bonus, you can even use the code I wrote for a web app to control your thermostat AND I show you how to make a metal touch capacitive case for the thermostat that will impress even the nerdiest of friends.
Step 1: What You Need to Build Your Own Smart Thermostat
My thermostat is relatively easy to build (if you know how to solder and that's easy too) and it uses readily available components:
- Adafruit Huzzah ESP8266 ($9.95)
- DHT22 module (6,95 in euros, I prefer the ones on a break-out board)
- Relay (they go for less than two dollars)
- Power supply that can supply 5 volts at 2 amps (any phone charger will work fine)
- Perfboard (I like Adafruits perma-proto boards)
- Jumper wire male-female
- Solder wire (use lead free, it's better for you)
You can go lots of ways for a case on the wall, but for what I did you're going to need this:
- 2 Micro-servos (such as the SG92R, 6 euros each)
- Metal case (I used an old cd-rom drive)
- 4 LEDs
- NPN-transistor (type BC547)
- Resistors (220 ohm and a couple 330 kilo-ohms)
- Piece of plexiglas
- Piece of wood
- Bits of smaller stuff like screws and iron wire
To create the circuit you only need a soldering iron. A multimeter is terribly handy for checking if you connected everything correctly. On your computer you are going to need the Arduino software and a USB to serial converter or cable to upload software to the ESP8266 chip.
To cut the metal for the case, I used a Dremel. A power drill, coping saw and a glue gun also come in handy. If you're going to pull an extra cable to power the thermostat, you may also need a wire pulling tool and silicon spray.
Step 2: So How Does a Thermostat Work Anyway?
In most houses with central heating, a wire runs through a tube in the wall between the heater and the thermostat in the living room.
The thermostat is really nothing more than a switch, one that will turn the heater on and off. It has a dial or buttons for setting the desired temperature. When the temperature in the room drops below the set temperature, the thermostat connects the wires coming from the heater. That's how the heater knows it should switch on. A circulation pump inside the heater will pump hot water through the radiators in the house, until the temperature is above the set temperature, at which point the thermostat will disconnect the two wires.
If you have multiple wires coming out of the wall, you can test which two you need simply by connecting them and (have a friend) listen if the heater comes on (usually it's a red and a blue wire).
Dumb heaters and smart heaters
Most heaters are smart enough to throttle back from time to time, to allow hot water to be pumped through the system before heating full on again. That saves on energy. However, some older type heaters don't do that, and you will have to help them a little by finding out what duty cycle is most efficient and change the code in the thermostat accordingly.
There is one other thing to take into account. In my house, the heater is of the modulating persuasion, so simple on and off switching. But newer heaters will expect thermostats to use the OpenTherm-protocol. That way, thermostats not only tell the heater to turn on and off, but also how hot the water in the system should be heated to. Not a problem: there are also OpenTherm libraries for Arduino available.
Step 3: Soldering the ESP8266
The ESP8266 module will probably get mailed to you complete, but without the black headers soldered on. Once you have done that, solder the whole thing onto the protoboard. Make sure you place the rows of pins on either sides of the empty space in the middle so they won't be connected.
Cut and strip a short wire (preferably red, that's the proper way) to connect the ESP8266 to the power supply. Solder the wire on the protoboard right next to the pin on the chip where it says 'Vbat'. Solder the other end of the wire to the row with the red line (see illustration below). Do the same with a black thread, and solder it between 'GND' (for 'ground') on the chip and the row with the black (or blue) line.
Then solder a small screw terminal on your protobord so you can easily connect the wires from the power supply to the 5 Volts rail later on.
The chip in turn powers the sensor, so on the opposite side of your protobord solder a wire between the 3V output of the ESP8266 to the red row, and from the GND pin to the blue row. Now you have on your protobord a 5 Volts rail, a 3.3 Volts rail and two ground rails.
After soldering, I cut the perfboard down to smaller size using a coping saw so it would fit in my case later on. It's probably better to do this before soldering, but then you have to be a better planner than I am.
I attached it to the wood with little screws, together with the other components in the thermostat.
Step 4: Wiring the Temperature Sensor and Relay to the Chip
Cut three jumper wires in half to get a wire with a female connector on one end and just wire on the other. Strip the isolation from that side. Push the female connectors on the pins of the temperature sensor, and solder the loose ends to the perma-proto-board. If you only have wires without connectors, you can also solder them directly to the pins or just solder the sensor directly onto the proto-board. 'VCC' on the sensor goes to the 3 Volts rail, 'GND' to the ground rail next to it, and the 'DATA' pin connects to pin 12 of the ESP8266.
In our thermostat we use a relay to switch the heater. A relay enables you to switch voltages much higher than what an Arduino, Raspberry Pi or ESP8266 can handle. Very practical if you want to want to have lamps turn on automatically when it gets dark or lower the blinds when it gets sunny.
In this case we need one because the switching voltage of most heaters is 24 Volts and the ESP8266 goes up in blue smoke if you give it more than 3.3 Volts. Connecting the relay again is easiest if you have one on a breakout board. Push the female header on the pins of the relay and solder the loose wires to the perma-protoboard. On the module you will probably have an option to use either ‘normally closed’ (NC) and ‘normally open’ (NO). Choose the latter, so the heater only switches on when the chip sends a signal. So one wire from the heater goes to ‘COM’ and the other in ‘NO’.
If your relay does not switch at 3.3 Volts (so when you don't hear the clicking sound) then you can also use the 5 Volts rail which powers the ESP8266 (but you may need to add a resistor and a transistor).
The way the relay is driven can be a little counter-intuitive (see the 'Important note' on this page). In the code we put the pin for the relay to 'high' when the heater should turn off. The way I imagine this is pulling up a shutter in the chip so no more current will run through the wire to the relay.
Step 5: Software for the Thermostat
For all components we use here standard libraries are available that we can just reference from one script. You only need to install those libraries before the script gets compiled and sent to the chip. In the Arduino software you can easily add them via Sketch > Use library > Libraries. Search and install ESP8266WebServer, DHT sensor library and perhaps also CapacitiveSensor. The Running Average library you need to download yourself, from here: http://playground.arduino.cc/Main/RunningAverage
The code for my thermostat you can download below. What the code does is described in the comments in the script itself. The only things you need to change, are the name and password of your wifi network.
The script starts a webserver (like it's nothing). You can change what information it passes on to the browser if you want. The script keeps track of an average temperature based on the ten most recent measurements. It switches the relay no more than once per minute, to make sure the thermostat is not too nervous when the temperature is on or around the desired room temperature.
Writing the code to the chip
Writing code to the ESP8266 is easy: you can just use the Arduino IDE. These are the settings needed to connect them:
Board: Adafruit Huzzah ESP8266 (you may need to add it first via Tools > Boards > Boards Manager)
CPU frequency: 80 Mhz
Upload speed: 115200 baud
Flash size: 4M (3M SPIFFS)
Port: choose the one that has your FTDI cable or serial cable.
Connect the FTDI or console cable to the Huzzah board. It may vary between converters, but usually it's red to V+, RX/white to TX, green/TX to RX, black to Ground. Put the ESP8266 in bootload mode by pressing the ‘GPIO0’ button, then pressing ‘reset’ and then letting go of GPIO0. When the red LED on the board is glowing less bright, then the bootloader mode is activated. Next, click on 'upload' in the Arduino IDE and your script will be loaded to the ESP8266.
When that's done, connect your circuit to the 5 Volt power supply... and everything should work! Open the Arduino IDE serial terminal by using the menu Tools -> Serial Monitor. Set the baud rate in the bottom right to 115,200 baud. You should see a screen that tells you the webserver has started and an IP address. Put that address into your web browser, and you will see your thermostat output data!
Step 6: Creating a Web App
If you want to be able to control your central heating when you are away from the house, then you have to make the ESP8266 module accessible by opening a port on your router. Do make sure you do it safely or your thermostat may be part of an Internet-of-Things botnet before you know it. [edit: in the comments AlexanderP124 has some good suggestions for a safe setup]
Once you have done that, wouldn't it be nice to have a pretty webapp to control your thermostat with? I put one on my home server, so it could contain more data and bells and whistles than the ESP8266 itself could hold.
You could have a script on your server which saves the data from the thermostat every minute, so it can show a graph with the temperature of the last 24 hours. I created an SQLite database to store the data in. If you want to use the code I wrote, you can get it below.
Step 7: Making a Case for a Case
A display with buttons on the wall wouldn't even be necessary anymore. Temperature setting can be done on your phone or tablet, and the only thing that needs to be in the living room is the temperature sensor.
But hey, we can't just leave wires and the circuit hanging from the wall, and we have power there anyway, so why not make a nice display. You could have all necessary information displayed on an LCD character display, although that is a little standard. I thought a self-built panel with a couple of lights and a few gauges would be more fun to look at.
What you want from a thermostat is to be able to see how warm it is and to have a way to change the goal temperature. I also wanted something that looks a bit nicer than the standard grey box everybody has on their wall. I went for an eighties amp look with brushed metal and analog gauges. I took the case of an old cd-rom drive and cut it in half. A bonus is that these cases have holes with screw-threads that make it easier to fix components to it and attach it to the wall. I cut out a square with a Dremel hand drill. You get the right look by applying a soft steel brush, brushing in one direction over the iron, either by hand or using a steel wool drill bit.
Step 8: Analog Gauges (That Are Pretty But Not Very Analog)
The analog gauges that show the temperature and goal temperature are not really analog. I just like the look. I turn the wires using micro-servos (you find them in RC planes and lots of toys).
Because they are so small, we can just power them using the voltage we already have available. Connect them to the chip by soldering them according to the schematic.
Cut a piece of plexiglas and a piece of wood (mine was 12 mm thick) to size for the inside of the metal case. A scale for the gauges can be drawn by hand or printed (see my design) on paper that you cut to the size of the wood. Gluing won't be necessary.
The paper helps to mark where the servos go. Drill a hole where the needle turns on the servo. Push the servos through the wood and mark the size of the hole needed for the upper side of the servo. Cut out the hole with a Dremel or chisels, and then screw the servos into place. Cut two pieces of iron wire to size, wrap their end around a little screw that fits into the servo horn, and then screw them into place. Adjust them to have their position match the current temperatures.
Step 9: Everything's Better With LEDs
Stick a few LEDs at the bottom of the wood to light up the gauge panel. Either bend the LEDs legs around the wood or drill a few very small holes. Together they need more current than the ESP8266 supplies, so connect them to the 5 Volts rail through a couple of resistors and a transistor. See the schematic on how to do it. The transistor works the same way as the relay, in that it takes only one pin on the ESP8266 to switch 5 Volts to the LEDs.
To have an indicator of when the heater is on, I made a light pipe between the relay (which has an LED that lights up when a connection is made) and the front of the case. You could have a separete LED connected to the ESP8266 as an indicator, but this seemed redundant to me as the relay already turns on an LED when it is making a connection.
I made the light pipe by hot glueing strands of glass fiber (cut from a toy) directly on the LED on the relay and a red plastic indicator cone (which came from an 80s amplifier) which I attached to the case, also with hot glue. To be honest: it didn't work well. It's hard to get the strands stand at the right angle on the tiny LED, especially when you try not to fry the circuit with your hot glue gun. I have no advice to offer on how to execute this idea better (please leave a comment below if you do).
Hot glue can also be used to attach the plexiglas window to the inside of the case.
Step 10: Touchy Interface
But how to set the temperature? A dial with set values is no use, because it won't be correct anymore once you change the goal temperature through the webapp. Two buttons would work, but that option is a bit bland. There is a trick that requires no buttons and that will impress your nerd friends. Because the case is made from metal, you can turn it into a ‘capacitive touch switch’. That way we can set the temperature just by touching it. One tap for instance means half a degree down, two is half a degree up, and three taps means on or off. We'll only turn on the LEDs and servos if the thermostat was touched less than a minute ago.
The only thing you need to do is connect a resistor to two digital pins (I used 14 and 15) and then solder a wire from the resistor to the case. The CapacitiveSensor library can then monitor when the case is touched. By setting a threshold value and by experimenting with the resistor value (somewhere between 50 kilo-Ohm and a couple mega-Ohm) you can accurately tune the sensitivity of your homemade sensor.
Step 11: Fixing It to the Wall
You could use a LiPo battery to power your thermostat, and have it warn you through the webapp when the battery runs low. I didn't want to worry about batteries though, so I wanted an extra cable for power.
If you are lucky there is already an extra wire there to power the thermostat, but I had to pull a new cable through the wall (using a wire pulling tool and lots of silicon spray) to be able to power my thermostat using an 5v 2 amps adapter.
Don't do what I did and use a piece of metal to attach the thermostat to the wall, because that - of course, silly me - will ruin the touch capacitive capacity (?) and then you will have to fix that again.
What could also be an option, is ‘powerstealing’. That means the thermostat will continuously draw a bit of current from the heater's wires to charge itself. That requires a battery and your heater has to support it, so you need to figure that out first.
Once you have checked everything is connected correctly and working, you can screw the wires coming from the wall carrying 5V to the screw terminal on your protoboard. Then put the plug in the wall socket and tadaaa! You have your own working wifi-enabled thermostat.
Step 12: Fun With Data and Some More Ideas
After enjoying your thermostat for a while, you may want to tweak and enhance it some more. Here are a few ideas.
You could have the server send you an e-mail alert when no data is coming in, so you will know when either your thermostat is disconnected or has crashed somehow.
Also nice would be adding outside temperature. I think it could be used somehow to change the duty cycle, but it could also be fun to add it as a third gauge.
By analysing the data in the database, you can monitor how well your heating system works. One thing I already had a bit of fun with: plotting temperature and humidity in your living room over the course of a month or a year. In my graph you can clearly see summer being warmer and more humid, but also that my house is quite well isolated.
You could use this data to tweak the code to make the thermostat a bit more energy efficient. It would of course be really nice if you make the thermostat learn your daily routine and heating preferences, so after a while it knows when to shut off at night, maybe in combination with a light sensor.
If you do any of this or come up with other cool extensions, please tell us in the comments or in your own Instructable!
Hope you found this Instructable interesting, and if you did, don't forget to vote for it. Thanks!