Introduction: Reverse Engineering Air Conditioner IR Remote Control Protocol

Hi, this is my first instructable, hope you like it.

To get into electronics I chose a home automation project: a system allowing me to control and program both air conditioner units in my flat. In this instructable I show how I got to understand the IR protocol.



Material:

- Panasonic inverter air conditioner remote control
- Raspberry Pi with raspbian and lirc installed
- 38kHz Infrared (IR) Receiver Module (for instance RadioShack Catalog #: 276-640)
- breadboard

The raspberry Pi is useful in my setup to analyse the incoming IR signals, but also to host other components on the global project. Any other computer equipped with an IR receiver could do. An Arduino could also output the needed information using the IRremote library (https://github.com/shirriff/Arduino-IRremote). This library will be used to control the air conditioners in the end.

The method used here could work with other remote protocols (with adaptations).

Please excuse the screen caps that don't show exactly the same output format: this part of the project was done during last summer and I used files generated by multiple versions of the codes I wrote.

Step 1: The Remote to Study

The remote shows multiple options to transmit:
- The target temperature to achieve
- The "mode" ("cool","heat","dry", "auto")
- The air flow swing (5 possible positions, and one automatic mode)
- The fan speed
- A powerful or quiet option (which impacts the fan speed (and more?))
- 2 timers: one to turn off the unit after a certain amount of time, one to bring it back on

One thing to know is that usual remotes controls, for TV, HI-FI, ... send a signal for each key pressed (often in loops while the key is pressed). An air conditioning remote often displays information about the parameters selected. But of course parameters can be changed on the remote while the unit is out of reach, which could lead to synchronization problems between the display and the unit in some cases if it worked like the TV remotes. This implies that when such a remote sends a signal, it sends the whole parameters set. What we'll do is then study what signals are sent to try and understand which part of the signal is for which parameter.

Step 2: Gathering Data

Off we go.
Note1: command recording is a repetitive and slightly boring process, but necessary.
Note2: I don't own an oscilloscope so the only way for my to plot the recorded values is to use a plotting program (gnuplot) on raw data. This can useful to have a visual idea of what happens, but it requires some adaptation in raw data and is in my opinion not necessary at all. For that reason I have not included any graph.

I used the instructions from this page: http://alexba.in/blog/2013/01/06/setting-up-lirc-... to plug the receiver on the Pi and prepare lirc.
I then recorded commands with the -raw option and redirected output to a file. The goal is to have a record of each value for ON and OFF of course, but also for each mode (AUTO, COOL, HEAT, DRY), for each swing and fan value, and, say, for min and max temperature (16 to 30°C in my case). The important part here is to make a reference record and to make a recording for each change of option, making only one option change every single time. Once a record is done, press CTRL+C to terminate the command and do it again with the next command/file

$ mode2 -d /dev/lirc0 -m > auto_21C_swing0_fan0

It could be necessary to gain super privileges to run this command ("sudo mode2 ...") and the lirc daemon can block the file, so it may be necessary to kill it first:

$ sudo /etc/init.d/lirc stop
$ sudo mode2 -d /dev/lirc0 -m > filename
$ [...]
$ sudo /etc/init.d/lirc start

When reading the generated files, what we see is all numbers, organized in 6 columns. These numbers indicate durations in microseconds. The columns work in pair, so

740   1495   920   1345  735   1335

means : "the IR LED was ON for 740us, then OFF for 1495us, then ON for 920us, then OFF for 1345us, etc."

Exemple :

3523     1766      414      451      418     1312
      423      448      419      452      418      452
      428      443      417      453      418      457
      418      452      418      452      416      454
      419      452      417      453      417     1316
      418      452      418      466      410      451
      419      453      414      457      416      452
      418      453      417     1316      418     1315
      418     1320      426      443      419      451
      419     1314      419      452      418      452
      418      452      418      452      418      457
      419      450      420      451      419      452
      421      451      417      452      418      452
      418      452      419      457      418      452
      418      449      422      451      418      452
      419      451      420      451      426      444
      418      457      418      452      417      452
      419      452      416      454      420      450
      418      452      419      452      419      456
      418      452      418     1323      411     1313
      421      451      419      451      418      452
      418      452      418      454      419     9997
     3521     1764      417      452      419     1315
      418      449      421      452      418      453
      417      453      418      451      427      448
      419      453      417      453      417      452
      419      452      417      453      417     1317
      417      451      419      456      419      451
      420      458      411      452      418      452
      416      455      418     1315      418     1315
      418     1321      417      452      419      452
      416     1318      418      452      418      451
      419      451      419      452      418      457
      418      452      418      452      420      448
      422      451      419      457      412      452
      417      452      419      457      418     1315
      417      453      419      449      421      452
      418      452      418      452      418      453
      424      450      418      453      419     1314
      418      452      418      452      418     1316
      418     1315      417      453      418      465
      410      452      419      452      416      453
      418      452      418      452      418      452
      418      453      417     1338      418     1316
      415     1318      418     1315      419     1314
      418      452      418     1315      419      449
      421     1328      410      452      418      453
      417      452      418      452      420      450
      419      451      417      455      416      457
      419      451      418      452      419      452
      419      453      417      453      417      453
      418      451      419      456      418      453
      418     1315      418     1315      418      452
      419      459      411      451      419      451
      416      460      418      452      419      451
      418      453      417      453      418      451
      418     1315      419     1313      420      458
      425      445      413      460      418      445
      422      452      418      452      418      452
      418      452      419      455      421      450
      420      463      407      452      417      452
      418      453      418      452      418      452
      418      457      418      450      421      452
      418      452      417      453      419      451
      424      445      419      451      419     1321
      417      453      417      454      416      452
      418      452      419      452      418      452
      418      452      418      468      408      452
      417     1313      422     1314      418      452
      420      451      418      452      418      452
      419      456      418      453      416      454
      418     1315      417      452      418     1315
      418      452      418     1316      418      451
      422

Ok, that seems insane :)
Note that the file will begin with a line with a single value : it is the time elapsed between the recording start and the arrival of the first IR signal. This line should be ignored.

Of course, as these are measures, with a time scale as small as the microsecond, all timings are different, which makes the detection of small differences between 2 commands impossible.
It can be observed that values are always close to 400 or 1300us, except for 3 (closer to 4400, 9900 and 1700). So what we'll do to make figures comparable is "round" the numbers to the closest of these 2 "reference" values (a spreadsheet is handy at first).
What this manipulation shows is that except for the 3 singular values the ON time is always 400us, what changes is only the OFF time.

Let's make the hypothesis that the OFF time is coding 0 and 1, and let's assume that 400us is for 0 and 1300us for 1. With this assumption it is possible to change each pair of columns to a single bit.
Let's also make an observation : the part between the 3 "singular timings" is always the same, in all the recordings. It can be assumed that :
- the part is an introduction, maybe identifying the remote or the Air Conditioner, and it will never change
- the different timings are Locks and separators between the introduction and the actual payload

It is therefore acceptable to take that part of the message as an invariant and not to study it.

For the ease of exploiting the data I wrote a small c program to round the values and transform it to binary digits. For ease of reading the code skips the intro part. Should you wish to use this code the timing values are defined in the beginning of the program, you will probably need to adapt it.

After compilation (gcc -o decode decode.c) you can use it on every data file :

$ ./decode auto_21C_swing0_Fan0 auto_21C_swing0_Fan0.decoded 


Example with mode auto target temperature 25°C:

$ more auto_25.decode 
01000000 00000100 00000111 00100000 00000000 10000000 01001100 00000001 11110101 00000000 00000000 01100000 00000110 00000000 00000000 00000001 00000000 01100000 00101010

Step 3: Exploiting the Data

OK, now what we have is a collection of data files containing bits (actually characters representing binary digits, which is technically different).

The use of a file comparison program will help in identifying which part changes for each parameter.

What we can see is not only one part changes but the ending part of the message also. Generally when communication is involved the data correctness is never guarantied so a checksum is usually used to ensure that no data has been corrupted. The checksum will be studied later.

The commands

ON/OFF:
Only one bit changes, the first of the 6th byte (or 40th bit). If 1 the command is ON, if 0 the command is OFF

AUTO/HEAT/COOL/DRY
3 bits change : bits 45 to 48 (see picture)

0000 = AUTO
1100 = COOL
0100 = DRY
0010 = HEAT

swing

bits 64 to 67:

1111 = swing auto 
1000 = swing lowest
0100 = swing low
1100 = swing high
0010 = swing higest

Fan speed

bit 68 to 72:

1100  = lowest
0010 = low 
1010  = medium
0110 = high
1110 = highest 
0101 = auto 


Options (Byte 13):

Powerful: 10000000
Quiet: 00000100 (and the Fan speed is set to minimum)
None: 00000000


Temperature:
Here it becomes a little trickier because it would be nice to understand how the value is coded and not scan all possibilities.
We have sampled 16°C, 30°C, and 21°C. In binary :

16 = 10000
22 = 10110
30 = 11110

The correct zone for the temperature is not found using these values. But often hardware use bits in reverse order (Most Significant Bit or Least Significant Bit on the left of the number, also referred as Little Endian or Big Endian). If reversing the bits the values obtained is:

16 = 00001
22 = 01101
30 = 01111

This gives a match for the 3 values at bits 49 to 53. This is rather surprising as the value is not aligned with a byte (closest would be 6x8=48th bit). This means that when building a message the code will have to shift of one bit the temperature value.

Which consequently validates the first hypothesis concerning timing values used for 0 and 1 :)

