diff --git a/libraries/HeatpumpIR/CarrierHeatpumpIR.cpp b/libraries/HeatpumpIR/CarrierHeatpumpIR.cpp index 244f03d..2b08763 100644 --- a/libraries/HeatpumpIR/CarrierHeatpumpIR.cpp +++ b/libraries/HeatpumpIR/CarrierHeatpumpIR.cpp @@ -141,7 +141,7 @@ void CarrierHeatpumpIR::sendCarrier(IRSender& IR, uint8_t operatingMode, uint8_t sendBuffer[8] = IR.bitReverse(checksum); // 40 kHz PWM frequency - IR.setFrequency(40); + IR.setFrequency(38); // Header IR.mark(CARRIER_AIRCON1_HDR_MARK); diff --git a/libraries/HeatpumpIR/FujitsuHeatpumpIR.cpp b/libraries/HeatpumpIR/FujitsuHeatpumpIR.cpp index dbad1ab..294491b 100644 --- a/libraries/HeatpumpIR/FujitsuHeatpumpIR.cpp +++ b/libraries/HeatpumpIR/FujitsuHeatpumpIR.cpp @@ -176,7 +176,7 @@ void FujitsuHeatpumpIR::sendFujitsuTestRun(IRSender& IR) void FujitsuHeatpumpIR::sendFujitsuMsg(IRSender& IR, uint8_t msgSize, uint8_t *msg) { // 40 kHz PWM frequency - IR.setFrequency(40); + IR.setFrequency(38); // Header IR.mark(FUJITSU_AIRCON1_HDR_MARK); diff --git a/libraries/HeatpumpIR/MideaHeatpumpIR.cpp b/libraries/HeatpumpIR/MideaHeatpumpIR.cpp index bf58bab..7f5d5c9 100644 --- a/libraries/HeatpumpIR/MideaHeatpumpIR.cpp +++ b/libraries/HeatpumpIR/MideaHeatpumpIR.cpp @@ -118,7 +118,7 @@ void MideaHeatpumpIR::sendMidea(IRSender& IR, uint8_t operatingMode, uint8_t fan void MideaHeatpumpIR::sendMidearaw(IRSender& IR, uint8_t sendBuffer[]) { // 40 kHz PWM frequency - IR.setFrequency(40); + IR.setFrequency(38); // Header IR.mark(MIDEA_AIRCON1_HDR_MARK); diff --git a/libraries/HeatpumpIR/MitsubishiHeatpumpIR.cpp b/libraries/HeatpumpIR/MitsubishiHeatpumpIR.cpp index 7823e57..23b7fee 100644 --- a/libraries/HeatpumpIR/MitsubishiHeatpumpIR.cpp +++ b/libraries/HeatpumpIR/MitsubishiHeatpumpIR.cpp @@ -188,7 +188,7 @@ void MitsubishiHeatpumpIR::sendMitsubishi(IRSender& IR, uint8_t powerMode, uint8 MitsubishiTemplate[17] = checksum; // 40 kHz PWM frequency - IR.setFrequency(40); + IR.setFrequency(38); // The Mitsubishi data is repeated twice for (int j=0; j<2; j++) { diff --git a/libraries/HeatpumpIR/PanasonicCKPHeatpumpIR.cpp b/libraries/HeatpumpIR/PanasonicCKPHeatpumpIR.cpp index 23978e9..fb62e9f 100644 --- a/libraries/HeatpumpIR/PanasonicCKPHeatpumpIR.cpp +++ b/libraries/HeatpumpIR/PanasonicCKPHeatpumpIR.cpp @@ -163,7 +163,7 @@ void PanasonicCKPHeatpumpIR::sendPanasonicCKP(IRSender& IR, uint8_t operatingMod void PanasonicCKPHeatpumpIR::sendPanasonicCKPraw(IRSender& IR, uint8_t sendBuffer[]) { // 40 kHz PWM frequency - IR.setFrequency(40); + IR.setFrequency(38); // Header, two first uint8_ts repeated IR.mark(PANASONIC_AIRCON1_HDR_MARK); @@ -228,7 +228,7 @@ void PanasonicCKPHeatpumpIR::sendPanasonicCKPOnOffTimerCancel(IRSender& IR, bool } // 40 kHz PWM frequency - IR.setFrequency(40); + IR.setFrequency(38); for (int i=0; i<6; i++) { IR.mark(PANASONIC_AIRCON1_HDR_MARK); diff --git a/libraries/HeatpumpIR/PanasonicHeatpumpIR.cpp b/libraries/HeatpumpIR/PanasonicHeatpumpIR.cpp index ee0be97..ff4c292 100644 --- a/libraries/HeatpumpIR/PanasonicHeatpumpIR.cpp +++ b/libraries/HeatpumpIR/PanasonicHeatpumpIR.cpp @@ -208,7 +208,7 @@ void PanasonicHeatpumpIR::sendPanasonic(IRSender& IR, uint8_t operatingMode, uin panasonicTemplate[26] = checksum; // 40 kHz PWM frequency - IR.setFrequency(40); + IR.setFrequency(38); // Header IR.mark(PANASONIC_AIRCON2_HDR_MARK); diff --git a/libraries/HeatpumpIR/README.md b/libraries/HeatpumpIR/README.md index f56737e..6047150 100644 --- a/libraries/HeatpumpIR/README.md +++ b/libraries/HeatpumpIR/README.md @@ -12,6 +12,7 @@ Currently supports at least these models * Fujitsu Nocria AWYZ14 (remote control P/N AR-PZ2) * Mitsubishi MSZ FD-25, probably also FD-35 (remote control P/N KM09D 0052376) * Hisense AUD (remote control Y-H1-01, Y-H1-02(E), Y-J1, Y-E4-07) probably AUC model +* Sharp AY-ZP40KR (remote control P/N CRMC-A788JBEZ), possibly also IVT ## Instructions diff --git a/libraries/HeatpumpIR/SamsungHeatpumpIR.cpp b/libraries/HeatpumpIR/SamsungHeatpumpIR.cpp index eb943bc..859dc7e 100644 --- a/libraries/HeatpumpIR/SamsungHeatpumpIR.cpp +++ b/libraries/HeatpumpIR/SamsungHeatpumpIR.cpp @@ -90,8 +90,8 @@ void SamsungHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operati void SamsungHeatpumpIR::sendSamsung(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV) { uint8_t SamsungTemplate[] = { 0x02, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, // Header part - 0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00, // Always the same data on POWER messages - 0x01, 0x00, 0xFE, 0x71, 0x00, 0x00, 0x00 }; // The actual data is in this part, on uint8_ts 14-20 + 0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00, // Always the same data on POWER messages + 0x01, 0x00, 0xFE, 0x71, 0x00, 0x00, 0x00 }; // The actual data is in this part, on uint8_ts 14-20 uint8_t SamsungChecksum = 0; @@ -114,15 +114,15 @@ void SamsungHeatpumpIR::sendSamsung(IRSender& IR, uint8_t powerMode, uint8_t ope // Set the vertical swing mode on the template message SamsungTemplate[16] = swingV; - // Calculate the uint8_t 15 checksum + // Calculate the byte 15 checksum // Count the number of ONE bits on message uint8_ts 15-20 for (uint8_t j=15; j<21; j++) { - uint8_t Samsunguint8_t = SamsungTemplate[j]; + uint8_t Samsungbyte = SamsungTemplate[j]; for (uint8_t i=0; i<8; i++) { - if ( (Samsunguint8_t & 0x01) == 0x01 ) { + if ( (Samsungbyte & 0x01) == 0x01 ) { SamsungChecksum++; } - Samsunguint8_t >>= 1; + Samsungbyte >>= 1; } } diff --git a/libraries/HeatpumpIR/SharpHeatpumpIR.cpp b/libraries/HeatpumpIR/SharpHeatpumpIR.cpp new file mode 100644 index 0000000..a9a937b --- /dev/null +++ b/libraries/HeatpumpIR/SharpHeatpumpIR.cpp @@ -0,0 +1,122 @@ +#include + + +SharpHeatpumpIR::SharpHeatpumpIR() : HeatpumpIR() +{ + static const char PROGMEM model[] PROGMEM = "sharp"; + static const char PROGMEM info[] PROGMEM = "{\"mdl\":\"sharp\",\"dn\":\"Sharp AY-ZP40KR\",\"mT\":18,\"xT\":32,\"fs\":3,\"maint\":[10]}}"; + + _model = model; + _info = info; +} + + +void SharpHeatpumpIR::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 powerMode = SHARP_AIRCON1_MODE_ON; + uint8_t operatingMode = SHARP_AIRCON1_MODE_HEAT; + uint8_t fanSpeed = SHARP_AIRCON1_FAN_AUTO; + uint8_t temperature = 23; + + if (powerModeCmd == 0) + { + powerMode = SHARP_AIRCON1_MODE_OFF; + } + + switch (operatingModeCmd) + { + case MODE_HEAT: + operatingMode = SHARP_AIRCON1_MODE_HEAT; + break; + case MODE_COOL: + operatingMode = SHARP_AIRCON1_MODE_COOL; + break; + case MODE_DRY: + operatingMode = SHARP_AIRCON1_MODE_DRY; + temperatureCmd = 10; + break; + case MODE_FAN: + operatingMode = SHARP_AIRCON1_MODE_COOL; + // Temperature needs to be set to 32 degrees for 'simulated' FAN mode + temperatureCmd = 32; + break; + case MODE_MAINT: // Maintenance mode is just the heat mode at +8 or +10, FAN5 + operatingMode |= SHARP_AIRCON1_MODE_HEAT; + temperature = 10; + fanSpeedCmd = FAN_5; + break; + } + + switch (fanSpeedCmd) + { + case FAN_AUTO: + fanSpeed = SHARP_AIRCON1_FAN_AUTO; + break; + case FAN_1: + fanSpeed = SHARP_AIRCON1_FAN1; + break; + case FAN_2: + fanSpeed = SHARP_AIRCON1_FAN2; + break; + case FAN_3: + fanSpeed = SHARP_AIRCON1_FAN3; + break; + } + + if ( temperatureCmd > 16 && temperatureCmd < 32) + { + temperature = temperatureCmd; + } + + sendSharp(IR, powerMode, operatingMode, fanSpeed, temperature); +} + +void SharpHeatpumpIR::sendSharp(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature) +{ + uint8_t SharpTemplate[] = { 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x00, 0x00, 0x06, 0x08, 0x80, 0x04, 0xF0, 0x01 }; + // 0 1 2 3 4 5 6 7 8 9 10 11 12 + + uint8_t checksum = 0x00; + + // Set the power mode on the template message + SharpTemplate[5] = powerMode; + + // Set the fan speed & operating mode on the template message + SharpTemplate[6] = fanSpeed | operatingMode; + + // Set the temperature on the template message + if (temperature == 10) { + SharpTemplate[4] = 0x00; // Maintenance mode temperature + } else { + SharpTemplate[4] = (temperature - 17); + } + + // Calculate the checksum + for (int i=0; i<12; i++) { + checksum ^= SharpTemplate[i]; + } + + checksum ^= SharpTemplate[12] & 0x0F; + checksum ^= (checksum >> 4); + checksum &= 0x0F; + + SharpTemplate[12] |= (checksum << 4); + + // 38 kHz PWM frequency + IR.setFrequency(38); + + // Header + IR.mark(SHARP_AIRCON1_HDR_MARK); + IR.space(SHARP_AIRCON1_HDR_SPACE); + + // Data + for (unsigned int i=0; i + + +// Sharp timing constants +#define SHARP_AIRCON1_HDR_MARK 3540 // 3820 +#define SHARP_AIRCON1_HDR_SPACE 1720 // 1680 +#define SHARP_AIRCON1_BIT_MARK 460 // 420 +#define SHARP_AIRCON1_ONE_SPACE 1400 // 1250 +#define SHARP_AIRCON1_ZERO_SPACE 430 // 330 + +// Sharp codes +#define SHARP_AIRCON1_MODE_HEAT 0x01 +#define SHARP_AIRCON1_MODE_COOL 0x02 +#define SHARP_AIRCON1_MODE_DRY 0x03 +#define SHARP_AIRCON1_MODE_OFF 0x21 // Power OFF +#define SHARP_AIRCON1_MODE_ON 0x31 // Power ON +#define SHARP_AIRCON1_FAN_AUTO 0x20 // Fan speed +#define SHARP_AIRCON1_FAN1 0x30 +#define SHARP_AIRCON1_FAN2 0x50 +#define SHARP_AIRCON1_FAN3 0x70 + + +class SharpHeatpumpIR : public HeatpumpIR +{ + public: + SharpHeatpumpIR(); + void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd); + + private: + void sendSharp(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature); +}; + +#endif diff --git a/libraries/HeatpumpIR/examples/simple/simple.ino b/libraries/HeatpumpIR/examples/simple/simple.ino index 229c936..b7723d1 100644 --- a/libraries/HeatpumpIR/examples/simple/simple.ino +++ b/libraries/HeatpumpIR/examples/simple/simple.ino @@ -7,6 +7,7 @@ #include #include #include +#include IRSender irSender(3); // IR led on Duemilanove digital pin 3 @@ -14,7 +15,7 @@ IRSender irSender(3); // IR led on Duemilanove digital pin 3 HeatpumpIR *heatpumpIR[] = {new PanasonicCKPHeatpumpIR(), new PanasonicDKEHeatpumpIR(), new PanasonicJKEHeatpumpIR(), new PanasonicNKEHeatpumpIR(), new CarrierHeatpumpIR(), new MideaHeatpumpIR(), new FujitsuHeatpumpIR(), new MitsubishiFDHeatpumpIR(), new MitsubishiFEHeatpumpIR(), - new SamsungHeatpumpIR(), NULL}; + new SamsungHeatpumpIR(), new SharpHeatpumpIR(), NULL}; void setup() { diff --git a/libraries/HeatpumpIR/keywords.txt b/libraries/HeatpumpIR/keywords.txt index b7e0632..7fa5eb1 100644 --- a/libraries/HeatpumpIR/keywords.txt +++ b/libraries/HeatpumpIR/keywords.txt @@ -11,6 +11,7 @@ MitsubishiHeatpumpIR KEYWORD1 MitsubishiFDHeatpumpIR KEYWORD1 MitsubishiFEHeatpumpIR KEYWORD1 SamsungHeatpumpIR KEYWORD1 +SharpHeatpumpIR KEYWORD1 IRSender KEYWORD1 diff --git a/libraries/MySensors/examples/HeatpumpIRController/HeatpumpIRController.ino b/libraries/MySensors/examples/HeatpumpIRController/HeatpumpIRController.ino index 33a68c2..d14953b 100644 --- a/libraries/MySensors/examples/HeatpumpIRController/HeatpumpIRController.ino +++ b/libraries/MySensors/examples/HeatpumpIRController/HeatpumpIRController.ino @@ -40,6 +40,7 @@ #include #include #include +#include // Timer library, https://github.com/JChristensen/Timer #include @@ -72,7 +73,8 @@ HeatpumpIR *heatpumpIR[] = { new PanasonicCKPHeatpumpIR(), // 0, keep this if yo new FujitsuHeatpumpIR(), // 6 new MitsubishiFDHeatpumpIR(), // 7 new MitsubishiFEHeatpumpIR(), // 8 - new SamsungHeatpumpIR() // 9 + new SamsungHeatpumpIR(), // 9 + new SharpHeatpumpIR() // 10 }; // IR led on PWM output-capable digital pin 3