Introduction: Cheap Web-connected Thermostat

Picture of 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

Picture of 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?

Picture of 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

Picture of 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

Picture of  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.

Relay

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

Picture of 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

Picture of 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

Picture of 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)

Picture of 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

Picture of 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

Picture of 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

Picture of 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

Picture of 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!

Comments

Diez66 (author)2017-11-13

I may not build this but I really liked the way you made the "analogue" meters.
OK, so they are not real but they do look the part.
Thanks for the idea, wish it had been mine.

tjaap (author)Diez662017-11-14

Thank you! Not entirely unique though I have to admit. Search for 'servo gauges' or 'gauges stepper motor' to see many more cool examples.

drdanny (author)2017-11-09

Excellent instructions! Thank you. I haven't looked at the code in detail yet - did you include a hysteresis setting? I think different types of thermostat need different values for this so that they aren't switching on & off constantly.

tjaap (author)drdanny2017-11-09

Thanks! No, it doesn't. I did make it so the heater won't be switched on or off more often than once a minute, to prevent jitter when the temperature is around the desired temperature. Because my house was well isolated however, hysteresis was limited, so temperature stayed within a nice small band. I got that from looking at the data in the web app, which makes it easy to analyze it for your situation.

AlexanderP124 made it! (author)2017-11-07

Just wanted to add some security notes for the readers regarding controlling it from away. It's nearly impossible to open the port on router just for your phone as the mobile network will never assign the same IP address to the phone. Also ESP8266 is not powerful enough to run a secure HTTPS server with some reasonable authentication. And you definitely don't want strangers to control your thermostat.

So I would recommend to have a simple home server (running on Raspberry Pi is perfect) which will serve as a front-end for the thermostat. In a simplest form you can install a simple web server like nginx which will perform so called "https termination", or, simply speaking, accept requests from outside via https and forward them to ESP8266 via http. Add http basic authenication and you get more or less secure system.

I'm not going to dive into the depth of nginx configuration but there are a few good guides in the Internet - for example, https://www.nginx.com/resources/admin-guide/restri... and https://www.nginx.com/resources/admin-guide/nginx-...

I have a very similar DIY thermostat at home, but I also went further and removed web server from ESP8266 completely. Instead, my home Raspberry Pi is running MQTT server (mosquitto) and the thermostat talks to other home components via MQTT protocol, which is much more suitable for IoT devices (it was basically made for this). Yes, I said "other components" because there is no relay in the thermostat itself, but there is one more ESP8266 is hidden in the heating cabinet that waits for commands over MQTT and turns the boiler on and off. This makes the thermostat independent from the boiler wiring and it can be placed in any room.

To control this I probably could use one of existing home automation systems such as http://majordomohome.com/, but I decided to just write a simple web application running on node.js and serviing as the interface between MQTT and a web browser (and eventually me).

Attached is the thermostat unit photo. Note, I figured out that I should move the temperature sensor outside of the box (it's ds18b20, circled in blue), otherwise the heat produced by the microcontroller and the displays skews the readings too much. ESP8266 uses from 100 to 300 mA, or up to 1W, which can raise the temperature in the closed box noticeably.

tjaap (author)AlexanderP1242017-11-07

This is fantastic, thanks for the great info on security. Your house has its own IoT-network, cool!

I should have noted that I left my thermostats open for that reason. By leaving top and bottom side open it's less influenced by any heat from the components and also so it can correctly sense changes in room temperature.

absolutekold (author)tjaap2017-11-07

Making use of the heat generated by the components to create a chimney effect to constantly draw fresh air over your sensor and keep the components cool at the same time. Although if you do have a sensor that also watches barometric pressure it would be (slightly) off but for just temperature it would be a useful way to ensure the air doesn't become stagnant around the sensor. You would just have to be aware of the air flow inside the enclosure. When in doubt smoke check it like with computer case mods.

tjaap (author)absolutekold2017-11-07

Interesting idea. I didn't know that technique is used in case modding.

absolutekold (author)tjaap2017-11-08

It isn't something you generally have to do as most cases nowadays are designed with adequate cooling and a lot of modding boils down to adding led's, some painting, and maybe a custom watercooling setup. It's only when you're trying to shove a computer in something that was never designed to have air flow to cool anything. Like when someone shoved a beast of a gaming computer into a portal companion cube or the Fallout Anthology bomb.

tjaap (author)AlexanderP1242017-11-07

I added a reference to your comment in the text. Thanks again.

gulliverrr (author)2017-11-07

I like the little details here and there. They make a difference ;) Nicely done

tjaap (author)gulliverrr2017-11-08

thank you!

gulliverrr (author)tjaap2017-11-08

We took a more "digital-looking" approach to the same problem you are addressing :) http://HestiaPi.com

tjaap (author)gulliverrr2017-11-08

Nice. Kudos for the 'without the personal data harvesting' bit.

gulliverrr (author)tjaap2017-11-08

Yeah it was one of the reasons why I started thinking about making one ;) Fully open source and standalone without third-party servers being involved

Juan JoseA9 (author)2017-11-08

Amazing Instructables project and many of comments. Many thanks and congratulations to all involved.

tjaap (author)Juan JoseA92017-11-08

I'm loving the comments too :-)

snorlaxprime (author)2017-11-08

Awesome work, I like the finishing touch with analog meter.

tjaap (author)snorlaxprime2017-11-08

Thank you!

tin.vrban (author)2017-11-07

Nicely done! I made a similar thermostat with a different sensor, AM2320 (precision 0,1 °C). Only I don't like the use of a relay, because it draws so much power to switch just a logic level, almost no current (the signal to the heater). I used a relay for a different project, and the power supply was a USB charger. It got very hot because the relay was drawing too much current. That's why I decidet to use a logic level MOSFET, IRLZ44n, which I had lying around. It is very simple to use, the MOSFET gate goes directly to the output pin, and the other two pins you use just like you would a relay, and it draws virtually no current! :)
One suggestion: instead of servos, could you have used voltmeters (or millivoltmeters) and PWM outputs to set the dials to desired position? The coils would do the low pass filtering.

tjaap (author)tin.vrban2017-11-08

A MOSFET would indeed be better. I do like the clicking sound of a relay, also because I associate it with classic thermostats :-) Probably the main reason I used the relay is that I had it lying around.

I did look at alternatives for the dials, including these (also see photo below). I did also think about using analog voltmeters and although I like them very much, they would have been too big to fit in my case. I know they exist that small, but then the needle would have been quite small. With the servos you can decide the length of the needle you want.

VK5OI (author)2017-11-07

excellent instructable, and excellent advice from AlexanderP124. Thanks for sharing guys.

tjaap (author)VK5OI2017-11-08

Thanks!

ajayt7 (author)2017-11-07

Ingeniously done.

tjaap (author)ajayt72017-11-07

thanks!

cjameson (author)2017-11-07

great project. How long have you been using this in your home?

I have read that the DHT22 has an accuracy of ±2°C. It seems to me that this might not be accurate enough to maintain a comfortable temperature in a home. What has been your experience with this?

A second thought: In my home the thermostat is located in a central hall rather than a room that people gather in. the result is that the hall is at a "perfect temp" but the family room is not. have you considered adding wireless satellite temp sensors to your build to deal with such situations?

tjaap (author)cjameson2017-11-07

Thank you! I used it a little over a year. I just moved houses and have not yet found the time to install it again in my new house, but in my old house it worked really well. Only thing I had some trouble with in the beginning was the capacitive touch, but otherwise it worked excellent.

You may be thinking of the DHT11, the predecessor of the DHT22 which was less precise. According to the datasheet, DHT22 has an accuracy of within +/- 0.2 Celcius: https://cdn-shop.adafruit.com/datasheets/DHT22.pdf

For my appartment this thermostat was sufficient, but you may want to read the comments by AlexanderP124 for an idea how to string more components together.

gtabbut1 (author)2017-11-07

Radiant heated homes could use a thermostat that can use the five day forecast to adjust heating temperatures in advance. Yahoo has an api that reads the five day forecast.

tjaap (author)gtabbut12017-11-07

That would be nice indeed. I'm not sure it is still as good and open as it used to be, but I used to like the Wunderground API as well.

VanoF (author)2017-11-07

Handig, dank je

Groeten uit Heiloo, N-H.

Waar zit jij ?

tjaap (author)VanoF2017-11-07

Nijmegen :-)

stumitch (author)2017-11-07

Excellent! I will try this out for sure. Thanks for such a well-written and comprehensive 'ible.

tjaap (author)stumitch2017-11-07

Thank you!!

MikeH36 (author)2017-11-07

"One tap for instance means half a degree up, two is half a degree up, and three taps means on or off."

I think one of those options should be "down"...

tjaap (author)MikeH362017-11-07

Thanks, I've corrected it.

akumabito (author)2017-11-06

Great project! Maybe I'll give it a go myself. Those gauges look really cool.

tjaap (author)akumabito2017-11-06

Thank you! One thing I didn't mention, is while normal iron wire will work, I got a bit of extra shiny wire from an arts and crafts store.

shahrokhani (author)2017-11-06

Excellent project, congratulations I've voted for you.

tjaap (author)shahrokhani2017-11-06

Thank you!

About This Instructable

18,282views

221favorites

License:

Bio: I am a freelance journalist and maker. I love to make my ideas become reality and I try to get better at it. Among techniques ... More »
More by tjaap:Cheap Web-connected ThermostatTeach Students to Make Things by Making Them Write Instructables8-bit wedding LED matrix
Add instructable to: