Project in progress
IR Controller for Air Conditioner

IR Controller for Air Conditioner © GPL3+

Control your AC from across the room or across the world

  • 37,853 views
  • 10 comments
  • 26 respects

Components and supplies

About this project

My goal is to make my window AC units more functional.  Currently they use an on-board thermostat to turn on when the room gets above a certain temperature ('duh).  I feel like there is a lot I can do to improve on both the efficiency (less electricity usage) and performance (cooler house throughout the day).

I'm going to break this out into phases and post my progress along the way.  I plan on incorporating this into a current Home Automation project I'm working on, so when I have the final version I will create a new project with start to finish build instructions.

Phase I

Control the existing remote with an Arduino (or ATtiny85).  I just want to build a platform that I can add additional sensors and communication abilities to.

I took apart the remote and it looks easy enough to hack. It's powered by two AA batteries in series (3vDC) and the buttons each have their own through holes on the PCB.  I used an L78L33 voltage regulator to drop the USB 5v to 3.3v for the remote power (it gets really hot, so I'll be replacing that in the next phase).  The brain is an ATtiny85 with pin6 driving an S8050 PNP transistor to open/close the circuit for the Air Conditioner power button on the remote.  Right now it's just sending the IR power signal every 30 seconds as a test. 

I also added a DHT11 temperature/humidity sensor and adapted my AV Cabinet Fan Controller code to work as a simple thermostat from across the room.

Phase II 

I have the arduino closing the connections for the tempup and tempdown buttons on the remote to put the thermostat at the min or max setting.  The AC unit is always powered on, but by adjusting the thermostat I can make the compressor and fan kick on while letting it use the built in cooldown settings.  On standby the unit pulls less than 2 watts.

I would rather not rely on the physical remote to turn on/off the AC unit so the next step is to emulate the IR signal using just an Arduino Nano. I followed the IR tutorial from Lady Ada to get the raw IR signal from the remote and use those to drive an IR LED directly, emulating the signal from the remote. 

One hurdle I had was simulating a long press using the IR signal since my AC unit beeps each time a button is pressed.  I did this using a "for" loop in the Arduino sketch but the delay required a bit of trial and error, so I used my IR receiver/blaster test board to try several different configurations.

Phase III (in development)

Now that the we have a stand alone 'dumb' temp controller, I need to give this some real intelligence. By adding an ESP8266 I can remotely control this from my phone and send the current temperature to thingspeak.com or my central home automation server to be logged and graphed.

My home automation project pulls weather data from the wunderground API to work out the most efficient time to kick on the AC based on the hourly heat forecast for the day.  It is also being integrated with my SmartThings and Frontpoint systems to know who is home, if there are any windows open, and which rooms are occupied.  HAI can use all of this data to manually override the thermostat and turn on or off the AC through this connected IR controller.  

What's next?

I'm building more WiFi temperature sensors to collect temps and humidity in other rooms in the house.  This will be logged directly to HAI so she can use that data to control vent ducts that direct airflow from our central heater to specific zones of the house during winter.

Code

WiFi AC ControllerC/C++
This sends temp and humidity to the central server every few minutes. Raw IR signals are sent directly to emulate the temperature up/down buttons on the AC unit's remote. Since my unit beeps when the temp is changed, I had the sketch check if the unit is already in the correct state before resetting the thermostat. When the temp is changed, I'm emulating a long button press so that it doesn't beep for each degree up or down. If your unit requires a button push for each degree, extend the delay in the for loop and change the number of times it loops to the number of degrees in each direction.
// AC Unit Controller by Buddy Crotty
// Temp is set manually in this sketch
// Additional settings will be pulled from HAI in checkserver() function in a later release
// Temp and humidity are sent to HAI server for logging
// IR blaster is using RAW IR codes to set AC thermostat at min/max values to force AC to turn on/off

const char* host = "192.168.1.80";           // Internal IP of (Home Automation w/ Intellegence) Webserver
const char* devID = "downstairs";            // Device ID (single word, no spaces, no special characters)

#include <IRremote.h>
#include <SoftwareSerial.h>
#include "DHT.h"                              // Written by ladyada, public domain
IRsend irsend;   
SoftwareSerial ser(10, 11); // (RX, TX)       // Software serial for controling ESP8266 Module
                                              // Hardware serial for debugging