Timer A:

The timers are coded in multiple positions: first avalue is used to indicate that the A timer is on, then a second one is used to indicate the timer value.
Timer active state can be found at the same byte as ON_OFF (6th byte, second bit, so starting from the beginning of the payload 41st bit).

So the Timer A is active if the byte is the 6th byte looks like :

x010xxx, the first bit being the ON/OFF bit.

For the timer duration, using the same encoding that with temperature and coding minutes and not hours (as the remote displays), the value can be found on the second half of the 12th byte.


Timer B:

Timer B is active if the 2nd bit of the ON/OFF byte is 1. As timer A is always ON when using the timer B, the byte looks like :

x110xxx, the first bit being the ON/OFF bit.

Ok, here I must admit that I failed to find the key to this value, maybe it is a delta between timer A and B, maybe another unit... Truth is: who cares about timers when the goal is to control it (automatically) from a computer ? :) Even timer A is not used in the end in my system, I was just happy to have found it.

Checksum:
Ah. Here is a value that cannot be disregarded. It is crucial to understand it.
After a few tests it appears that the checksum is for the payload part only (not including the introduction), and is the result of the simple sum of all bytes, keeping only one byte of the result (ignoring overflows). The trick is, of course, that this checksum is made by a Big Endian system, so every byte has to be reversed before being summed, then the result reversed again.
 

