Friday, August 13, 2010

Thermostat

So lately I've been playing with a new toy: The Arduino. It's a microcontroller prototyping board. Quite fun. I bought a kit which came with all sorts of sensors and LEDs/motors/etc.

So the first real project (other than making lights blink in fun patterns) was a thermostat for our air conditioning. Here's a little description of the layout:

Sensors:
Temperature Sensor - basically a thermal resistor. Every degree Celsius translates to a 5mV change in voltage.
Potentiometer - a variable resistor, most frequently used in stereos for volume control. (Think walkman wheel control)

Output:
8 LEDS (4 Green, 4 Red) - This is my crude display for binary/ hex data. The red lights display one hex digit, the green the other. This displays the current value the potentiometer is set at (the triggering temperature);
Servo Motor - I have this motor set to turn 100 degrees in the event that the temperature is too high (turning on the A/C) and turn back if it drops down again.

The code is pretty simple. Read in the values, tweak the numbers a bit so they are in the range we want them to be. Then there's a simple if/else statement dealing with the temperature. I have it polling every second, but in reality I could probably lower it to once a minute.

Enjoy!

EDIT: after leaving it to run overnight, I found it not working in the morning. My wife suggested that it drained the battery. After looking at it, I think having it poll so often uses way too much power. I switched it to be powered off of USB instead, and changed the polling interval to 5 minutes.





#include

Servo myservo;
int leds[] = {2,3,4,5,6,7,8,9};
int control = 1;
int temp = 0;
int pos = 0;
int sensorValue = 0;

void setup(){
myservo.attach(10);
for (int i = 0; i < 8; i++){
pinMode(leds[i],OUTPUT);
}
}

void loop(){
sensorValue = analogRead(controlc);
int maxTemp = sensorValue / 10 + 10; //(use F values between 10 and 112)
writeFF(maxTemp);
float temperature = analogRead(temp) * .004882814;
temperature = (temperature - 0.5) * 100 * 1.8 + 32; // convert to F
if (temperature > maxTemp){
myservo.write(100);
} else {
myservo.write(0);
}
delay(1000);
}

void writeFF(int a){
int values[8];
for(int i = 0; i < 8; i++){
values[i] = a % 2;
a = a / 2;
}
for (int i = 0; i<8;i++){
digitalWrite(leds[i],values[i]);
}
}

7 comments:

  1. Very nice indeed, however I believe your battery trouble stems from the power regulator, not the Arduino. The LM8705 on the board burns off the extra voltage by shunting it to ground and therefor really kills battery life. Even with no load it's putting 4 of the 9 input volts to ground to give you that stable 5v out. My suggestion would be to use a wall wart. Or maybe using a boost converter and bypassing the voltage regulator.

    ReplyDelete
  2. Great simple implementation, can I ask what kit, or what servo you got exactly?

    ReplyDelete
  3. You could also save a lot of power by using the sleep function to put the arduino to sleep until it needs to read again... And yes, get rid of the 7805. Use a switching regulator to get better results.

    Congrats on making it on HackaDay.com

    ReplyDelete
  4. broken: Here's a link to the kit: http://www.adafruit.com/index.php?main_page=product_info&cPath=17&products_id=170&zenid=6ce2a07a1aed2efd1d4309105276d949


    I wanted to start developing some arduino projects and figured a kit like this would give me enough to build something useful. The servo is the one in the kit:
    http://www.adafruit.com/index.php?main_page=product_info&cPath=34&products_id=169

    ReplyDelete
  5. You need to get a girlfriend, dork! Oh wait...you are married. You and Linda need to start having kids. Definitely too much time on your hands.

    ReplyDelete
  6. the 7805 is a series regulator NOT a parallel regulator like a zener diode which does shunt current to ground, it doesn't waste power

    ReplyDelete