What’s better than working on a project for improving an electronic device (see Making my washing machine smarter)? Working on two projects!
I have a Daitsu air conditioner in my bedroom. It is an old model, the DSG-07HRN2. My plans are: I want to control it from my phone, and be able to program it accoring to X criteria in the future (temperature, month of the year, if I’m at home or not…). I could use OpenHAB for this of course, as I did with my washing machine, but first, I need to connect my air conditioner to my OpenHAB server, which, being an old non-smart model, is not possible without modifications.
I could use some king of magical (and probably expensive) thingy that externally sends the commands using infrared and uses a proprietary APP to control it (I know of their existance), but… where’s the fun there? 😜. My idea is to use another ESP-01 microcontroller, and send the infrared commands from inside the air conditioner unit itself. I’m sure this is going to be interesting 😊.
First, let’s investigate which kind of protocol does the original remote use, I used the IRrecvDumpV2 example sketch from the Arduino-IRRemote library, created by Ken Shirriff and other contributors.
When I tested my remote on my arduino MEGA, I was surprised it said the protocol used was SAMSUNG, which has nothing to do with Daitsu. Interesting.
At that moment, I pushed every button, choose any mode, fan speed, temperature… The thing is the majority of the remotes send the complete state of the air conditioner in one go (ON, COOL mode, 23 degrees, medium speed for example), so I needed some variety of these commands to find out which part did what. I wrote down every command, as you can see further down.
What do all those numbers mean? It seems it is the amount of time the infrared LED is on (positive number) or off (negative number) in microseconds.
If we sort the values in an excel spreadsheet, we can see the differences between every command by using conditional formatting. This way we can start to see which number does what.
If we look closely, every time the temperature changes in the command, values number 68, 70, 72 and 74 change, so these values are the responsible of transmitting the temperature. Also, values 84, 86, 88 and 90 change, but in reverse (if number 68 changes from a low value to a higher one, 84 changes from high to low value). We will interpret each of these values as “true” (or “1”) and “false” (or “0”), which will make everything easier. In my case, I’m interpreting the higher value (-350 microseconds aproximately) as a “1” and the lower value (-1500 microseconds aproximately) as a “0”. Having this in mind, we can make the following observations:
- Positions 36, 38 and 40 correspond to the fan speed. These same posititions, as we said earlier, are repeated also in positions 52, 54 and 56 with opposite values. The possible values seem to be 010 (AUTO), 011 (LOW), 101 (MEDIUM), 110 (HIGH) and 100 (OFF). There is an special value, which is only transmitted when the AUTO mode is selected, with value 111.
- Position 46 (repeated with opposite value in position 62) corresponds to the power state (turned on or off). The false “0” value is turned ON and the true value “1” is turned OFF.
- Positions 68, 70, 72 and 74, as we told earlier, with the opposing positions 84, 86, 88 and 90 correspond to the temperature. First I thought (and I still think) there is a relation between the amount of degrees and the value (interpreted in binary) of these four positions, but I have not found out. Possibles values are 0001 (Turned off), 1111 (17ºC), 1110 (18ºC), 1100 (19ºC), 1101 (20ºC), 1001 (21ºC), 1000 (22ºC), 1010 (23ºC), 1011 (24ºC), 0011 (25ºC), 0010 (26ºC), 0110 (27ºC), 0111 (28ºC), 0101 (29ºC) and 0100 (30ºC).
- Positions 76 and 78 (with opposing values 92 and 94) correspond to the functioning mode, being 01 in AUTO mode (cold or hot depending on the current room temperature and the selected temperature), 11 in COOL mode, 10 in fan mode and 00 in HEAT mode.
- The complete command (positions 1 to 99) repeat with the same value in positions 101 to 199, using a separator value of approximately 4600 microseconds. I suppose this is for error prevention or correction.
With all this information, I started creating an arduino sketch, to confirm all the conclusions were correct.
First, I declared an array which I filled up with the fixed values that do not change in the command, leaving those which do change (speed, power, temperature and mode) as zero.
uint16_t commandTemplate[] = {4660, 4240, 768, 1422, 768, 348, 768, 1422, 768, 1422, 768, 348, 768, 348, 768, 1422, //Unknown - Header? 768, 348, 768, 348, 768, 1422, 768, 348, 768, 348, 768, 1422, 768, 1422, 768, 348, //Unknown - Filler? Other functions? 768, 1422, 768, 0, 768, 0, 768, 0, 768, 1422, 768, 1422, 768, 0, 768, 1422, //Speed and ON/OFF 768, 1422, 768, 0, 768, 0, 768, 0, 768, 348, 768, 348, 768, 0, 768, 348, //Speed and ON/OFF - repetition (inverted) 768, 348, 768, 0, 768, 0, 768, 0, 768, 0, 768, 0, 768, 0, 768, 348, //Temperature and mode 768, 348, 768, 0, 768, 0, 768, 0, 768, 0, 768, 0, 768, 0, 768, 1422, //Temperature and mode - repetition (inverted) 768, 1422, 768, //Unknown - Trailer? 4660, //Separator - Command repetition --------------------- 4660, 4240, 768, 1422, 768, 348, 768, 1422, 768, 1422, 768, 348, 768, 348, 768, 1422, //Unknown - Header? 768, 348, 768, 348, 768, 1422, 768, 348, 768, 348, 768, 1422, 768, 1422, 768, 348, //Unknown - Filler? Other functions? 768, 1422, 768, 0, 768, 0, 768, 0, 768, 1422, 768, 1422, 768, 0, 768, 1422, //Speed and ON/OFF 768, 1422, 768, 0, 768, 0, 768, 0, 768, 348, 768, 348, 768, 0, 768, 348, //Speed and ON/OFF - repetition (inverted) 768, 348, 768, 0, 768, 0, 768, 0, 768, 0, 768, 0, 768, 0, 768, 348, //Temperature and mode 768, 348, 768, 0, 768, 0, 768, 0, 768, 0, 768, 0, 768, 0, 768, 1422, //Temperature and mode - repetition (inverted) 768, 1422, 768}; //Unknown - Trailer?
I also declared several arrays, one for each function of the air conditioner with the representation in binary of every value:
/** * I'm not exactly sure if there is correlation between the temperature in degrees and the binary values. If there is, I * have not been able to find it. Here are the specific codes for every temperature. */ const boolean temperatureCommandValues[][4] { {false, false, false, true}, //OFF -> 0001 {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}, //Filler positions {true, true, true, true}, //17ºC -> 1111 {true, true, true, false}, //18ºC -> 1110 {true, true, false, false}, //19ºC -> 1100 {true, true, false, true}, //20ºC -> 1101 {true, false, false, true}, //21ºC -> 1001 {true, false, false, false}, //22ºC -> 1000 {true, false, true, false}, //23ºC -> 1010 {true, false, true, true}, //24ºC -> 1011 {false, false, true, true}, //25ºC -> 0011 {false, false, true, false}, //26ºC -> 0010 {false, true, true, false}, //27ºC -> 0110 {false, true, true, true}, //28ºC -> 0111 {false, true, false, true}, //29ºC -> 0101 {false, true, false, false} }; //30ºC -> 0100 /** * Weirdly enough, there is an special speed value for AUTO mode. Value AUTO for speed is not accepted by the machine, * so the special value is used. */ const boolean speedCommandValues[][3] { {false, true, false}, //AUTO -> 010 {false, true, true}, //LOW -> 011 {true, false, true}, //MED -> 101 {true, true, false}, //HIGH -> 110 {true, true, true}, //SPECIAL -> 111 {true, false, false} }; //OFF -> 100 /** * Another weird point here is the value for COOL here is the same as the value for OFF mode. Oh well... */ const boolean modeCommandValues[][2] { {false, true}, //AUTO -> 01 {true, true}, //COOL -> 11, also OFF {true, false}, //FAN -> 10 {false, false} }; //HEAT -> 00
With some subroutines to control how to load every value, I had a functioning little sketch, that I will use as a base for my ESP-01. I left it below, so you can download it. You can also find it on my github. The next step is to migrate it to the ESP-01 and communicate with OpenHAB using MQTT as the protocol. Then, the hardware modifications 😊
See you in my next post!