Step 4: Verifying the Analysis

The goal of the study is to be able to generate messages that the air conditioner will understand and accept. So the program joined will take arguments and generate a binary message. Now all that's left to do (until we have a working IR emitter) is to compare the message generated by the program and the recorded messages we had in inputs.

The values and position of each data in the payload is defined here.

Once compiled (gcc -o encode encode.c) this code should allow us to verify that the generated frame is equal to the one sampled

The encode program separates the bytes for easier reading.

$ more auto_25.decode
01000000 00000100 00000111 00100000 00000000 10000000 01001100 00000001 11110101 00000000 00000000 01100000 00000110 00000000 00000000 00000001 00000000 01100000 00101010
$ ./encode -m AUTO 25
01000000 00000100 00000111 00100000 00000000 10000000 01001100 00000001 11110101 00000000 00000000 01100000 00000110 00000000 00000000 00000001 00000000 01100000 00101010

That's all for this instructable, not much pictures or fun in it, I must admit, but there's more to come. Hope it might help someone.

Don't hesitate to ask for precision and comment.

Comments

author
RicardoA168 made it! (author)2017-06-25

Awesome write up! I need a little help. I built a
sweet smartphone AC remote for my Frigidaire window ACs and I want to implement
remote sensing. That's where the remote control lets the window AC know what
the real room temperature is instead of letting the AC rely on the biased
temperature sensor that is in the AC. I got it all figured out with the
help of this article, but there is one bit that I cant make heads or tails of.
I've taken a ton of sample IR signals and figured out this much.
The remote displays the room temp in F but no decimal place, but it
spears it is rounding to the nearest half degree. The first number is what is
displayed on the remote (room temp reading without decimal), then we have the
part of the IR code that doesn't change and represents that its sending a
temperature. The last 8 bits are the part that changes. The 7 bits to the
right represent the temperature, but the 1 bit on the left (?) doesn't and I
don't know what it means. Any clues?

70 = 000100001010111111110110 0? 0101001 = 41

75 = 000100001010111111110110 1? 0110011 = 51

76 = 000100001010111111110110 0? 0110100 = 52

the above measurement was sent a
split second after it changed from 75 to 76 which is how I determined that last
bit represents 0.5 degrees.

76 = 000100001010111111110110 1? 0110101 = 53

77 = 000100001010111111110110 1? 0110110. = 54



So if the temp my room air sensor reads is 65.5 degrees, I subtract 50 = 15.5,
then double it to get 31, convert that to binary and send that, but what do I
do with that other bit?

Here are some quick details on how I built it. I'm not using a raspberry pi. I bought a broadlink rm3 mini WiFi to IR bridge and A1 air sensor. The remote is a webapp hosted on my desktop home PC that uses python libraries avaialbe on github to send IR hex codes to the WiFi IR bridge.

Screenshot_20170623-093356.jpg
author
RicardoA168 (author)RicardoA1682017-07-05

Update! I figure out the extra bit. It's for balance of some sort. For some reason those 8 bits must contain an odd number of 1s and that extra bit is used to insure that but has no meaning otherwise. I have everything working now an my air conditioner in receiving the temperature updates properly.

author
ScottV44 (author)RicardoA1682017-06-26

Ricardo did you ever find the codes for the frigidaire on and off switch? I happen to be working on the project with a frigidaire wall unit, and lirc irrecord proved useless. Any help is appreciated. Thanks.

author
RicardoA168 (author)ScottV442017-06-27

I have a Window unit and I just used my broadlink rm2 mini WiFi IR bridge to learn all the codes. I didn't have any issues learning them. It stores them in a hex format. I'm at work right now so I cant grab the hex code at the moment. From my research it seems Frigidaire is problematic with a lot of different smart thermostats on the market. They all see to have a disclaimer about not working with certain Frigidaire models.

author
hsouza (author)2017-07-01

The main goal isn't using the decoded signal to transmit it from other than the original remote right? For that, would be only needed to record the original signal and try to retransmit it through the raspberry?

