Introduction: How to Control the Air Conditioner A/C at Home With Arduino, Even Remotely!

About: I'm an Arduino Maker, I like technology, playing tennis

Arduino really allows you to do many things concerning the Internet of things, just have a little 'desire and intuition to create any type of project.
In this post we will see how to remote control your air conditioner at home, through the Arduino, which is connected to the Internet. Yes, you just read that right!

Requirements hardware

• 1 x Arduino Uno + 1 x or 2 x Arduino Mega Arduino Uno
• IR receiver TSOP1738
• IR LED
• 1 x 330 Ohm resistor
• Some flexible cable

Requirements software

Library iRemote Arduino
Programs available in my Github repo


Step 1: How Does the System Work ?

As many will know , the mechanism of regulation of various settings between user and conditioner , is via a remote control , which is based on sending infrared signals . To investigate the function of these signals , I recommend you look at the post in reference to Chapter 10 of the Arduino design becomes simple (in Italian).
Obviously , the code of an air conditioner , vary depending on the model and according to the manufacturer. For this reason, as the first phase of the work , you must do the procedure that is called reverse engineering , that is to obtain the codes for your device , using the sensor TSOP1738 .
Once you have obtained the codes for your air conditioner, we're almost to complete "the work ." You need to use a small program that simplifies setting the code to insert into the Arduino , and you can send the various encodings . These codes can be set by the user through a simple web page , with or without protection.
As you have read in the " Hardware requirements " , I wrote that you need two Arduino , the main reason is that the sequences of bits to be sent to the air conditioners are too large to be contained in a single device , which among other things should also take care of the part of management commands that will be transmitted via the Internet.
In practice there will be a device that will take care of the part webserver and the other to send IR signals . The other reason that prompted me to do this project with two device , is that you can safely use Raspberry PI for the management of the webserver , so definitely improve the look and feel of the web page.

Step 2: How to Set Up the Various Data

As stated in the previous rows, you must obtain encodings of our remote control to retransmit them to the Arduino. To do this we will make use of the library for Arduino iRemote, in particular this code:

/* Modified by Chris Targett
* Now includes more protocols
* Novemeber 2011

* IRremote: IRrecvDump - dump details of IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*
* Modified by Chris Targett to speed up the process of collecting
* IR (HEX and DEC) codes from a remote (to put into and .h file)
*
*/

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
//  decode_results *results = (decode_results *)v
void dump(decode_results *results) {
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.print("Unknown encoding: ");
  }
    else if (results->decode_type == NEC) {
    Serial.print("Decoded NEC: ");
  }
  else if (results->decode_type == SONY) {
    Serial.print("Decoded SONY: ");
  }
  else if (results->decode_type == RC5) {
    Serial.print("Decoded RC5: ");
  }
  else if (results->decode_type == RC6) {
    Serial.print("Decoded RC6: ");
  }
  else if (results->decode_type == SAMSUNG) {
    Serial.print("Decoded SAMSUNG: ");
  }
  else if (results->decode_type == JVC) {
    Serial.print("Decoded JVC: ");
  }
  else if (results->decode_type == PANASONIC) {
    Serial.print("Decoded Panasonic: ");
  }
  Serial.print(results->value, HEX);
  Serial.print("(");
  Serial.print(results->bits, DEC);
  Serial.println(" bits)");
  Serial.print("#define Something_DEC ");
  Serial.println(results->value, DEC);
  Serial.print("#define Something_HEX ");
  Serial.println(results->value, HEX);
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");
  for (int i = 0; i < count; i++) {
    if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    }
    else {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println("");
}

void loop() {
  if (irrecv.decode(&results)) {
    dump(&results);
    irrecv.resume(); // Receive the next value
  }
}

You can see in the picture how to link Arduino with the device.

After loading the code on the Arduino, we should press the buttons on the remote control and copy somewhere the results shown by the serial.
In my case, I got the following sequence of encodings:

Accensione 20 C° Caldo
Raw (150): -5320 3000 -3000 3000 -4400 550 -1600 600 -550 550 -1650 550 -550 550 -550 550 -1650 550 -550 550 -1650 500 -550 550 -1650 550 -550 550 -500 600 -500 600 -550 550 -550 550 -1650 500 -550 550 -600 500 -1700 500 -550 550 -550 550 -550 550 -600 500 -550 550 -550 550 -550 550 -550 550 -1650 550 -1650 550 -1650 500 -1650 550 -1650 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -1650 550 -500 550 -550 550 -1700 500 -1650 550 -550 550 -500 600 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 500 -1700 500 -550 550 -550 550 -550 550 -550 550 -550 550 -600 500 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -500 550 -1700 500 -550 550 -550 550 -550 550 -1650 550

