Finally I’ve made a huge step forward in actually controlling the Itho ventilation box from my arduino, using a CC1150 RF-transmitter. This wouldn’t have been possible without Sander letting me swap my Itho remote control for his remote control, so thanks Sander!
If you are not interested in how I got this working, but want to see it working for yourself, head straight on over to my GitHub repository and download the code: https://github.com/xs4free/Itho-library. Take a look at the AllFourButtons example. If you have a CC1150 RF transmitter, an Arduino Pro Mini (running at 3.3V) and 4 tactile switches, you can control an Itho RFT ventilation box by wiring up the compents like this:
In retrospect I had to solve 3 problems to get the code working:
- Know which fields contain the identity of the remote control (so I can re-create that number or create a fake number)
- Find out what the last 2 bytes in the first part of the message mean
- Find out what the 2 sets of bytes mean in the second part of the message that keep on changing every button press
The first problem (I thought) I had, was not knowing which bytes in the message actually contain the remotes unique identifier. My theory was that I had to generate another identifier for my Arduino based remote, or else the original remote would not work anymore. In the end it turns out both remotes work just fine when used interchangeable, but I didn’t know that up front. So I asked my colleague Sander if I could borrow his remote. That way I could analyze the messages being sent from his remote and analyze the differences. For each button press the Itho remote sents out 6 short RF messages. The first and second message are unique, the 4 messages after that are only repeats of the first 2. The first message contains 20 bytes in total, 6 bytes where different between the first and second remote. The second message contains 51 bytes in total, 5 bytes where different between the first and second remote. These were the only bytes that changed between the 2 remote controls, but stayed the same between 2 button presses on the same remote. I’m assuming the Itho ventilation box remembers these numbers when you preform the “join” operation when the ventilation box is turned on for the first time. Anyone using my code should perform a join first (untested yet!) with the identifiers in my code, before an Itho ventilation box will accept commands from the Arduino.
When I was analyzing the first message being sent for each button press, I noticed that the last 2 bytes only use a limited number of values. After looking at all the traces I had recorded I concluded that the last 2 bytes specify the previous command sent by the controller. So if the previous command was “go to low speed” and the command being sent now was “go to full speed”, the last two bytes of the first message would always be 85 and 77 (low speed). Each button/command has it’s own unique combination for these 2 bytes.
The second message that is being sent when a button is pressed, contains 51 bytes of data. This message contains 6 bytes that change every time you press a button (even if you keep pressing the same button over and over again). The only explanation I could think of, was that these bytes had to form a number that gets incremented with each button press. To find out what logic is being used to generate these numbers I put the 6 changing numbers in their own excelsheet and started searching for patterns and applying formulas. After a lot of searching I discovered that the 6 bytes formed 2 numbers, one that decrementes every button press and one that increments/decrementes based on the button that is being pressed and the previous button that was pressed before it. For example, if the Itho is running at low speed (was the last button pressed), and counter 1 currently has the value 100 and counter 2 has the value 200:
|Itho current speed||low||low||high||high||timer|
|Message 1 last 2 bytes||85, 77||85, 53||85, 53||85, 85|
|Message 2 counter 1||100||99||98||97||96|
|Message 2 counter 2||200||203 (+3)||204 (+1)||210 (+6)||206 (-4)|
The counters in message 2 are not simply stored in two bytes, but are split across the bits of 3 bytes. The assumption I made in my excelsheets, to convert the binary bits back to bytes, actually made it harder for me to see these number. For example, if bytes 26, 27 and 28 of the first message contain the values 150, 150 and 166, then the number we are looking for is 99. How did I calculate this number? First you convert the byte values to bits, so 150 becomes:
10010110 and 166 becomes:
10100110. If you put all 3 binary numbers after each other you get
10010110 10010110 10100110. Now take the 10th bit (from the left), the 8th bit, the 6th, 4th, 2nd, 18th, 16th, 14th and 12th. If you put these bits after each other, you get:
001100011. If you convert this binary number back to decimal, you get 99. The fun part for this counter is, that besides the number 99 the Itho remote always sends another number along with this counter. To calculate the value of the other number you substract the value of the counter (99) from 511, so the second number would be 511 - 99 = 412.
The second counter in message 2 uses the same kind of formula, only the first bit of the counter does not start at the 10th bit, but at the 14th bit.
So my current understanding of the protocol the Itho remote uses to communicate with the ventilationbox is as follows:
|Byte start||Byte end||Default value||Description|
|1||3||170||Start of the message (10101010 x 3)|
|7||9||id of the remote|
|10||10||id (7 bits) + command (1 bit)|
|14||14||command (7 bits) + checksum (1 bit)|
|15||16||checksum (command specific)|
|19||19||Fixed value for the previous command: register = 77, unregister = 82, low/medium/full/timer = 85.|
|20||20||Fixed value for the previous command: register = 77, unregister = 171, low = 77, medium = 75, full = 53, timer = 85.|
|Byte start||Byte end||Default value||Description|
|1||7||170||Start of the message (10101010 x 7)|
|17||24||id of the remote|
|27||27||counter 1 (2 bits) + command (6 bits)|
|42||42||command (4 bits) + counter 2 (4 bits)|
|44||44||counter 2 (6 bits) + footer (2 bits)|
|45||50||footer command specific: for join command (2, 165, 169, 169, 154, 86, 85, 5) for all other commands (2, 172, 170, 170, 170, 170, 170, 7)|
|51||51||footer (3 bits)|
For my needs, the above code works perfectly. I do have a few future tasks and ideas:
- Convert the code to be commandable via the serial port and change the schema to work safely on a Arduino Nano (that can easily be hooked up to an Cubietruck or Raspberry Pi)
- Test the join and leave commands so others can use my code without knowing their own remotes unique identifier
- Get this code working with an CC1101, so I can also listen/receive the buttons presses from the regular remote
- Duration test
- Compare my findings with the results Klusjesman (a commenter on this blog) sent me.
If you are going to use my Itho (CC1150) code, please drop me a line in the comments below. I would love to hear your experiences and ideas!