Introducing Climaduino - the Arduino-Based Thermostat You Control From Your Phone!




Introduction: Introducing Climaduino - the Arduino-Based Thermostat You Control From Your Phone!

There is a new version of the Climaduino and the Climaduino Controller with some very significant changes.

  • Supports multiple zones
  • Uses the Arduino Yún
  • Works with Central A/C
  • Communicates using the MQTT protocol (can integrate with other systems besides the Climaduino Controller)
  • Does not have an LCD or temperature setting buttons (they will need to be added back at some point)

For more information, visit the develop branch of both projects Git in the git repo:


Not everyone lives somewhere with central air, or is willing to pay for a Nest or similar "smart" thermostat. The Climaduino is a DIY Arduino-based thermostat designed to control a wall unit A/C. I incorporated both temperature and humidity sensors in order to optimize comfort and reduce energy usage. I then developed a Raspberry Pi-based web interface to control the Climaduino from my phone.

This is still a work in progress, but is definitely functional. I am posting this instructable so others can both build their own smart thermostats, and hopefully build on this project with their Climaduino improvements.

Here are the features so far:

Climaduino thermostat

  • Arduino-based
  • temperature and humidity sensors
  • Relay to control A/C
  • LCD Display
  • Buttons to control temperature
  • Controls both temperature and humidity
  • Settings stored in EEPROM and survive power failures
  • Short cycle protection for efficiency and compressor protection

Climaduino Controller

  • Raspberry Pi-based
  • Wifi-enabled
  • Mobile-optimized web interface to control Climaduino settings
  • Historical temperature and humidity graphs
  • Programmable temperature and humidity changes

Why did I want to build this? Mainly because it was fun to do and I've always been very interested in climate control. (I know that sounds weird, but it's true.) It's also because humidity is a huge issue in my area, South Florida. I designed the Climaduino Thermostat to take this into account. The A/C will stay on just a little bit longer when it's humid to wring more moisture out of the air. I also added a humidity control mode. It can save a significant amount of power and prevent coming home to a mold-infested house. Humidity control mode ignores temperature and only runs the A/C when things get too humid. It's useful when going out of town or when the house is empty (of people and pets).

Obligatory warning
If you perform any of the steps in this instructable, you assume all risk for the outcome. Working with high voltage can be extremely dangerous. Improperly altering your A/C unit could lead it to malfunction or completely break. Please be careful.

Electrical Safety: Safety and Health for Electrical Trades Student Manual

Step 1: Supplies

The following will be needed to complete this project.

Climaduino Thermostat

  • 1 x Arduino - I'm using an Arduino Uno
  • 1 x Solderless breadboard
  • 2 x buttons - momentary on (optional)
  • 1 x DHT22 temperature and humidity sensor
  • 1 x LCD display (optional) - Not sure of the model, but it is parallel-based and uses the LiquidCrystal library
  • Resistors:
    1 x 4.7K ohms
    1 x 220 ohms (only required if LCD is used)
  • Wires to connect everything
  • The DHT library installed in Arduino/libraries
  • Climaduino Thermostat source code

Climaduino Controller

Step 2: Thermostat: Building and Installing the Relay

  • Look up how much current your A/C draws. If it is more than 20 amps, you'll have to find a different relay kit.
  • Solder parts on the Beefcake Relay PCB except for the output terminals (the PCB is labelled). The Arduino Controlled Relay Box instructable has steps and some tips and tricks.
  • Solder wire of an appropriate gauge for the amount of current your AC will draw directly to the larger pads labelled LOAD on the PCB.
  • Create a relay-controlled power cord or outlet for the A/C to connect to. The Arduino Controlled Relay Box instructable is a good place to start.

    Note: Make sure to use a power cord that can handle the current your A/C draws and has the right plug type.

    Another option is to subvert the A/C's built in controls and install the relay inside the A/C. (Has serious potential to break your A/C, and can be dangerous if not insulated properly from the chassis.)

I originally planned on creating a power cable for the unit with the relay inline. Unfortunately, this unit's built-in thermostat was cycling it off prematurely. I looked up the unit's wiring diagram and found a way to wire in the relay so the old built-in thermostat could still be used in the future. I then set the built-in thermostat to its hottest setting giving the Climaduino Thermostat full control.

