Skip to content

Adding support for a new AC protocol

David Conran edited this page Sep 17, 2019 · 21 revisions

Here is a rough outline of the steps & actions required to add a new Air Conditioner protocol to the library.

Preparation

See if it is already supported first.

Take a look at the Supported Protocols document. See if we've already documented support for your Air Conditioner/Heat Pump. Obtain a IR Demodulator Hardware component, and build this circuit, and then compile and run the IRrecvDumpV2 example code on your ESP device. Monitor the serial output from the ESP module. The output should tell you what it knows about your protocol if it is supported, or list it as UNKNOWN if it doesn't know what it is.

Obtain the make & model number of the A/C unit AND the IR remote.

We will need that information later. Do some research to see if you can find any/all of the following:

  • The operation manual.
  • The specification for the IR protocol.
  • Links to any other implementations and projects that support your air conditioner.
  • Photos of the remote control etc.

Read the FAQ first

See & read the FAQ on this topic to see/understand what you are asking/attempting.

Get basic support for a *new IR protocol working first!

This document assumes you've carried out all the steps to add basic support for the protocol. You'll most likely need to do that before you proceed or read further.

A note on collecting data

Capture some "Raw" IR messages from the remote.

If you've added basic support (at least decodeBlah()) successfully, and it is successfully recognised by the IRrecvDumpV2 example code etc, you will want to document all the settings on the A/C remote for each message you capture.

e.g. "Power button was pressed. Remote went from 'off' to 'on' and Cool mode, with Fan at auto, no fan swing, no filters were on, led display on the aircon was on, timers were all off/disabled, the clock on the remote was at '12:00', the temperature was 25C ..." etc for each message.

Add that text (please, no screen shots) description of every setting on the remote to each uint8_t state[] = {...}; you capture. I also suggest you keep a copy of the uint16_t rawData[] = {...}; lines as well until we are sure everything the state[] lines are perfect. The rawData lines can be used by the library to faithfully reproduce the real message you got. The state[] lines are higher level translation.

Unlike simple IR remotes (think, TVs & Stereos etc.) Air Conditioners tend to not have discrete IR commands. e.g. There is no repeatable/re-playable standard "Volume Up" code like a TV has. Almost all of the time, it sends every setting on the remote in one message. You will be spending some time later to try to work out what parts of the message mean what.

Create a spreadsheet

