@madpilot rants

Reverse engineering a Fujitsu Air Conditioner Unit – The protocol from the outdoor unit

So, I think I’ve worked out the meaning of the bitstream coming from the outdoor unit!

On my day off, I took the unit of the wall, got me some coffee and setup shop in the hallway, oscilloscope in hand.

I must admit, I’m still getting used to using the oscilloscope and I’m sure there is a far better way to do what I’m trying to do, but I found that if I probe the RX pin on the CPU, with the ‘scope set to single trigger mode and keep hitting the start button, I’d eventually align the waveform at the start of the cycle. After that I used the onscreen rulers to work out the gaps between the pulses. I then wrote them down in to this spreadsheet. I’d change a setting, take a new set of readings, and repeat until I had covered enough states that I could get a complete picture of what was going on.

Looking at the data, I could start to see some patterns.

  1. The shortest spacing was around 2ms (some longer; some shorter)
  2. The RX pin is idle low, and there is always a high transition to represent the start bit
  3. There seems to be a low transition to represent a stop bit
  4. There is 9 bits between the start and stop bit (except for the last set)

It’s starting to look like a straight up serial transmission, except the idle state, start and stop bits are inverted, so unfortunately the built in serial protocol decoder wouldn’t read it.

Next I need to find the bits that change between each state.

The power bit was pretty obvious: there was only one bit that was different when the power was off – the 68th bit.

Looking at the rest of that byte, there was a pattern developing in the next 3 bits – they seemed to change when the settings changed. Taking LSB first, Fan only mode is represented by 0x01, Humidity mode (Yeah – I don’t know what that is either) is 0x02, Cool mode is 0x03, Heat mode is 0x04 and Auto mode is 0x05. The next three bits represent the fan speed: Auto 0x00, Speed 2: 0x02, Speed 3: 0x03, Speed 4: 0x04. But was was the ninth bit?

Having a think about serial, it’s could a parity bit. By summing the number of bits, it became pretty obvious it was odd parity. I checked this against the other bytes, and it checked out – now we are getting somewhere!

Looking at the next byte, it was clear it was changing with the temperature. I purposely looked at the lowest possible setting for the temperature (15deg) and the highest (30deg) and it was here I was lead down the garden path a little. Reading up on other people’s efforts at reverse engineering air conditioner units, this is a fairly common range. Many of the IR transmitters represent this as a 4 bit number, where 0x0 is 15 and 0xF 30. Unfortunately, I couldn’t for the life of me work out how that mapped to the numbers I was seeing.

It turns out, this system uses a 5 bit number – feasibly being able to represent 0 – 31 degrees. Bits 6 and 7 are always 0, and bit 8 is the “economy” settings.

There is four unknown bytes, and one block that seems to be make up of 5 bytes. My guess is one of the unknown bytes is reserved for errors, and one is a serial number of some sort. I have no clue what the other two could be for, and I’m quite confused by the last, short byte.

But this is definitely progress!

I did a final check the get some timing on what is transmitted, and there seems to be three windows of roughly 212ms each. The first from the outdoor unit, the second transmitted by the remote control, and I’m guessing the third is for a slave unit.

To build a test harness, I’ll need to bit-bang the data for 212ms, then set the line to high impedance for 424ms. This will hopefully allow me to get the remote control to work on my bench. Once I can get the remote to work, I can analyse what it is doing. Next, I’ll simulate that as well, then set the remote to slave mode and work out that part of the protocol. Once I have the three parts of the protocol nutted out, I can just simulate the outdoor unit, connect the spare remote controller as master, and the microcontroller will become the slave. Easy!

Leave a comment