int khz = 38; // 38kHz carrier frequency 
// Insert RAW IR signal for "Temperature Up"
unsigned int irSignalUp[] = {8350,4150, 550,1550, 550,1550, 550,1550, 550,500, 550,1550, 550,550, 500,1600, 500,1600, 500,4150, 550,500, 550,550, 500,550, 500,1600, 500,550, 500,550, 550,500, 550,550, 600};  // UNKNOWN CE608146 TempUp
// Insert RAW IR signal for "Temperature Down"
unsigned int irSignalDown[] = {8350,4150, 550,1550, 550,1550, 550,1600, 500,550, 500,1600, 500,550, 500,1600, 500,1600, 500,4200, 500,1600, 500,550, 500,550, 500,1600, 550,500, 550,500, 550,550, 500,550, 600};  // UNKNOWN 3F3D09A5 TempDown
// IR pin is digital pin 3                                             
int ACTEMP = 85;        // Default temp at which the AC turns on (85*F)
const int numReadings = 10;  // Readings used for average
#define DHTPIN 2        // DHT Sensor
int ACON = 0;           // AC state. Assumes AC is off on first boot

// Uncomment whatever type you're using
#define DHTTYPE DHT11   // DHT11, DHT22 or DHT21

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);

// Set variables to zero
float avetemp = 0;                
float temp = 0;

/*
 * next up is adding a timer instead of delays
unsigned long tempMillis = 0;             // will store last time temp was updated
unsigned long serverMillis = 0;           // will store last time server was updated
unsigned long postMillis = 0;             // will store last time temp was posted
unsigned long ACMillis = 0;               // will store last time AC was checked
const long tempival = 30000;              // interval to check temp (every 30 seconds)
const long servercheckival = 60000;       // interval to check server config (every minute)
const long temppostival = 900000;         // interval to post new temp stats (every 15 minutes)
const long ACcooldown = 300000;           // time to wait if AC is already on (5 minutes)
*/

void setup() {
  Serial.begin(9600);
  ser.begin(9600);

  /*
  // Uncomment to reset WiFi settings
    delay(1000);
    ser.println("AT+CWMODE=1");
    ser.println("AT+CWJAP=\"SSID\",\"Password\"");
  */

  delay(2000);
  dht.begin();

  Serial.println("IR controlled AC Started");
  
  dht.begin();
 
  Serial.println("Giving everything a chance to warm up");          //wait 25 seconds for WiFi to connect
  Serial.println("|-------------------------|");
  Serial.print("|");
  for(int x = 0; x < 25; x++){
    Serial.print("#");
    delay(1000); 
  }
  Serial.println("|");
  Serial.println("Done");
}

void checkserver() {
  // Update thermostat setting (ACTEMP=##) from HAI
  // Thermostat override with TurnACon=true or TurnACoff=true
}

void turnACon() {
  // Run IR code to turn on AC
    Serial.print("Temperature is over ");
    Serial.print(ACTEMP);
    Serial.print(", AC is on (for 5 minutes)");
      // Send IR signal to turn AC Unit ON
      // Turn thermostat all the way down to make AC kick on
      for (int x = 0; x <250; x++){
        irsend.sendRaw(irSignalDown, sizeof(irSignalDown) / sizeof(irSignalDown[0]), khz); 
        delay(22);  
      }
    ACON = 1;
    delay(285000);                                // turn on minimum of 5 min (subtracted 15 seconds for gettemp)
}

void turnACoff() {
  // Run IR code to turn off AC
    Serial.print("Temperature is under ");
    Serial.print(ACTEMP);
    Serial.println(", AC is off");   
      // Send IR signal to turn AC Unit OFF               
      // Turn thermostat all the way up so that AC never kicks on
      for (int x = 0; x <250; x++){
         irsend.sendRaw(irSignalUp, sizeof(irSignalUp) / sizeof(irSignalUp[0]), khz); 
         delay(22);  
      }
    ACON = 0; 
    delay(15000);                             // When AC is off, Temp is read every 30 seconds (15+15)
}