It may seem like too much work at first, but you will wish you had done it soon if you don't do it early. Start organising the data in a spreadsheet. Typically breaking down & storing the description of what the message is about, or what the user action was (e.g. Set the temp to 22C), and the state[] code associated with it. It's often helpful to break up each state[] code into each byte (That's two Hexadecimal characters per byte e.g. 0x4F is one byte) per cell. You will want to label the columns of bytes starting with the first byte column as 0, then next 1 etc) This will help when referencing the data later. e.g. In C++, the first byte of the state[] array is state[0].

Most AirCon config settings tends to be sole confined to a single byte, or half of the byte (called a Nibble). Doing the above will help make any setting changes stand out. You will want this for later.

Log an issue (or fork your own branch and send a PR) to add experimental support for the protocol.

Report all the information you've collected in a new issue. If I've got all that information, I can fairly quickly verify that the basic support for your protocol looks good, tweak it if needed, or ask you for more information.

Raw Data should no longer be needed now

Once we have a working decode routine. You should no longer need to record the full output of IRrecvDumpV2. You only need the uint64_t data = ...; or the uint8_t state[] = {...}; lines to fully detail what the message is. i.e. The protocol number/type (e.g. 70 or DAIKIN152) and the data/state lines should be all anyone needs to reproduce the message. We no longer need to care about the micro-details of timings if it is successfully detected. If it is still coming up as UNKNOWN then, yes, collecting the raw data is necessary to help get better matching and timing information.

Analysing the data

Determining the bit order of the protocol.

Most AirCon protocols have two distinct formats which significantly affect the hex code for the protocol. That is, if the code is transmitted in Least Significant Bit First (LSB or LSBF), or Most Significant Bit First (MSB or MSBF) bit order. To try work out which order your protocol uses, we use a fairly simple process.

  • Set the remote to what ever modes produce the most about of zeros in the hex code as currently captured. e.g. Clock to "00:00", Auto modes, or Cool modes typically.
  • Capture & Record the the ENTIRE temperature range starting from the lowest temperature the remote/aircon can do, and step up every smallest temperature increment you can until you reach the highest temp.
  • Try to find which part of the hex code changes when you do this. Typically the last byte (the last two hexidecimal numbers) are often the checksum for the message. It is often safe to ignore those for the moment for now.
  • Look to see how the numbers change with each temperature increment. If they are linear with the temperature (e.g. the increase by 1 for each degree etc) then we've probably got the bit ordering of the protocol correct. It's a 50/50 chance. If not, odds are we need to swap the bit ordering in the code.
  • Once we've confirmed we have the bit ordering correct, only then should you proceed to trying to work out what bits and bytes control which aspects of the AirCon.

Working out the details

This is where things get hard, and you have to a lot of analysis work. I'll break things up in to sections to attack but you don't have to do them in any particular order.

The most important features you need to target are:

  • Power control (i.e. Turning the unit On and Off. See: Binary Settings.)
  • Mode control (i.e. Cool, Heat, Fan Only, Auto, Dry etc. See: Value ranges)
  • Temperature control (Which you should probably have worked out by now. See earlier. See: Value ranges)
  • Fan Speed control (How fast the fan is to run. See: Value ranges) & potentially, the hardest to decode:
  • The message checksum(s) (Often Air Conditioner remotes are long and to make sure the message hasn't been corrupted they have some verification code built into the message. If a/c messages have a checksum(s), then working out how to calculate it will be required to be able to dynamically create a new valid A/C message. Thus, it's a requirement if you want the library to be able to create and send a new A/C message. It isn't required to just decode a message.

Binary Settings

These are A/C settings that are typically controlled by a single "bit" in the hex code. e.g. An option that can only be "on" or "off". For instance, "Health", "Ion Filter", or "Turbo" settings are often a Binary Settings controlled by a single bit in the message. "Power" is often a binary setting too, but some A/Cs have special messages that either toggle the A/C unit from off to on and on to off with the exact same bit in a message, or even have an entirely different and unique message for controlling this. The best way to detect these is to try to have the remote produce a code that has the least number of bits set to 1 (on). e.g. a 0 bit is typically off, or the default for a setting. The more 0s in a code the better for making these settings stand out easier.

In your spreadsheet, you'll find that a certain byte/nibble will always alternate when you change the setting from on & off etc. That column may also change when other settings change too. Beware of that. This is because a binary setting can be just one bit out of the possible 8 in a byte (or 4 in a nibble). The other bits may be used for other settings.

It's often useful to use a program or web page that will help you convert from Hex to Binary. This will allow you to see which bit changes from 1 to 0 and back to 1 etc.

For example, let's say that state[5] changes when we toggle the power setting. It changes from 0x8A (on) to 0x0A (off). If you convert those hex values to binary, you'd get 0b10001010 (on) and 0b00001010 (off). You can now more easily see it's the left most bit (highest bit, or Most Significant Bit) that changes. Thus we can assume that the power setting is controlled by the 0b10000000 bit of state[5].

Value Ranges

These are A/C settings that are typically controlled by a group of "bits" in the hex code. e.g. A setting that has more than just "on" or "off". For instance, "Mode", "Temperature", or "Fan Speed" settings are often a Range Settings controlled by a cluster of bits in the message. They can vary from only two bits to multiple bytes in size. The size is at a minimum, determined by the amount of information needed to be stored. e.g. Often there are 5+ operation modes (Cool, Heat, Fan Only, Auto, Dry etc.) 5 in binary is 0b101. Thus it need at least 3 bits to store the information. Often, due to who designed the protocol, they may use more bits than the absolute minimum for what ever reasons they saw fit at the time. Often if a range is only 3 bits long (using the current example) they will store it in it's own distinct nibble (the upper or lower 4 bits of a byte).

e.g. Let's say your spreadsheet shows that state[3] changes when you change operation mode on the remote. 0x20 for Auto, 0x21 for Cool, 0x22 for Heat, etc up to 0x25 for Dry. Only the last half of the byte (or nibble) is changing. If we do the same trick of looking at it in binary notation per Binary Settings, you get 0b0010000 for Auto, 0b0010001 for Cool, 0b0010010 for Heat, etc up to 0b0010101 for Dry. As you can see, only the last three bits ever change when the mode changes. We could say that the a/c's mode is controlled by the last three (or lowest 3, or the 3 Least Significant) bits of state[3]. Or we can say 0b00000111 in binary (0x07 in hex) are the controls (or masks) for the operating mode.

Temperatures often have a range of a minimum of 16C to a maximum of 31C. Sometimes the manufacture only stores the difference from the minimum temp in the message. i.e. 31 - 16 = 15. 15 in binary is 0b1111, thus fitting in a nibble, where sometimes they store the whole number. i.e. 31 is 0b11111, 5 bits. When it extends over a nibble, they tend to dedicate an entire byte to it.