Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
BuddyC
Published © GPL3+

IR Controller for Air Conditioner

Control your AC from across the room or across the world

IntermediateWork in progress53,299
IR Controller for Air Conditioner

Things used in this project

Story

Read more

Schematics

IR Blaster Schematic

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 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.

Code

WiFi AC Controller

C/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();
  
}

Credits

BuddyC

BuddyC

10 projects • 102 followers
I collect hobbies.

Comments