Step 3: Thermostat: Wiring It All Up

  • Wire things up as they are in the diagram. The LCD and buttons can be skipped if you don't want them.
  • Connect the relay to the Arduino:

    GND to - rail on the breadboard
    CTRL to pin 10 on the Arduino
    5V to + rail on the breadboard

I recommend orienting the Arduino so pins 0-13 are next to the the breadboard. This makes the wiring for the LCD a lot neater.

The resistor used for the LCD is 220 ohms, and the one used as a pull-up for the DHT22 sensor's data line is 4.7K ohms.

Step 4: Thermostat: Loading the Code and Testing

  • Connect the Arduino to your computer and upload the Climaduino sketch.

    If it fails to upload, this may be because you do not have the DHT library installed in your Arduino/libraries folder.

Once uploaded, the LCD should display the current temperature/humidity settings and readings. The temperature setting can be changed using the two buttons on the Thermostat. One button raises the temperature by a degree at a time and the other lowers it. Hold the button down until the setpoint changes to the desired value. It will not be very responsive. Earlier attempts at using interrupts to allow immediate reactions to button presses caused problems.

The thermostat outputs current readings, parameters, and other operational details as JSON over the serial port. To test this, open the serial monitor (right-most button in Arduino IDE). You should see JSON data being sent from the Arduino to your computer. This data includes the operational parameters, the current settings, and readings.

To test changing the settings, open the serial monitor. Click the drop-down menu at the bottom of the window that says Newline and select No line ending. Type the desired temperature followed by an F (case sensitive) and press Send to change the temperature setpoint. 77F and then Send would change the temperature to 77 degrees fahrenheit. Type the desired humidity followed by a % and press Send to change the humidity setpoint. 55% and then Send would change the humidity setpoint to 55 degrees of relative humidity. Finally, the mode can be changed by typing the desired mode number followed by M (case sensitive) and pressing Send.

Valid values for mode are:
  • 0 - Cooling/Humidity Control
  • 1 - Humidity Control
  • 9 - System Off

Step 5: Controller: Installing Pre-requisites

This assumes you already have a Raspberry Pi running the Adafruit Occidentalis Distribution (based on Raspbian). It also assumes you have network connectivity either by connecting directly over Ethernet, or by setting up and using a USB WiFi adapter.

Here are some resources to help those new to the Raspberry Pi:

The Occidentalis distribution advertises itself as raspberrypi.local using Avahi (Bonjour). This means that Macs, and iPhones will be able to access the Raspberry Pi using this rather than IP address. If unable to use raspberrypi.local, it may be advisable to configure a static ip. If you decide not to configure a static IP, and can not use raspberrypi.local, you can find the IP address assigned to the device from your router or by logging on to the Raspberry Pi using a monitor and keyboard and typing ifconfig. You will use the account pi to log in. The default password for the pi account is raspberry.

Change the default password (optional)

  • Log on to the Raspberry Pi using pi as the username and raspberry as the password.
    • can ssh in (ssh pi@raspberrypi.local in the Mac Terminal)
    • can log in at the console using a connected keyboard and monitor
  • Type passwd and follow the on-screen prompts to change the password

Install Python Setuptools

Python Setuptools makes it easier to download, install, and configure Python packages. It provides the easy_install command I'm going to use a lot in these steps.

Update apt-get

  • sudo apt-get update

Install rrdtool

  • sudo apt-get install libcairo2-dev libpango1.0-dev libxml2-dev rrdtool librrd-dev

Installing Git (optional)

  • sudo apt-get install git

Install Python virtualenv (optional)

  • sudo easy_install virtualenv

Python virtualenv
allows creating a isolated install of Python. The advantage of doing this is that it keeps any modifications you make to Python compartmentalized in that one virtual environment. This is a bit overkill for what we are doing with the Climaduino Controller, but I like to leave things in a good state for future projects. Here is a quote from that explains it well:

"The basic problem being addressed is one of dependencies and versions, and indirectly permissions. Imagine you have an application that needs version 1 of LibFoo, but another application requires version 2. How can you use both these applications? If you install everything into /usr/lib/python2.7/site-packages (or whatever your platform's standard location is), it's easy to end up in a situation where you unintentionally upgrade an application that shouldn't be upgraded."

Creating a Virtualenv (optional)

  • virtualenv ~

We're now going to create a Python virtualenv at /home/pi. Since we are logged in as pi, ~ expands to /home/pi. If you choose to create your virtualenv somewhere else, then the steps and examples in the rest of this instructable will need to be adjusted accordingly.

Using a Virtualenv

  • source ~/bin/activate

There are two ways to use your virtualenv. You can either directly use the activate script (installed with the virtualenv) to update your path, or directly reference the executable in the virtualenv.

Using the activate script to use the virtualenv is the option I chose as it is less error-prone. When choosing this option, no special considerations need to be made as the right executables will be used. This has to be repeated each time you log in and want to use your virtualenv.

If you choose not to use the activate script, then care must be taken when running Python programs or using easy_install. When the activate script is not used, then the system-wide versions are used unless you specify the path of the executable you want to use. To run a python program you would need to type ~/bin/python and to use easy_install, you would need to type ~/bin/easy_install package_name.

Note: The rest of the commands in this instructable will assume a virtualenv was created and the activate script was used to update the path. If no virtualenv was created, the easy_install commands will need sudo prepended to them. If a virtualenv was created and the activate script was not used, ~/bin/ will need to be prepended to some commands.

Step 6: Controller: Initial Setup

Connect the Arduino

  • Connect a USB cable from the Arduino to the Raspberry Pi.

Installing Needed Python Packages

  • easy_install pySerial
  • easy_install python-rrdtool
  • pip install Django==1.6.10

Get the Climaduino Controller source code
The code can either be:

Set Up the Climaduino controller

  • cd ~/climaduino
  • Create the database
    • python syncdb
    • Answer yes and follow the prompts to create an administrator user
  • Start the development server listening on all IP addresses on port 8000
    • python runserver

Test Initial Setup

  • Browse to http://raspberrypi.local:8000 on your computer and/or phone. A page should display showing the current temperature, temperature setpoint, humidity, humidity setpoint, and mode.
  • Verify the readings listed on the page match those on the Climaduino Thermostat's LCD (if you installed one).
  • Change the temperature by clicking or tapping on the button displaying the temperature. Change it to another value and verify the setpoint displayed on the thermostat's LCD displays the new value after a couple seconds pass.
  • Access the administrative interface from your computer by browsing to http://raspberrypi.local:8000/admin/. Log on using the administrative credentials entered during the database setup.

Step 7: Controller: Polishing the Setup

The setup as we left it is not very polished. The following are optional steps that can be taken to make the Climaduino Controller's installation more polished.

Change the hostname so it can be accessed using climaduino.local
This will change it so we connect to the controller at climaduino.local rather than raspberrypi.local.

  • sudo nano /etc/hostname
  • replaceraspberrypi with climaduino
  • Ctrl + x, y, and then press Enter
  • sudo reboot

The Climaduino Controller should now be accessible at http://climaduino.local:8000.

Start Automatically at Boot and use Port 80
I have already created a startup script that can be used. If any details of your implementation differ from the steps in this instructable, the script may need some tweaking.

  • sudo apt-get install screen
  • sudo cp ~/climaduino-2/startup_script\ for\ Debian/climaduino-controller /etc/init.d
  • update-rc.d climaduino-controller defaults
  • sudo reboot

After reboot, the Climaduino Controller should start automatically. It should now be accessible without adding a port number since port 80 is the default for http. http://climaduino.local (or http://raspberrypi.local if the hostname was not changed).

Step 8: Thermostat: Advanced Tweaking

Most people are probably going to want to ignore this step. It is just extra information about parameters in the Climaduino Thermostat that can be tweaked and what they do.

