Skip to content

AC controller

NYC Resistor has two heat pumps that use infrared remotes and people forget to turn them off at the end of the night. We're also in the process of automating the space with MQTT and HomeAssistant, so I reverse engineered the IR protocol to be able to turn the A/C units on and off. The ESP8266 is fast enough to decode the modulation to clone the IR code and bit-bang the 36 KHz modulated signal back to the units. The IR LED isn't quite the right wavelength, so it has very limited range and we'll need to install it close to the unit that it is controlling.

IR Modulation

I wasn't able to get any response from typical 38 KHz IR demodulators, so i hooked probes directly to the remote control's LED pins. The signal has a square-ish waveform at 36 KHz during the transmissions and the bits are encoded by the width of the non-transmitted periods.

The sync pulse appears to be 3440us high, followed by 430 usec low, 1 bits are 1320 usec low, 430 usec high. 0 bits are 430 usec low, 430 usec high. There might be a fence-post error on the start bit -- it might 3440 usec high, 1760 usec low, and then the bits are high then low. For now it is sufficient for re-transmitting the bits.

        3440 us               430       430    430
       +------------+         +--+      +--+   +--+
___|            |_________|  |______|  |___|  |___
                     430+1320    1 = 1320  0=430


I haven't decoded all of the bits since we only need three commands: turn on the heat, turn on the cold and turn off the system and I think I have a fence-post error on the bits (since we end up with one extra bit at the end). The only bits that I've identified are the On/Off bit (in red), the temperature (in blue) and some sort of checksum (in green).

  static const char off_cmd[] =
  "11100010" "01101001" "10110010" "01000000"
  "00000000" "000000<span style="color:red">0</span>0" "00001000" "01011000"
  "00000001" "11101111" "00000000" "00000000"
  "00000000" "00000000" "00000000" "00000000"
  "00000000" <span style="color:green">"01010011" "0"</span>;

  // this is the on command for 85F, swing h+v, 3 fan
  static const char heat_cmd[] =
  "11100010" "01101001" "10110010" "01000000"
  "00000000" "000000<span style="color:red">1</span>0" "00001000" "<span style="color:blue">01011000</span>"
  "00000001" "11101111" "00000000" "00000000"
  "00000000" "00000000" "00000000" "00000000"
  "00000000" "<span style="color:green">01010000" "1"</span>;

  // this is the on command for 70F, swing h+v, 3 fan
  static const char cool_cmd[] =
  "11100010" "01101001" "10110010" "01000000"
  "00000000" "000000<span style="color:red">1</span>0" "00001000" "<span style="color:blue">01010100</span>"
  "00000001" "11101111" "00000000" "00000000"
  "00000000" "00000000" "00000000" "00000000"
  "00000000" <span style="color:green">"01011000" "1"</span>;

Source code

The firmware talks to the MQTT server at NYC Resistor. You'll need to update the config and other parameters for your WiFi and MQTT-broker. The source code is in our hackerspace's "Things" tree:

2018 Automation

Last update: November 8, 2020