Fun read though, nice work.

author
psylo24 (author)2016-02-15

Dear all,

I tried to decode ircode from my ir remote for my PANASONIC A/C. (it's not the same remote of you :( )

I did the same test 3 times and have three different results
The tests are to configure the remote control to 20 degrees and start the recording of infrared codes and press the button to set temperature above the temperature at 21 degrees.

First test
3500 1650 500 400 500 1200
500 350 500 400 500 350
500 350 500 400 450 400
500 350 500 350 500 400
450 400 500 350 500 1250
450 400 500 350 500 400
450 400 500 350 500 400
450 400 450 1300 450 1250
450 1300 450 400 450 400
500 1250 450 400 450 400
500 400 450 400 450 400
500 400 450 400 450 400
450 400 500 400 450 400
450 400 500 400 450 400
450 400 450 400 500 400
450 400 450 400 450 450
450 400 450 400 450 400
450 450 450 400 450 400
450 450 450 400 450 400
450 400 450 1300 450 1300
450 400 450 400 450 400
450 450 450 400 450 9950
3450 1700 450 450 450 1250
450 400 450 450 450 400
450 400 450 450 450 400
450 400 450 450 400 450
450 400 450 400 450 1300
450 400 450 450 400 450
450 400 450 400 450 450
450 400 450 1300 400 1300
450 1300 450 400 450 400
450 1300 450 400 450 400
450 450 450 400 450 400
450 450 400 450 450 400
450 400 450 450 450 400
450 400 450 450 400 1300
450 450 400 450 450 1250
450 450 400 450 450 400
450 450 400 450 450 1250
450 450 450 1250 450 450
400 1300 450 400 450 450
450 400 450 400 450 450
400 450 450 400 450 450
400 450 450 1250 450 450
400 1300 450 450 400 450
450 400 450 1300 400 450
450 1300 400 450 450 400
450 1300 400 1300 450 450
400 450 450 400 450 400
450 450 400 450 450 400
450 450 400 450 450 400
450 450 400 450 400 450
450 1300 400 1300 450 1300
450 400 450 400 450 450
400 450 450 400 450 450
400 450 450 400 450 400
450 1300 450 1300 400 1300
450 400 450 450 400 450
450 400 450 450 400 450
450 400 450 450 400 450
400 450 450 400 450 450
400 450 450 400 450 450
400 450 400 1300 450 450
400 450 450 400 450 450
400 450 400 450 450 1300
400 450 450 400 450 450
400 450 450 400 450 450
400 450 400 450 450 400
450 450 400 450 450 400
450 450 400 450 400 450
450 400 450 450 400 1300
450 1300 400 450 450 1300
400 450 450 1300 400 1300
450


Second test
3550 1650 500 350 500 1250
500 350 500 350 500 400
500 350 500 350 500 350
500 400 500 350 500 350
500 400 450 400 500 1250
450 400 450 400 500 350
500 400 450 400 450 400
500 400 450 1250 500 1250
450 1250 500 400 450 400
450 1250 500 400 450 400
450 400 500 400 450 400
450 400 500 350 500 400
450 400 450 400 500 400
450 400 450 400 450 400
500 400 450 400 450 400
500 400 450 400 450 400
450 400 500 400 450 400
450 400 450 450 450 400
450 400 450 450 450 400
450 400 450 1300 450 1250
450 450 450 400 450 400
450 400 450 450 450 9900
3500 1700 450 400 450 1300
450 400 450 400 450 450
450 400 450 400 450 450
400 450 450 400 450 400
450 450 450 400 450 1300
400 450 450 400 450 400
450 450 450 400 450 400
450 450 400 1300 450 1300
450 1250 450 450 400 450
450 1300 400 450 450 400
450 400 450 450 400 450
450 400 450 450 400 450
450 400 450 400 450 450
400 450 450 400 450 1300
450 400 450 400 450 1300
450 400 450 450 400 450
450 400 450 400 450 1300
450 400 450 1300 450 400
450 1300 450 400 450 400
450 450 400 450 450 400
450 450 400 450 450 400
450 400 450 1300 450 400
450 1300 450 400 450 400
450 450 400 1300 450 450
400 1300 450 400 450 450
400 1300 450 1300 450 400
450 400 450 450 400 450
450 400 450 450 400 450
450 400 450 450 400 450
450 400 450 400 450 450
400 1300 450 1300 450 1250
450 450 400 450 450 400
450 450 400 450 450 400
450 400 450 450 400 450
450 1300 400 1300 450 1300
400 450 450 400 450 450
400 450 450 400 450 450
400 450 400 450 450 400
450 450 400 450 450 400
450 450 400 450 400 450
450 400 450 1300 450 400
450 450 400 450 400 450
450 400 450 450 400 1300
450 450 400 450 450 400
450 450 400 450 400 450
450 400 450 450 400 450
450 400 450 450 400 450
400 450 450 400 450 450
400 450 450 400 450 1300
400 1300 450 450 400 1300
450 450 400 1300 450 1300
400


Third test
3550 1650 500 350 550 1200
500 350 500 400 500 350
500 350 500 350 500 400
500 350 500 350 500 400
450 400 500 350 500 1250
450 400 500 350 500 400
450 400 450 400 500 350
500 400 450 1250 500 1250
450 1300 450 400 450 400
500 1250 450 400 450 400
500 400 450 400 450 400
450 400 500 400 450 400
450 400 500 400 450 400
450 400 450 400 500 400
450 400 450 400 450 450
450 400 450 400 450 400
500 400 450 400 450 400
450 450 450 400 450 400
450 400 450 450 450 400
450 400 450 1300 450 1300
400 450 450 400 450 400
450 450 450 400 450 9950
3450 1700 450 400 450 1300
450 400 450 450 400 450
450 400 450 400 450 450
450 400 450 400 450 450
450 400 450 400 450 1300
450 400 450 400 450 450
450 400 450 400 450 450
400 450 450 1250 450 1300
450 1300 400 450 450 400
450 1300 450 400 450 400
450 450 400 450 450 400
450 400 450 450 450 400
450 400 450 450 400 450
450 400 450 400 450 1300
450 400 450 450 400 1300
450 400 450 450 450 400
450 400 450 450 400 1300
450 450 400 1300 450 400
450 1300 450 400 450 450
400 450 450 400 450 400
450 450 450 400 450 400
450 450 400 1300 450 400
450 1300 450 400 450 450
400 450 450 1300 400 450
450 1250 450 450 400 450
450 1300 400 1300 450 400
450 450 400 450 450 400
450 450 400 450 450 400
450 400 450 450 400 450
450 400 450 450 400 450
450 1300 400 1300 450 1300
400 450 450 400 450 450
400 450 400 450 450 400
450 450 400 450 450 400
450 1300 450 1250 450 1300
450 400 450 450 400 450
450 400 450 400 450 450
400 450 450 400 450 450
400 450 450 400 450 450
400 450 400 450 450 400
450 450 400 1300 450 450
400 450 400 450 450 400
450 450 400 450 450 1300
400 450 400 450 450 400
450 450 400 450 450 400
450 450 400 450 400 450
450 400 450 450 400 450
450 400 450 450 400 450
400 450 450 450 400 1300
450 1300 400 450 450 1300
400 450 400 1350 400 1300
450

The goal is to control my air conditioning with my raspberry, but I can not interpret the raw code.

I don't undrestand why the results are not the same, and how interpret these codes?

On some sites I found the following results and on other sites I think of completely different values
3550 HDR_MARK
1600 HDR_SPACE
550 BIT_MARK
350 ZERO_SPACE
500 BIT_MARK
1200 ONE_SPACE

Thanks in advance for your help.

author
baswarajm (author)psylo242017-05-31

Facing the same issue.Did your problem solved ?please help me

author
Gusgonnet (author)2017-04-17

I like your project very much and your description of the process you followed to decode the signals is super helpful. THANK YOU!

Gustavo.

author
GuillaumeT16 (author)2017-01-08

Hello,

I'm trying to do the same but I'm facing some problems : how to get the gap parameter ?

I'm doing a :

sudo irrecord -a clim.conf > lircd.conf

to have a more readable file but it returns me :

irrecord: could not find gap.
irrecord: decoding of OFF failed

author
PrastaR (author)2016-10-30

hey man, great tutorial,

im having trouble to control my panasonic ac, im using LIRC, and always having trouble to send the code, somehow the ac wont recognize any data i send, any suggestion?

author
gtoal (author)2016-10-25

This may be new since you wrote your article: http://removeandreplace.com/2016/06/17/universal-air-conditioner-remote-control-codes/

author
mat_fr (author)gtoal2016-10-27

Thanks for the link. Seems like a nice product.

I doubt they describe the codes anyware though...

Anyway my goal was to control it from my PC, which I now do (and with the possibility to schedule it and make it a little more intelligent, like "turn it on the heat at 6PM but only if temperature is below a certain threshold" for instance).

author
gtoal (author)mat_fr2016-10-27

I was hoping that it implied the information was out there, but you're probably right - it'll be proprietary :-( I wonder if they have access to the info from the manufacturers or if they reverse engineered a bunch of remotes like you did?

author
Danman-pi (author)2016-08-14

Hi your tutorial is amazing!
I managed to understand my air condition remote IR signals(by revers engineering it). but im not sure I understand how do I check if im right and how do I make the Pi send a transmission to turn on the AC for me with 23C and cooling mode,
I read this article:

http://www.raspberry-pi-geek.com/Archive/2015/10/R...
and have it connected but i don't know how to combine your tutorial with all the information I gathered to execute this AMAZING project and step forward to create a web application so I can control my AC on the way home from a hot working day.

please help and thanks again for your amazing help so far!

author
Udon (author)2016-08-06

This seems like an awful lot of work for just collecting and catching hex values....isn't it?

I admit I'm no expert, and hence I found your guide because I'm considering doing an IR sender/receiver. It just looks to me that the way the Rasberry Pi is being used is a bit like killing pigeons with a bazooka....by bludgeoning the pigeons to death with the bazooka.

Couldn't some kind of library do the donkey work for you?

author
The Lost Puppy (author)2016-06-19

I don't know if this of any significance, but when you start talking about temperature in step 3 the values next to the numbers are binary representations of them. Example 16 = 10000 and 10000 in decimal is 16.

author
infernocs (author)2016-06-12

I'we been looking into controlling my midea branded ac unit sold as Ultimatemarket inverter12 in Finland, looked on some forums that described the bitstream to send out from an arduino system and I'm confused. Seems most if not all use a 64-bit stream to pack in all the ac units settings. So far I'we identified that the last two 8-bit (so last 16bits) streams seem to be an identifier for the ac unit, this is probably what the manufacturers can change in identical ones to separate controls as someone mentioned. First two 8-bit sections seem to hold the mode and temperature settings and the third and fourth seems to be the fan speed.

I'm still not done with this research but there seems to be a logic to this madness that so far I can't see that anyone would have figured out yet. Usually streams like this be it 64,32, 16-bit or whatever can be broken down into 8-bit information that the cpu on whatever equipment you have will then either read as single bit binary information or decimal values.

The part I'm mostly confused with is why this:

"

Example with mode auto target temperature 25°C:

$ more auto_25.decode 
01000000 00000100 00000111 00100000 00000000 10000000 01001100 00000001 11110101 00000000 00000000 01100000 00000110 00000000 00000000 00000001 00000000 01100000 00101010

"

Seems to be about 88-bits more than you need to control an ac unit???

When I want 22c auto with high fan speed all I need is this:

B24D1FE07887

Wich in binary translates to:

‭101100100100110100011111111000000111100010000111‬

Choppig this up into 8-bit sections I think we should be getting into what we really are telling the ac unit to do:

‭10110010-01001101-00011111-11100000-01111000-10000111‬

178-77-31-224-120-135

But as I said, need to investigate some more.













author
shootermatic (author)2015-12-15

Thanks for taking the time to explain how you did this. Though my project differs in execution it was very useful to see your methodology.

author
lowflyerUK made it! (author)2015-10-06

Hi! I did it for my Daikin FTXS series air conditioning system that uses the ARC452 remote control. All the details are here https://github.com/lowflyerUK/aircon-raspi-xrf

Thanks for your inspiration!!!

Daikin_ARC452A3.png
author
AmitJ6 (author)2015-10-02

hello , I recently bought air conditioners of single Japanese brand and have installed 2 in living room . When I point the remote to one both switch on and off and all other settings happen together

The Ac vendor changed the code in one and now I have to manage two remotes

There could be multiple reasons for this but it is not great to manage so many remotes is there a solution for this problem available with anyone

Thanks

author
HagaiW (author)2015-09-09

i try this with my air conditioner and my RPi

my control is YB1FA

i try this but i get many of diffrent in the temperator test.

root@raspberrypi:/home/pi/lirc# hexdump 25_fan4_cool.dec

0000000 dd4c e5db dcdc dcdc d5dc dcdc dbd6 dcd9

0000010 dddb dcdc dcdb d6dc d8dc dcdc dcdc dddb

0000020 dcdc dddc f4d5 ddd0 dcdd dddd d7dd dddd

0000030 dcdc e3dd dcdd dbdd dcdd dcd1 dcd7 dddd

0000040 dbdb dcc2 5dc3 000a

0000047

root@raspberrypi:/home/pi/lirc# hexdump 26_fan4_cool.dec

0000000 dc4b dbdc dadb dbd9 dbda c8dd dcd4 dadc

0000010 dadb e1da dbd7 dbdb d3c1 dad5 d5db dbdb

0000020 dbe1 d7d7 dcdb dbdc dbe1 d5da dadd d6d7

0000030 dbd2 dcdb dbdb d7ea d6da dbdb d7d7 dcdb

0000040 dadb dbdc 5ddd 000a

0000047

author
UH1PIC (author)2014-12-30

Confirmed, LIRC sends raw codes just fine on the RPi. I'm running Arch, which may be a little different, but it still worked. I think the kernel priority concerns are fixed by using a daemon to send the code.

To add some detail to a post below, I did the following:

Capture raw codes with IR receiver using "irrecord -m > filename.out"

Edit the file as described above, capturing the important section...

Place in /etc/lirc/lircd.conf with this format:

begin remote

name remote_name

flags RAW_CODES

eps 30

aeps 100

ptrail 0

repeat 0 0

gap 40991

begin raw_codes

name ON

[your raw codes here]

name OFF

[your raw codes here]

end raw_codes

end remote

Restart LIRC daemon to re-read config file. The above would be sent using the command "irsend SEND_ONCE remote_name ON".

Setting up LIRC on ARCH is a bit of a challenge but it can be done.

Versions:

Linux: ARCH 3.12.35-1-ARCH

LIRC: 0.9.1a

author
Raras Handwiyanto (author)UH1PIC2015-08-18

Hello UH1PIC, right now im doing a project to control my Panasonic Air Conditioner refering to Mat's tutorial. But, i am stuck right now.

Would you please post some documentation regarding to your project. Right now im using LIRC version 0.9.0 on Rasbian OS. It does not work recording IR signal of my Panasonic Air Conditioner. Or maybe you would like to tell me how to install the LIRC 0.9.1 on the Raspberry Pi. Thank you so much.

author
UH1PIC (author)Raras Handwiyanto2015-08-19

Its been a while and I will have to think back...

The big problem is there is very little in the way of logging. First is getting LIRC installed and functional. Do you have a /dev/lirc0? Arch doesnt use /etc/modules anymore, not sure about your flavor of Rasbian. Check the settings in /boot/config.txt if thats what your flavor uses.

This web site seems accurate:

http://alexba.in/blog/2013/01/06/setting-up-lirc-o...

Make sure you make the changes to /boot/config.txt

Note, on Arch linux, when configuring GPIO pins, use the BCM GPIO number, not the physical pin number (or wiringPi). That was one of the things I got hung up on.

author
mat_fr (author)UH1PIC2015-01-01

Hi, Thanks for the update.

I began with testing recording/replaying commands using LIRC on the rPI. It worked just fine with raspbian also. But I couldn't manage to send manually custom, dynamic commands due to the lag (and using LIRC does not permit dynamic command building). I don't mean that it's not possible, but I abandonned the Pi path for this reason...

I'm
quite happy with my setup right now, a MUC server with an arduino
plugged in, although it's not finished (I removed the Pi which had the
temperature probe so I moved it to the arduino but haven't updated the
communication code yet). The project is pretty much on pause right now, I
should get back to it someday.

Anyway, if you manage to build and send IR codes to your AC unit using the Pi I'd be happy to hear it :)

author
praveenk17 (author)2015-04-20

My question is how an ac can detect when we pressed the remote button in any direction in a room. Why not tv remote or dvd remote works. Is there any difference in them.

author
mat_fr (author)praveenk172015-04-20

Hi,
Hum, that would be a physics question... I suppose it lights brighter and reflects on the walls. Really I don't know.

author
Mjtrinihobby (author)2015-04-15

your instructable inspired me to create my home infrared control network!

author
mat_fr (author)Mjtrinihobby2015-04-15

Great :)

