/** * Midea AC IR driver * driving a IR LED at 38 KHz on digital pin 5 */ #define PIN_AC_IR 5; unsigned long t0, t; void setup() { Serial.begin(19200); Serial.print("Emit IR Remote, pin "); Serial.println(PIN_AC_IR); pinMode(PIN_AC_IR, OUTPUT); } /******************************************************************** * * * Driver for Midea AC through IR control * * * ********************************************************************/ /* protocol encodes temperatures on 4 bits in a crazy way, range is very limited too */ int midea_temperature(int temp) { if ((temp < 17) || (temp > 30)) return(-1); switch (temp) { case 17: return(0); case 18: return(1); case 19: return(3); case 20: return(2); case 21: return(6); case 22: return(7); case 23: return(5); case 24: return(4); case 25: return(12); case 26: return(13); case 27: return(9); case 28: return(8); case 29: return(10); case 30: return(11); } return(-1); } void send_mark(int us) { unsigned long e, t = micros(); e = t + us; while (t < e) { digitalWrite(PIN_AC_IR, HIGH); if (t - e < 4) { while ((t = micros()) < e); digitalWrite(PIN_AC_IR, LOW); break; } if (t - e < 22) { delayMicroseconds(t-e); digitalWrite(PIN_AC_IR, LOW); break; } delayMicroseconds(22); digitalWrite(PIN_AC_IR, LOW); t = micros(); if (t - e < 4) { while ((t = micros()) < e); break; } delayMicroseconds(4); t = micros(); } } void send_space(int us) { digitalWrite(PIN_AC_IR, LOW); delayMicroseconds(us); } void emit_midea_start(void) { send_mark(4200); send_space(4500); } void emit_midea_end(void) { send_mark(550); send_space(4500); } void emit_midea_byte(byte b) { int i; byte cur = b; byte mask = 0x80; for (i = 0;i < 8;i++) { send_mark(350); if (cur & mask) send_space(1700); else send_space(600); mask >>= 1; } cur = ~b; mask = 0x80; for (i = 0;i < 8;i++) { send_mark(350); if (cur & mask) send_space(1700); else send_space(600); mask >>= 1; } } void command_midea_ac(byte b1, byte b2) { emit_midea_start(); emit_midea_byte(0xB2); emit_midea_byte(b1); emit_midea_byte(b2); emit_midea_end(); /* do we need any delay there before reemission ? */ emit_midea_start(); emit_midea_byte(0xB2); emit_midea_byte(b1); emit_midea_byte(b2); emit_midea_end(); } int stop_midea_ac() { command_midea_ac(0x7B, 0xE0); return(0); } int cool_midea_ac(int temp) { byte fan_speed = 0x9; /* 1001: 1, 0101: 2, 0011: 3, 1011 : auto, 1110: off */ byte command = 0x0; /* 0000: cool, 1100: heat, 1000: auto, 1101: humidity extraction */ int t = midea_temperature(temp); if (t < 0) { Serial.print("Failed to convert temperature"); Serial.println(temp); return(-1); } command_midea_ac(fan_speed << 4 | 0xF, ((byte) t) << 4 | command); return(0); } int warm_midea_ac(int temp) { byte fan_speed = 0x9; /* 1001: 1, 0101: 2, 0011: 3, 1011 : auto, 1110: off */ byte command = 0xC; /* 0000: cool, 1100: heat, 1000: auto, 1101: humidity extraction */ int t = midea_temperature(temp); if (t < 0) { Serial.print("Failed to convert temperature"); Serial.println(temp); return(-1); } command_midea_ac(fan_speed << 4 | 0xF, ((byte) t) << 4 | command); return(0); } void loop() { int i; t0 = micros(); cool_midea_ac(23); t = micros(); Serial.print("took :"); Serial.println(t - t0); delay(15000); t0 = micros(); warm_midea_ac(26); t = micros(); Serial.print("took :"); Serial.println(t - t0); delay(15000); t0 = micros(); stop_midea_ac(); t = micros(); Serial.print("took :"); Serial.println(t - t0); delay(30000); }