Spegnimento
Raw (150): -3276 3100 -2900 2950 -4400 700 -1500 700 -400 700 -1500 700 -400 650 -450 550 -1650 550 -550 650 -1500 600 -500 600 -1600 600 -500 600 -500 600 -450 650 -450 600 -550 550 -550 550 -550 550 -600 500 -1600 600 -500 600 -500 600 -550 550 -500 600 -500 600 -550 550 -550 550 -1600 600 -500 600 -500 600 -500 550 -1650 550 -1600 600 -500 600 -500 600 -550 550 -550 550 -1600 600 -1600 550 -550 550 -550 550 -1650 550 -1600 600 -550 550 -500 600 -500 600 -550 550 -550 550 -500 600 -500 600 -1600 600 -1600 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -500 600 -550 550 -550 550 -500 600 -500 600 -500 600 -1600 600 -500 600 -1600 550 -550 550 -1600 600 -550 550 -550 550

Accensione 23 C° Freddo 2 FAN
Raw (150): -16044 3050 -3000 3000 -4400 550 -1600 600 -550 550 -1650 550 -550 550 -550 550 -1650 550 -500 600 -1600 550 -550 550 -1650 550 -1650 550 -1650 550 -550 550 -550 550 -500 600 -1600 550 -550 550 -550 550 -1650 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -500 600 -1650 500 -550 550 -600 500 -1700 500 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -1650 550 -550 550 -500 550 -1650 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -550 550 -550 550 -550 550 -550 550 -500 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -1600 600 -550 550

Accensione 20 C° Caldo e Swing
Raw (150): 18566 3000 -3000 3000 -4400 550 -1650 550 -500 600 -1600 600 -500 600 -500 600 -1600 550 -550 550 -1650 550 -500 600 -1600 600 -550 550 -550 550 -550 550 -1600 600 -500 600 -500 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -550 550 -1600 550 -550 550 -600 500 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -1650 550 -550 550 -550 550 -1600 550 -1650 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -1650 550 -550 550 -550 550 -550 550 -550 500 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -1650 550 -1650 500 -1650 550 -550 550 -1700 500

Accensione 23 C° Freddo 2 FAN e Swing
Raw (150): 2084 2950 -3050 2950 -4400 550 -1600 600 -550 550 -1650 550 -550 550 -550 550 -1600 600 -500 600 -1600 550 -500 600 -1650 550 -1650 550 -1600 600 -500 600 -1600 600 -500 600 -500 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -500 600 -550 550 -500 600 -1650 550 -550 550 -1600 600 -500 600 -1600 550 -1600 600 -500 600 -500 600 -550 550 -500 600 -1650 550 -1600 600 -500 600 -500 550 -1650 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -500 600 -500 600 -500 600 -500 600 -500 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -550 550 -1650 550 -1650 550 -1600 600 -1600 550 -550 600 -500 550 -550 550 -550 550

As reported in the library iRemote, in order to retransmit these data, it is necessary to make some changes, in particular, need to replace the hyphens, delete the first value and place among the various values​​, a comma, as in the Arduino code will be inserted in a vector of integers.
To facilitate this, I created a small program in Java that can do these tasks automatically.
Also this program is available in the Github repo and is called AcToolArduino. In this first version, the program automates the process by entering the information in the TextField. In the next version, you can load from file, the results obtained from the serial Arduino.

Step 3: Sending IR Command to A/C

With the following code, you will be able to send IR command to A/C via Arduino:

#include "IRremote.h"

IRsend irsend;

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