Hope to see what you make out of it.

author
UH1PIC (author)2014-12-29

There hasn't been much activity here in a while but I figured I would just add a post to 'freshen' it up for the search engines. Hopefully someones search terms hit on this post and it brings them here for help.

I was happy to find your instructable as I am trying to do the same thing for my LG HSV Air Conditioner. I cant seem to get LIRC to record the signal, probably due to length. I am able to get pretty consistent values from the mode2 command tho. I was able to force creation of a conf file using "irrecord -a" but I havent gotten a chance to test it yet.

I agree with you about the priorities problems with using a Raspberry Pi, but my very limited reading indicates the issue may be resolved. Again, I'll post my results as I intend to at least try with my Pi. It seems to make sense that the longer the sequence, the more the timing errors would build up. It seems I read something that talked about using PWM and modulating the IR codes on that signal. Maybe the PWM helps keep timing more steady in the runtime environment.

Since I'm going to run the wires for the IR emitter, if the Pi wont drive the air conditioner, I'll just put an adafruit trinket or some other micro arduino in there to drive the LED instead...

Thanks again for the great infro!

author
guysoft (author)2014-09-09

Question: Why not use the RasepberryPi as a transmittor as well? Is there an lirc limitation?

author
mat_fr (author)guysoft2014-09-11