There are many variables that are not currently able to be adjusted without changing them in the code. While some may be exposed using the serial interface in the future, for now the following variables can be changed in the source code. The sketch can then be re-uploaded to the Arduino.

  • tempHysteresis
    • Default: 2
    • Number of degrees the temperature is allowed to go above the temperature setpoint when in Cooling mode and below the setpoint when in Heating mode.
  • humidityHysteresis
    • Default: 2
    • Percent relative humidity the humidity is allowed to go above the temperature setpoint when in Cooling or Humidity Control mode.
  • humidityOverCooling
    • Default: 5
    • Degrees cooler than temperature setpoint allowed when humidity is above the humidity setpoint. Only used when in Cooling / Humidity Control mode. This puts a cap on how much cooler the area is allowed to become when the compressor is running because humidity is too high. If set too low, there may not be adequate humidity control in some cases. If set too high, the area may become uncomfortably cold in some cases.
  • minRunTimeMillis
    • Default: 600000 (10 minutes)
    • Minimum time the system will run for when in a mode that uses the compressor. This may lead to overshooting the temperature or humidity setpoint, but it should lead to greater efficiency and be easier on the compressor. This prevents short cycling.
  • minOffTimeMillis
    • Default: 180000 (3 minutes)
    • Minimum time the system will stay off for before coming back on when in a mode that uses the compressor. This prevents short cycling and protects the life of the compressor. Most wall units likely already have protection to keep the compressor from coming back on too quickly after it has turned off, but it seemed safer to explicitly add this to the code.
  • numberOfReadings
    • Default: 2
    • Number of readings to average before returning a temperature value. This was mainly coded in for when this project was being prototyped using less accurate and more inconsistent analog thermistors. I left it in the code, because it may still help to get more stable readings.
  • delayBetweenReadingsMillis
    • Default: 2000 (2 seconds)
    • Time to wait between each reading to be averaged. This is set to 2 seconds because the DHT22 sensor can only give readings every 2 seconds. The DHT library, in fact, will not check the sensor again until 2 seconds have elapsed. If queried before this time has elapsed, the library simply returns the previous value. That would negate the point of averaging 2 readings.
  • pinRelay
    • Default: 10
    • Pin that will trigger the relay.
  • pinSensor
    • Default: 9
    • Pin DHT22 sensor data line is connected to
  • pinCooler
    • Default: 11
    • Pin button to lower temperature setpoint is connected to
  • pinWarmer
    • Default: 12
    • Pin button to raise temperature setpoint is connected to
  • lcdRS
    • Default: 3
  • lcdEnable
    • Default: 4
  • lcdD4
    • Default: 5
  • lcdD5
    • Default: 6
  • lcdD6
    • Default: 7
  • lcdD7
    • Default: 8

Step 9: Contribute Back

If you use this project and improve it or fix any bugs, please contribute your changes back. Comment on this instructable or contact me through instructables.

Thanks and hope you enjoy this project!

Hardware Hacking

Participated in the
Hardware Hacking

