Introduction: Arduino Thermostat (Mechanical)

About: I hope to help people with the things I make.

I am currently living in a college dorm. Like most dorms it's about the size of a tissue box but less comforting. Fortunately, my room has a heater/AC with four positions: low, medium, high, and off. Unfortunately in winter an hour on the low setting makes the room a stifling 80 degrees and when turned off it drops quickly to 60 degrees. My solution uses an arduino, temperature sensor, and motor to automatically turn the heater on/off to keep the room within a desired temperature range. Not only is this more comfortable but it dramatically reduces the time the heater is used, saving lots of energy. (Also note that the motor is only driven to switch the setting and then turned off so no holding energy is wasted.)

So for anyone in an apartment/dorm/etc that has a heater with manual settings I offer you a custom, cheap, and green solution!

To get a better idea on the reduction in energy usage I took data over a 24 hour period of use. The heater was only on for 23% of the time and stayed within the temperature range (68-72) the entire night (average temp outside was 22 degrees)! I'm working on a way to get the data turned into graphs, should be up soon.

I've attached a video of an early test. Nothing exciting but it gives you an idea of how it works. The cardboard was used as a quick fit, I later printed a part to hold the motor stable during extended use. It's tough to tell when the motor turns on but you can see the wire jerk when this happens and hear a low hum of the heater.

Step 1: Parts List

1x Arduino Uno - $30
1x Micro Servo - $6
1x TMP36 Temperature Sensor - $2
1x Small Breadboard - $5
1x Arduino Power Supply - $6
A few wires
Cardboard

Total cost to buy all components from Adafruit comes to $49, and if you already have an arduino or can get one for cheaper elsewhere (I encourage you to check other sites as well) then the rest of the components costs a measly $19!

(Also note that if your heater/AC is difficult to manually twist the knob you may need a beefier servo than what I am suggesting!)

Step 2: Breadboarding

Breadboarding the components is a fairly simple task for this project. First we will connect the black servo wire to ground, the red servo wire to the 5V out pin on the arduino, and the yellow servo wire to the 11 digital input pin on the arduino (can be any but that is what I used for my code). 

Next we will wire the digital temperature sensor. With the round side facing you attach the rightmost pin to the 3.3V out pin and AREF (above the digital input pins), the middle pin to the analog input pin A1, and the leftmost pin to ground. 

Check the picture if you are confused!

Step 3: The Program

Now that you have it all wired up we can test that the motor is functional and the temperature sensor is accurate. If you've never used arduino before you can download the IDE and learn more about it HERE. I've attached my full code below. To quickly change the temperature you can just pinch the sensor between your fingers to heat it up. My full code is below. Make sure the motor signal is attached to the digital input pin 11 and the temperature sensor is attached to analog pin A1. 

#include <Servo.h>
#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!
Servo motor;
int offPos = 500, onPos = 1800, wait = 10000; // adjust offPos and onPos until the motor just barely turns on and off your heater/AC
float tempLow = 68.0, tempHigh = 72.0, temperatureF; //  Adjust tempLow and tempHigh to the range of temperature you want the room kept at
boolean heat = false;

int tempPin = 1;        //the analog pin the TMP36's Vout (sense) pin is connected to
                        //the resolution is 10 mV / degree centigrade with a
                        //500 mV offset to allow for negative temperatures
int tempReading;        // the analog reading from the sensor

void setup(void)
{
  Serial.begin(9600);  
  analogReference(EXTERNAL);
  turnOff();
}

void loop(void)
{
  readTemp();
  checkTemp();
  delay(wait);
}

void readTemp()
{
  tempReading = analogRead(tempPin); 

  // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage;
  voltage /= 1024.0;

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree with 500 mV offset
                                               //to degrees ((volatge - 500mV) times 100)
  // now convert to Fahrenheight
  temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
  Serial.print(temperatureF); Serial.println(" degrees F");
}

void checkTemp()
{
  if(temperatureF < tempLow && heat == false)
  {
    turnOn();
  }
  else if(temperatureF > tempHigh)
  {
    turnOff();
  }
}

void turnOff()
{
    motor.attach(11);
    delay(1000);
    motor.writeMicroseconds(offPos);
    delay(1000);
    motor.detach();
    delay(1000);
    heat = false;
}

void turnOn()
{
    motor.attach(11);
    delay(1000);
    motor.writeMicroseconds(onPos);
    delay(1000);
    motor.detach();
    delay(1000);
    heat = true;
}

Step 4: The Mechanical System

Now it's time to attach the servo to the knob that sets the heating temperature. I did this by 3D printing a piece I mounted onto my servo horn. This can be done in many ways with whatever materials are available (wood/cardboard/plastic/etc) just use a little creativity. As you can see I made a mount out of cardboard to hold the servo in place for testing. What you use will be very specific to the layout of your heater and servo motor, so I unfortunately can't help you too much here. 

Step 5: Tweaking

Once you have the servo mounted on top of the heater/AC you will need to run the program and make small adjustments to the code for the positions of the motor to turn your thermostat on and off and define the temperature range you want. the first 5 lines of code I have copied below. You will have to change the 4th and 5th lines accordingly. The only way to determine the motor positions is through trial and error. 

#include <Servo.h>
#define aref_voltage 3.3  
Servo motor;
int offPos = 500, onPos = 1800, wait = 10000; // adjust offPos and onPos until the motor just barely turns on and off your heater/AC
float tempLow = 68.0, tempHigh = 72.0, temperatureF; //  Adjust tempLow and tempHigh to the range of temperature you want

Step 6: Finishing Touches

Now that you have everything set up and working you may want to add a nice box to set your arduino and breadboard inside. I 3D printed one with a apple and windows logo on the cover. You will also want to switch to a DC arduino power supply rather than using the usb cable to power it. Now you should be all set up!

Green Electronics Challenge

Second Prize in the
Green Electronics Challenge

Sensors Contest

Participated in the
Sensors Contest

Gadget Hacking and Accessories Contest

Participated in the
Gadget Hacking and Accessories Contest