I answered your comment but the (long) message never got posted :(

To cut a long story short lirc only allows the sending of pre-defined messages, not "real time built" composite orders. It's ok for HI-FI, TV, ... but not for air conditionners.

The Pi could send the messages as does the arduino, usining a GPIO and changing its state timely, but the Pi (raspbian) is not real time, so the small timings required for these operations are not easy to achieve (sometimes another process takes the CPU and you end up with a 50ms jitter on your timing). I suppose there are solutions but I preferred to use an USB connected Arduino, as a "USB dedicated peripheral".

author
guysoft (author)mat_fr2014-09-12

You should use Lazarus, it backs up anything you type, so if something is not posted you can recover it: http://getlazarus.com/download

Anyway, I am aware of what lirc does, and that the remote control I am using, by a company by a company named "Electra" sends long messages, so long that sometimes the air conditioner itself fails to decode them!
I want to replay just one or two commands (turn off, turn on, with re-defined settings).
Question: I have also set up an IR LED, is there a way to play back the raw mode2 recordings?

author
mat_fr (author)guysoft2014-09-12

Interesting, I'll look into Lazarus :)

There is indeed a way to replay frames that you recorded with lirc (in fact, that's the first thing I did when beginning this project). In that case you don't even need to analyse the frame, so no need to decode anything, you just record and replay.

To replay a sequence of timings you just have to copy/paste the sequence given by mode2 recording into the lirc configuration file, with a command name. Not sure anymore how you do it, but as I recall it was like :

[lirc.conf]

[...]

begin raw_codes

name ON

[paste here the mode2 record output]

name OFF

[paste here the mode2 record output]

end raw codes

then you can send the commands with :

irsend SEND_ONCE ON

Check this page for instance :

http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi/

author
guysoft (author)mat_fr2014-10-19

Hey mat_fr,
So I have been researching more, and thanks Barak (who actually contacted me after googeling this comment), it seems that the air conditions here use 33.3Mhz frequency which means normal LED receivers don't work with them since they use 38Mhz. He revered engineered his using some advanced and pricey analyser, but it uses different codes than mine:

He uploaded his results to github, but it does not work for me:

https://github.com/barakwei/IRelectra

author
guysoft (author)guysoft2014-09-09

Ok, so I tried to record my AC and I am getting gibberish from the decoder.
You can download my input and output files here (along with the source I used).

Would appreciate if you could take a look and tell me why your code is returning garbage binary data?

author
mat_fr (author)guysoft2014-09-11

You probably don't have the same air conditioner as mine (not a Panasonic?), so the sequence of data is not the same. Sorry my code is only adapted to my device, I don't have any other to work with...

By the look of it your sample set does not have an introduction as mine had (there is just one loooong On state, in my case there was 2, defining 2 different parts in the message), and the code expects 2 parts, and ignores the first. I'll try to give you a modified version.

author
guysoft (author)mat_fr2014-09-12

Hey Mat,
Thanks for your help!
I have been trying to decode this remote for a while and so far had no luck, so far this is as close as I have come to decode it.

Your defines give out ones and zeros. Its still not always identical, but the results seem to converge on two sequences (I have done 10 readings for the 'on' button, and these are the two main I got:

{{{1100001111110001101100000101110000000101000000000000010000000000000000000000010000000000101000000111}}}
or

{{{110000111111000110110000010111000000101000000000000010000000000000000000000010000000000101000000111}}}

author
mat_fr (author)guysoft2014-09-12

The different size of your 2 frames makes the analysis harder... I would have expected both to be the same size. The ON/OFF could be just a single bit. I don't see the end of both lines so I see just 2 identical lines except for an extra 0 somewhere between the 10111 and the 101...

author
mat_fr (author)guysoft2014-09-11

In fact your problem is simpler than that: just look at the timings in your data file (irOff and irOff2). The timings do not match the ones for my device. You find long timings of 17xx, shorts between about 530 and 640, the introduction is 9080 followed by 4580... so you have to update the timings defined in the beginning of the code to match you data sample:

#define SHORT 530
#define LONG 1700
#define MARGIN 150
#define INTRO 9000
#define INTRO2 4500

There is no SEPARATOR used as there is only one part in your data frame.

What is weird however is that your 2 samples are not the same size.

author
Basavaraj H (author)2014-09-25

Hi Mat,

That was great help from you, providing details of your project. By the way I am planning to build Universal AC remote control. In that case do I need to mine the data from all individual remotes? Any help is appreciable.

Thanks

Basavaraj H

author
mat_fr (author)Basavaraj H2014-09-26

Hi Basavaraj H,
Thanks for your comment.

I had to reverse engineer the protocol because I couldn't find any related documentation online... maybe other protocols are well documented or already reverse engineered by others... I'm not aware of any project like yours, but I suppose you will indeed have to know every protocol for a Universal Remote to work...

The TV be gone remote is a good example: they put in a uControler the OFF codes for all known TVs protocols, and send the command for each one. But that's way simpler, as TV remote protocols are generally well (better) known and are only one command at a time. I'm affraid for AC you would have to understand thoroughly each and every one of the protocol exchanges.

Plus, if you don't have a way to tell your remote which AC protocol to use you would have to send the data for all known AC one by one, which, given the length of the data packets, could take a very long time (few seconds at least I suppose). That would make the remote quite annoying to use if the user has to aim at the unit for 5s to send a command...

author
mat_fr (author)2014-09-08

Hi SalvaV,

Thanks for your comment.

The code for encoding and decoding embedded in this instructable should work to analyse, decode and encode IR signal into binary data, but if you want to actually control your device you should check my other instructable

https://www.instructables.com/id/An-air-conditioner... which contains Arduino code to send the data to the air conditionner.

Cheers

author
SalvaV (author)2014-09-05

Good work. I have de same device and I would like to control it via Arduino and RasPi.

Where is de source code of decode and encode?

Thanks.

About This Instructable

124,815views

81favorites

License:

More by mat_fr:Yet Another (ugly) UV exposure BoxAn air conditioner remote replacementReverse engineering Air Conditioner IR Remote control protocol
Add instructable to: