diff --git a/DaikinHeatpumpARC417IR.cpp b/DaikinHeatpumpARC417IR.cpp new file mode 100644 index 0000000..9b95a1f --- /dev/null +++ b/DaikinHeatpumpARC417IR.cpp @@ -0,0 +1,134 @@ +#include + +DaikinHeatpumpARC417IR::DaikinHeatpumpARC417IR() : HeatpumpIR() +{ + static const char PROGMEM model[] PROGMEM = "daikin_arc417"; + static const char PROGMEM info[] PROGMEM = "{\"mdl\":\"daikin_arc417\",\"dn\":\"Daikin ARC417\",\"mT\":18,\"xT\":30,\"fs\":6,\"maint\":[10,11,12,13,14,15,16,17]}}}"; + + _model = model; + _info = info; +} + + +// Daikin numeric values to command bytes +void DaikinHeatpumpARC417IR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd) +{ + // Sensible defaults for the heat pump mode + + uint8_t operatingMode = DAIKIN_AIRCON2_MODE_OFF | DAIKIN_AIRCON2_MODE_AUTO; + uint8_t fanSpeed = DAIKIN_AIRCON2_FAN_AUTO; + uint8_t temperature = 0x10; // 18 deg + + if ((operatingModeCmd == MODE_HEAT && temperatureCmd >= 14 && temperatureCmd <= 28) || + (operatingModeCmd == MODE_COOL && temperatureCmd >= 18 && temperatureCmd <= 32) || + (temperatureCmd >= 18 && temperatureCmd <= 28)) + { + temperature = (temperatureCmd << 1) - 20; + } + + switch (powerModeCmd) + { + case POWER_ON: + operatingMode |= DAIKIN_AIRCON2_MODE_ON; + break; + } + + switch (operatingModeCmd) + { + case MODE_AUTO: + operatingMode |= DAIKIN_AIRCON2_MODE_AUTO; + break; + case MODE_HEAT: + operatingMode |= DAIKIN_AIRCON2_MODE_HEAT; + break; + case MODE_COOL: + operatingMode |= DAIKIN_AIRCON2_MODE_COOL; + break; + case MODE_DRY: + operatingMode |= DAIKIN_AIRCON2_MODE_DRY; + temperature = 0x80; + break; + case MODE_FAN: + operatingMode |= DAIKIN_AIRCON2_MODE_FAN; + temperatureCmd = 0xC0; + break; + } + + switch (fanSpeedCmd) + { + case FAN_AUTO: + fanSpeed = DAIKIN_AIRCON2_FAN_AUTO; + break; + case FAN_1: + fanSpeed = DAIKIN_AIRCON2_FAN1; + break; + case FAN_2: + fanSpeed = DAIKIN_AIRCON2_FAN2; + break; + case FAN_3: + fanSpeed = DAIKIN_AIRCON2_FAN3; + break; + case FAN_4: + fanSpeed = DAIKIN_AIRCON2_FAN4; + break; + case FAN_5: + fanSpeed = DAIKIN_AIRCON2_FAN5; + break; + } + + sendDaikin(IR, operatingMode, fanSpeed, temperature, swingVCmd, swingHCmd); +} + + +// Send the Daikin code +void DaikinHeatpumpARC417IR::sendDaikin(IRSender& IR, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV, uint8_t swingH) +{ + (void)swingV; + (void)swingH; + + uint8_t daikinTemplate[20] = { + 0x11, 0xDA, 0x27, 0xF0, 0x0D, 0x00, 0x0F, // First header + // 0 1 2 3 4 5 6 + 0x11, 0xDA, 0x27, 0x00, 0xD3, 0x11, 0x00, 0x00, 0x00, 0x1E, 0x0A, 0x08, 0x26 }; + // 7 8 9 10 11 12 13 14 15 16 17 18 19 + + daikinTemplate[12] = operatingMode; + daikinTemplate[16] = temperature; + daikinTemplate[17] = fanSpeed; + + // Checksum calculation + // * Checksum at byte 6 is calculated the same way + uint8_t checksum = 0x00; + + for (int i=7; i<19; i++) { + checksum += daikinTemplate[i]; + } + + daikinTemplate[19] = checksum; + + // 38 kHz PWM frequency + IR.setFrequency(38); + + // Header + IR.mark(DAIKIN_AIRCON2_HDR_MARK); + IR.space(DAIKIN_AIRCON2_HDR_SPACE); + + // First header + for (int i=0; i<7; i++) { + IR.sendIRbyte(daikinTemplate[i], DAIKIN_AIRCON2_BIT_MARK, DAIKIN_AIRCON2_ZERO_SPACE, DAIKIN_AIRCON2_ONE_SPACE); + } + + // Pause + new header + IR.mark(DAIKIN_AIRCON2_BIT_MARK); + IR.space(DAIKIN_AIRCON2_MSG_SPACE); + IR.mark(DAIKIN_AIRCON2_HDR_MARK); + IR.space(DAIKIN_AIRCON2_HDR_SPACE); + + // + for (int i=7; i<20; i++) { + IR.sendIRbyte(daikinTemplate[i], DAIKIN_AIRCON2_BIT_MARK, DAIKIN_AIRCON2_ZERO_SPACE, DAIKIN_AIRCON2_ONE_SPACE); + } + + IR.mark(DAIKIN_AIRCON2_BIT_MARK); + IR.space(0); +} \ No newline at end of file diff --git a/DaikinHeatpumpARC417IR.h b/DaikinHeatpumpARC417IR.h new file mode 100644 index 0000000..cd9fa4b --- /dev/null +++ b/DaikinHeatpumpARC417IR.h @@ -0,0 +1,44 @@ +/* + Daikin heatpump control (Daikin remote control P/N ARC417A3) +*/ +#ifndef DaikinHeatpumpARC417IR_h +#define DaikinHeatpumpARC417IR_h + +#include + + +// Daikin timing constants +#define DAIKIN_AIRCON2_HDR_MARK 5050 +#define DAIKIN_AIRCON2_HDR_SPACE 2100 +#define DAIKIN_AIRCON2_BIT_MARK 391 +#define DAIKIN_AIRCON2_ONE_SPACE 1725 +#define DAIKIN_AIRCON2_ZERO_SPACE 667 +#define DAIKIN_AIRCON2_MSG_SPACE 30000 + +// Daikin codes +#define DAIKIN_AIRCON2_MODE_AUTO 0x10 // Operating mode +#define DAIKIN_AIRCON2_MODE_HEAT 0x40 +#define DAIKIN_AIRCON2_MODE_COOL 0x30 +#define DAIKIN_AIRCON2_MODE_DRY 0x20 +#define DAIKIN_AIRCON2_MODE_FAN 0x60 +#define DAIKIN_AIRCON2_MODE_OFF 0x00 // Power OFF +#define DAIKIN_AIRCON2_MODE_ON 0x01 +#define DAIKIN_AIRCON2_FAN_AUTO 0x0A // Fan speed +#define DAIKIN_AIRCON2_FAN1 0x03 +#define DAIKIN_AIRCON2_FAN2 0x04 +#define DAIKIN_AIRCON2_FAN3 0x05 +#define DAIKIN_AIRCON2_FAN4 0x06 +#define DAIKIN_AIRCON2_FAN5 0x07 + + +class DaikinHeatpumpARC417IR : public HeatpumpIR +{ + public: + DaikinHeatpumpARC417IR(); + void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd); + + private: + void sendDaikin(IRSender& IR, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV, uint8_t swingH); +}; + +#endif \ No newline at end of file