Be the First to Share


    • Stone Concrete Cement Contest

      Stone Concrete Cement Contest
    • Home and Garden Contest

      Home and Garden Contest
    • Digital Fabrication Student Design Challenge

      Digital Fabrication Student Design Challenge



    8 years ago on Introduction

    Very cool!!!
    I thought of something very similar. Obviously using my open source java library control. Actually there is still no web interface (you can just control Arduino from network) but it works very well with Raspberry. If you are interested check it at


    Reply 8 years ago on Introduction

    Izu, that looks very intriguing. It is an extremely cool project that I would love to experiment with at some point. Thanks for letting me know about it.


    Reply 8 years ago on Introduction

    Thank you. Give me a feedback when you'll try it.


    4 years ago

    Does any of you use a gsm module in this project. I want to access from anywhere. Sim card will have static ip.


    5 years ago


    Do you believe the climaduino can go solar?

    I have transpired solar collectors on a house with inlet and exhaust dampers. All I need to do now is cost-effectively control the pre-heated solar hot/warm air by way of the homes furnace fan.

    If the collectors and the outside air temperature had a remote temperature sensor that could talk to a controller that activates a home's furnace fan then the system will work.

    The practical aspect is: Collectors are 75 F or higher and the outside air is 62 F or below. This combination of data is relayed to the controller remotely. Whem the parameters are met the controller turns on the home's furnace fan and circulates the heated air from the collectors throughout the home.

    Is the Climaduino the right way to go?


    Reply 5 years ago

    It probably could do that, but many of the assumptions baked into the Climaduino may not meet what you want to do.

    This Instructable is old, and there is another branch on Github that uses MQTT to communicate. (

    I think your best bet would probably be to copy some of the MQTT code from there. Then you could have the Climaduino relay the temperature using MQTT to a home automation server like OpenHAB or Vera. The outside temperature could also be sent to the home automation server. Then the home automation server could send a command over MQTT to turn on or off the fan.

    The other option is to have the Climaduino read the MQTT data from the outdoor thermostat itself and make that determination.

    If you'd like to keep costs down, you could use an ESP8266 (like the Adafruit Huzzah) instead of an Arduino Yun. The Adafruit Huzzah was about $5 or so. I don't have any code on Github for that, but I successfully used it as a remote IR sender for a wall airconditioning unit. I could put that code on Github, but it is not very polished at all.


    Reply 5 years ago


    Thank you, great info and insight. I hope to let you know if I get this pulled off.

    Thanks again for your generosity.


    Reply 5 years ago

    I posted a longer reply, but Instructables seems to not have put it up.

    Climaduino has a lot of assumptions that are not true here. You could use the MQTT branch Then possibly remove the Thermostat.cpp and .h files. Remove Thermostat from the .ino file and implement your logic in the .ino file instead.

    My recommendation is to use MQTT to communicate between the multiple sensors and possibly with a home automation server (like OpenHAB or Vera). The choice would be whether you want the logic in the thermostat device itself or on the home automation server. For Climaduino I chose to keep the logic on the thermostat device, but made the parameters the logic uses remotely configurable over MQTT. That way it keeps working even if it loses connectivity or the home automation server goes down.

    If you have it on the device itself, you can use MQTT on the thermostat to get the outside temperature from the other sensor and make the determination there.

    There is another option which could help to lower costs. You may be able to use the ESP8266 instead of an Arduino Yun. The Adafruit Huzzah is about $5, but you need to do some soldering. I used one as a remote IR sender hooked up to my home automation server using MQTT. That way I could lower and raise the temperatures programmatically.

    I don't have that code on Github, but could post it. It is not very polished. It also doe snot have any thermostat logic, but that could be added in.


    5 years ago

    You could also have the logic on the home automation server and then simply provide a means using MQTT to trigger the furnace fan on and off.


    6 years ago

    As you're already using MQTT you could use as MQTT broker... Like this you have the easy configurable mobile app from DIoTY available to you as mobile (android + iOS) interface...


    7 years ago on Introduction

    Dear bbustin, could you provide for me Raspberry pi controller code if I want to use raspberry pi and arduno uno over usb please?

    I did everything as was mentioned in this tutorial, but I get error message if I try to click on submit or on settings or history for example, I can´t get the readings too :/

    Help me please, thank you :)

    I used this for Arduino:

    And this one for pi:


    Reply 7 years ago on Introduction

    Hi Deekaylol,

    The code you used should work for that; however, I think that the problem here is that there is a new version of Django that was released in the interim. The old code is not working with the new version of Django.

    Maybe you could try uninstalling Django and then installing the older version:
    pip install Django==1.6.10

    If that works, please let me know and I will update this instructable so others do not run into the problem.


    Reply 7 years ago on Introduction

    Dear bbustin,

    That did the trick ! I was able to uninstall Django with pip uninstall, and install the version you mentioned, the reading is working, great :) Thank you,you are the king bro ! ;)

    I got two more questions, I hope you could help me:

    1, I see Heating option, but I in the Arduino code, I just see one relay output "const int pinRelay = 10; // pin for relay" , could you provide some information about this ? I would be really thankful, If you coud edit the code for second relay, which could control the heating.

    2, Could you provide some information how the temperature could be changed to SI ? I mean to Celsius, since I´d like to use that code to control heating/cooling system in our bungallow (AC and Heating is connected to 220V so the relay shoud do the trick.)

    I look forward to hear from you.

    Best regards, deekaylol


    Reply 7 years ago on Introduction

    Hi Deekaylol,

    The original code currently only handles one relay for cooling. I had put the heating in there for the future. The current code handles heating as well; however, it works in a completely different way and has different requirements.

    Changing the code to display Celsius should be easy. Change line 216 in the code from

    "float readingTemp = dht.readTemperature(true);"


    "float readingTemp = dht.readTemperature(false);"


    Reply 7 years ago on Introduction

    Dear bbustin,

    I was ablet to edit the code, second powerstate and pinrelay did the trick, it´s a bit buggy at the moment, but working. But I was stucked with the F to C converting, that was so easy. Thank you very much !

    Have a nice day ;-)



    7 years ago on Introduction

    Hi Tom,

    I think that about the init script not following the LSB standards may be ok. One way to tell is to see if the rest of the steps work. If they do not, let me know and I will try my best to come up with some steps that should work.

    I'm sorry this has been so difficult. The code you are using is the newest and best, but I have not had time to polish things up or write an install guide yet.


    Reply 7 years ago on Introduction

    hi bbustin. We got it, the fact you told us to reset the Yun distro actually worked. I guess this is a valuable experience. We continue to work on it as adding more features like controlling washer too. But your help is so great and we want to say thank you..

    actually, we have to change a tiny bit in

    mqtt_connect('climaduino.local') with our Pi's address. then it started collecting data.

    wget and is another experience. we actually did wget whole html file instad of python file.


    Reply 7 years ago on Introduction

    Hi Tom,

    I am really happy it is working now. I updated the README file to now tell others to first update their Yún. If I can help with anything else, let me know.


    Reply 7 years ago on Introduction

    thank you for your respond.

    First, we uploaded sketch to arduino Yun and tried to see how data be transmitted, (no shield yet). even though, we used

    ssh root@yourYunsName.local 'telnet localhost 6571'

    tried to get data but the error : telnet bad address "localhost" stopped this happening.

    how we can define the Yun hostname is big thing

    Second, at the same time, we installed develop code controller for Raspberry pi but cannot understand how Raspberry pi able to communicate with Yun, we understood that MQTT bridge does that part but how Pi is able to load the data from Arduino Yun is a big challenger. All steps were followed.

    but the question is : should we install MQTT into Pi as well? most of other projects we saw MQTT been installed to all machines it communicates with. how can MQTT in Yun able to communicate with Pi if the receiver doesn't have the same program to receive the message?

    I would like to hear you back soon, we tried many steps but not going anywhere further yet. the data is not transmitted. no communicate between Yun and Pi .


    Reply 7 years ago on Introduction

    Hi Tom,

    The code in the Develop branch of the controller has instructions for installing MQTT on the Pi. What you have is an MQTT broker server on the Pi. Then you have the MQTT bridge component on the Pi that talks to the MQTT broker. The Yún has an MQTT bridge component as well which communicates with the MQTT broker on the Pi.

    For some reason the Yún does not seem to support MDNS, so I had to add instructions in the README about adding the Raspberry Pi's IP to the hosts file until I can figure out how to get MDNS working properly on the Yún.

    So the communication is from each component to the MQTT broker server. The Yún puts messages on the MQTT broker and the Climaduino Controller software picks them up. This information is stuff like current temperature and humidity, whether the system is on or not, whether the fan is on or auto. The Climaduino Controller software subscribes to those types of messages with the MQTT broker. Whenever the Yún sends one of these messages out to the MQTT broker, the MQTT broker sends the message to the Climaduino Controller.

    The process also works in reverse. When the Climaduino Controller needs to ask the Climaduino to change a setting (such as changing the temperature set point), it sends this information to the MQTT broker. The Yún is subscribed to those kinds of messages with the MQTT broker. So whenever the broker gets one of the setting messages, it sends it to the Yún.

    The MQTT broker is what handles all of the data receiving, storing, sending. The MQTT Bridge components on the Yún and the Pi are the ones that interface with the MQTT broker.

    The MQTT bridge on the Yún is different code than the MQTT bridge on the Pi. So the Pi should have the Climaduino Controller code from the Develop branch and the Yún should have the Climaduino code from its Develop branch. Both have README files that are not great (remember the Develop branch is very much a work in progress), but give a general idea of some of the steps that are needed to get it up and running.

    Time-permitting I really want to make this a lot easier to deploy. Maybe some sort of installer routine and better documentation. If you see any areas where a specific type of documentation would help or something is very unclear, let me know. That way I can improve those parts and we can work together to make this project even better and easier for anyone to use.