void gettemp() {
  // pull temp from sensor and send to server
  // whole process takes about 
    Serial.print("Realtime Temp: \t");

  // Average temp over numReadings * delay
  temp = 0;
  for (int x = 0; x < numReadings; x++){
    float f = dht.readTemperature(true);            // Read temperature as Fahrenheit
    Serial.print(f);
    Serial.print("\t");
    temp = f + temp;
    delay(1000);                                    // delay in between reads for stability  
  }    
  Serial.println();

  avetemp = temp / numReadings;                     // calculate the average
    int h = dht.readHumidity();
    float hi = dht.computeHeatIndex(avetemp, h);    // convert to 'feels like' temp (heat index based on humidity)
  Serial.print("Average Temp is ");
  Serial.println(hi);                               // send it to the computer as ASCII digits

  // Check if any reads failed and exit early (to try again).
  if (isnan(hi)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

// Output values being sent to ThingSpeak/local web server
  Serial.print("Temperature: "); 
  Serial.print(avetemp);
  Serial.print(" *F\t");
  Serial.print("Heat Index: ");
  Serial.print(hi);
  Serial.println(" *F");  
  Serial.print("Humidity: "); 
  Serial.print(h);  
  Serial.println("%\t");  
  Serial.print("...connecting to ");
  Serial.println(host);  
  
  // TCP connection
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += host;             
  cmd += "\",80";
  ser.println(cmd);
    delay(1000); 
  if(ser.find("Error")){
    Serial.println("AT+CIPSTART error");
    return;
  }
  else{
  }

  // prepare GET string
  String getStr = "GET /tempupdate.php?ID=";
  getStr += devID;
  getStr += "&field1="; //Temp
  getStr += avetemp;
  getStr += "&field2="; //Humidity
  getStr += h;
  getStr += "&field3="; //Heat Index
  getStr += hi;
  getStr += "\r\n\r\n";

  Serial.print("Sending data URL: ");
  Serial.println(getStr);

  // send data length
  cmd = "AT+CIPSEND=";
  cmd += String(getStr.length());
  ser.println(cmd);

  if(ser.find(">")){
    ser.print(getStr);
    Serial.println("Success!");
  }
  else{
    ser.println("AT+CIPCLOSE");
    Serial.println("Connection Failed");            // alert user
  }
}

void loop() {
  // Get updated settings from server
  checkserver();

  // read the sensor and send results to server
  gettemp();
  
  // if room is cool and AC is off, do nothing
  if (avetemp<ACTEMP && ACON==0){
    Serial.print("Temperature is ");
    Serial.print(avetemp);
    Serial.println(", AC is already off");           
    delay(15000);                             // When AC is off, Temp is read every 30 seconds (temp read takes 15 seconds)
  }
  
  // if room is hot and AC is already running, do nothing
  if (avetemp>ACTEMP && ACON==1){
    Serial.print("Temperature is ");
    Serial.print(avetemp);
    Serial.println(", AC is already on");           
    delay(285000);                             // When AC is on, Temp is only read every 5 min 
  }

  // Turn off AC if room is already cooled
  if (avetemp<ACTEMP && ACON==1){
    turnACoff();
    }

  // Turn on AC if room is too warm
  if (avetemp>ACTEMP && ACON==0) {
    turnACon();
    }

  Serial.println();
  Serial.println();
  
}

Schematics

IR Blaster Schematic
Ir blaster schem
IR AC Controller
This would be the schematic for IR and an ATtiny85. Currently, I am using an Arduino Nano and controlling the buttons on the existing AC remote.
Ir blaster schem
IR AC Controller
This would be the schematic for an ATtiny85 (my prototype is using an Arduino Nano). I'm also not currently using a resistor with the LEDs since they are in series and only flash for a very short time.
Ir blaster schem

Comments

Similar projects you might like

WiFi IR Blaster

Project tutorial by BuddyC

  • 85,587 views
  • 43 comments
  • 89 respects

Developing an IR Remote and Software Controller

Project tutorial by Steve

  • 18,069 views
  • 0 comments
  • 35 respects

Zoned Climate Control with MediaTek's LinkIt™ Smart 7688

Project tutorial by BuddyC

  • 7,716 views
  • 5 comments
  • 18 respects

OH HAI! on Windows 10 IoT Core

Project in progress by BuddyC

  • 12,530 views
  • 3 comments
  • 48 respects

IoT arduino ESP Garage Door opener (UD)

Project in progress by David Smerkous

  • 10,854 views
  • 6 comments
  • 16 respects
Add projectSign up / Login