/*** Infra-red remote control simulator ***/
+/*
+ * The AC unit expects demodulated IR signal. The RC sends 52-bit messages
+ * (plus leader and trailer). The last 4 bits are a complement of checksum
+ * of 4-bit nibbles.
+ */
+
#define RC_POWER_OFF_HI 0b00000000000000000000
#define RC_POWER_OFF_LO 0b00000000000000010000000010100100
#define RC_DEFAULT_HI 0b00000011000000000000
-// Various temperatures
-#define RC_17_COOL_AUTO 0b00000000000000010000000000101001
-#define RC_18_COOL_AUTO 0b00000000000000010000000000111000
-#define RC_19_COOL_AUTO 0b00000000000000010000000001000111
-#define RC_20_COOL_AUTO 0b00000000000000010000000001010110
-#define RC_21_COOL_AUTO 0b00000000000000010000000001100101
-#define RC_22_COOL_AUTO 0b00000000000000010000000001110100
-#define RC_23_COOL_AUTO 0b00000000000000010000000010000011
-#define RC_24_COOL_AUTO 0b00000000000000010000000010010010
-#define RC_25_COOL_AUTO 0b00000000000000010000000010100001
-#define RC_26_COOL_AUTO 0b00000000000000010000000010110000
-#define RC_27_COOL_AUTO 0b00000000000000010000000011001111
-#define RC_28_COOL_AUTO 0b00000000000000010000000011011110
-#define RC_29_COOL_AUTO 0b00000000000000010000000011101101
-#define RC_30_COOL_AUTO 0b00000000000000010000000011111100
-
-// Various fan settings
-#define RC_17_COOL_HI 0b00000000000000010000100000100001
-#define RC_17_COOL_MED 0b00000000000000010001000100100111
-#define RC_17_COOL_LO 0b00000000000000010010001000100101
-
-// Stand-alone, no temperature nor fan setting
-#define RC_DEHUMIDIFY 0b00000000000000010010010000100011
-
-// Combines with a temperature setting, but no fan setting
-#define RC_17_WARM 0b00000000000000010000001100100110
-
-// All modes have a sleep variant, which we do not use yet
-#define RC_17_COOL_AUTO_SLEEP 0b00000000000010010000000000100001
-
-static const u32 rc_fan_settings[4] = {
- 0,
- RC_17_COOL_LO ^ RC_17_COOL_AUTO,
- RC_17_COOL_MED ^ RC_17_COOL_AUTO,
- RC_17_COOL_HI ^ RC_17_COOL_AUTO,
+// Combines with a temperature setting (17-30)
+#define RC_COOL_AUTO 0b00000000000000010000000000000000
+#define RC_COOL_HI 0b00000000000000010000100000000000
+#define RC_COOL_MED 0b00000000000000010001000100000000
+#define RC_COOL_LO 0b00000000000000010010001000000000
+
+static const u32 rc_cool_fan[4] = {
+ RC_COOL_AUTO,
+ RC_COOL_LO,
+ RC_COOL_MED,
+ RC_COOL_HI,
};
-static const u32 rc_temp_settings[14] = {
-#define X(t) RC_##t##_COOL_AUTO ^ RC_17_COOL_AUTO
- X(17),
- X(18),
- X(19),
- X(20),
- X(21),
- X(22),
- X(23),
- X(24),
- X(25),
- X(26),
- X(27),
- X(28),
- X(29),
- X(30),
-#undef X
-};
+// Combines with a temperature setting (15-25)
+#define RC_WARM 0b00000000000000010000001100000000
+
+// This is sent with temperature=17
+#define RC_DEHUMIDIFY 0b00000000000000010010010000000000
+
+// This can be added to any command to enable sleep mode, but we do not issue these yet
+#define RC_SLEEP 0b00000000000010000000000000000000
enum rc_mode {
MODE_OFF,
static byte rc_mode = MODE_COOL; // MODE_xxx
static byte rc_fan; // 0-3
-static byte rc_temp = 17; // 17-30
+static byte rc_temp = 17; // 15-30
static void rc_init(void)
{
}
rc_pattern[0] = RC_DEFAULT_HI;
- uint t = rc_temp, f = rc_fan;
+ uint t = rc_temp;
if (rc_mode == MODE_COOL) {
- rc_pattern[1] = RC_17_COOL_AUTO;
+ rc_pattern[1] = rc_cool_fan[rc_fan];
+ if (t < 17)
+ t = 17;
+ if (t > 30)
+ t = 30;
} else if (rc_mode == MODE_WARM) {
- rc_pattern[1] = RC_17_WARM;
- f = 0;
+ rc_pattern[1] = RC_WARM;
+ if (t < 15)
+ t = 15;
+ if (t > 25)
+ t = 25;
} else {
rc_pattern[1] = RC_DEHUMIDIFY;
- f = t = 0;
+ t = 17;
}
- rc_pattern[1] ^= rc_fan_settings[f];
+ // Encode temperature
+ rc_pattern[1] |= (t - 15) << 4;
- if (t >= 17 && t < 17 + ARRAY_SIZE(rc_temp_settings))
- rc_pattern[1] ^= rc_temp_settings[t - 17];
+ // Compute checksum
+ uint sum = 0;
+ for (uint i=0; i<2; i++)
+ for (uint j=0; j<32; j+=4)
+ sum += (rc_pattern[i] >> j) & 0x0f;
+ rc_pattern[1] |= (sum & 0x0f) ^ 0x0f;
}
void tim4_isr(void)