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