int khz=38; //NB Change this default value as neccessary to the correct modulation frequency
// ON and 2O C° with 1 FAN heat
unsigned heat[] = {3000,3000,3000,4400,550,1600,600,550,550,1650,550,550,550,550,550,1650,550,550,550,1650,500,550,550,1650,550,550,550,500,600,500,600,550,550,550,550,1650,500,550,550,600,500,1700,500,550,550,550,550,550,550,600,500,550,550,550,550,550,550,550,550,1650,550,1650,550,1650,500,1650,550,1650,550,550,550,550,550,550,550,550,550,1650,550,1650,550,500,550,550,550,1700,500,1650,550,550,550,500,600,550,550,550,550,550,550,550,550,550,550,1650,500,1700,500,550,550,550,550,550,550,550,550,550,550,600,500,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,500,550,1700,500,550,550,550,550,550,550,1650,550};
// OFF the A/C
unsigned OFF[] = {3100,2900,2950,4400,700,1500,700,400,700,1500,700,400,650,450,550,1650,550,550,650,1500,600,500,600,1600,600,500,600,500,600,450,650,450,600,550,550,550,550,550,550,600,500,1600,600,500,600,500,600,550,550,500,600,500,600,550,550,550,550,1600,600,500,600,500,600,500,550,1650,550,1600,600,500,600,500,600,550,550,550,550,1600,600,1600,550,550,550,550,550,1650,550,1600,600,550,550,500,600,500,600,550,550,550,550,500,600,500,600,1600,600,1600,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,500,600,550,550,550,550,500,600,500,600,500,600,1600,600,500,600,1600,550,550,550,1600,600,550,550,550,550};
// ON and 23° with 2 FAN cold
unsigned cold[] = {3050,3000,3000,4400,550,1600,600,550,550,1650,550,550,550,550,550,1650,550,500,600,1600,550,550,550,1650,550,1650,550,1650,550,550,550,550,550,500,600,1600,550,550,550,550,550,1650,550,550,550,550,550,550,550,550,550,550,550,550,550,500,600,1650,500,550,550,600,500,1700,500,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,1650,550,550,550,500,550,1650,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,550,550,550,550,550,550,550,550,500,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,1600,600,550,550};
// ON and 20 C° with 1 FAN heat and SWING
unsigned heat_with_swing[] = {3000,3000,3000,4400,550,1650,550,500,600,1600,600,500,600,500,600,1600,550,550,550,1650,550,500,600,1600,600,550,550,550,550,550,550,1600,600,500,600,500,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,550,550,1600,550,550,550,600,500,550,550,550,550,550,550,550,550,550,550,1650,550,1650,550,550,550,550,550,1600,550,1650,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,1650,550,550,550,550,550,550,550,550,500,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,1650,550,1650,500,1650,550,550,550,1700,500};
// ON and 23° with 2 FAN cold and SWING
unsigned cold_with_sqwing[] = {2950,3050,2950,4400,550,1600,600,550,550,1650,550,550,550,550,550,1600,600,500,600,1600,550,500,600,1650,550,1650,550,1600,600,500,600,1600,600,500,600,500,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,500,600,550,550,500,600,1650,550,550,550,1600,600,500,600,1600,550,1600,600,500,600,500,600,550,550,500,600,1650,550,1600,600,500,600,500,550,1650,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,500,600,500,600,500,600,500,600,500,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,1650,550,1650,550,1600,600,1600,550,550,600,500,550,550,550,550,550};

void loop() {

irsend.sendRaw(heat, sizeof(heat)/sizeof(int), khz);
delay(10000);
irsend.sendRaw(OFF, sizeof(OFF)/sizeof(int),khz);
delay(10000);
}

If we went out to operate the air conditioner at home, we are well on track to complete the project!
As indicated previously, it is necessary to use two Arduino, one that manages the webserver, the other that handles the communication with the air conditioner.
To connect the two Arduino in a correct way, care should be taken to the below image.
On the device connected to the Ethernet Shield is necessary to load the program that takes the name of AC_Webpage_Controller.ino, while nell'Arduino that will send IR commands, you must load the program that takes the name of AC_Sender_Code.ino. You can find the software on my Github repo https://github.com/jackbell16/AC-Progetto-Arduino/tree/master/Arduino_Code

Now that we have completed the loading process, we just have to do some work to improve the project, the most useful, is to make it accessible from a remote webserver. To do that we should "open the doors" of our router to properly route requests that are made outside of our local network.
It should be stated that in the version of the code on Github reported, there is no level security password, to simplify a bit 'the project. However, with some modifications to the code AC_Webpage_Controller.ino, you can also implement this feature.

Step 4: Port Forwarding, to Put the Arduino and A/C on the WEB

The operation of port forwarding, it varies from router to router, but in general, you can proceed as follows:

• Identify the IP address of the webserver Arduino
• Identify the IP address of the gateway
• Open your browser and type the IP address of your router and enter the credentials
• Open the port forwarding section and enter data such as the IP port as the Arduino and 80.

Now we could also access outside of our local network, simply by opening a web page with the public IP of your ADSL connection (to retrieve this value, simply type on Google.com "my ip").
Now we can finally test our project!



Step 5: Download the Android Application !

If you don't want to use the webpage, you can download the application for Android !

You can do this by typing RemoteAC from the Play Store, or use this link:

https://play.google.com/store/apps/details?id=com....

Remember that once you open the application you need to set the IP of Arduino in the preferences !

Spring's Coming Contest

Participated in the
Spring's Coming Contest