Separate Toshiba Daiseikai to its own module (even though it's very similar to Carrier)

This commit is contained in:
ToniA 2016-12-26 19:44:54 +02:00
parent ca26d28ca6
commit 374317929b
7 changed files with 224 additions and 209 deletions

View File

@ -19,15 +19,6 @@ CarrierNQVHeatpumpIR::CarrierNQVHeatpumpIR() : CarrierHeatpumpIR()
_info = info;
}
DaiseikaiHeatpumpIR::DaiseikaiHeatpumpIR() : CarrierHeatpumpIR()
{
static const char PROGMEM model[] PROGMEM = "carrier_nqv";
static const char PROGMEM info[] PROGMEM = "{\"mdl\":\"carrier_nqv\",\"dn\":\"Carrier NQV\",\"mT\":17,\"xT\":30,\"fs\":6}";
_model = model;
_info = info;
}
CarrierMCAHeatpumpIR::CarrierMCAHeatpumpIR() : CarrierHeatpumpIR()
{
static const char PROGMEM model[] PROGMEM = "carrier_mca";
@ -306,162 +297,3 @@ void CarrierMCAHeatpumpIR::sendCarrier(IRSender& IR, uint8_t powerMode, uint8_t
IR.mark(CARRIER_AIRCON2_BIT_MARK);
IR.space(0);
}
void DaiseikaiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd)
{
(void)swingVCmd;
(void)swingHCmd;
// Sensible defaults for the heat pump mode
uint8_t operatingMode = DAISEIKAI_AIRCON1_MODE_HEAT;
uint8_t fanSpeed = DAISEIKAI_AIRCON1_FAN_AUTO;
uint8_t temperature = 23;
if (powerModeCmd == POWER_OFF)
{
operatingMode = DAISEIKAI_AIRCON1_MODE_OFF;
}
else
{
switch (operatingModeCmd)
{
case MODE_AUTO:
operatingMode = DAISEIKAI_AIRCON1_MODE_AUTO;
break;
case MODE_HEAT:
operatingMode = DAISEIKAI_AIRCON1_MODE_HEAT;
break;
case MODE_COOL:
operatingMode = DAISEIKAI_AIRCON1_MODE_COOL;
break;
case MODE_DRY:
operatingMode = DAISEIKAI_AIRCON1_MODE_DRY;
fanSpeedCmd = FAN_AUTO; // Fan speed is always 'AUTO' in DRY mode
break;
case MODE_FAN:
operatingMode = DAISEIKAI_AIRCON1_MODE_FAN;
temperatureCmd = 22; // Temperature is always 22 in FAN mode
break;
}
}
switch (fanSpeedCmd)
{
case FAN_AUTO:
fanSpeed = DAISEIKAI_AIRCON1_FAN_AUTO;
break;
case FAN_1:
fanSpeed = DAISEIKAI_AIRCON1_FAN1;
break;
case FAN_2:
fanSpeed = DAISEIKAI_AIRCON1_FAN2;
break;
case FAN_3:
fanSpeed = DAISEIKAI_AIRCON1_FAN3;
break;
case FAN_4:
fanSpeed = DAISEIKAI_AIRCON1_FAN4;
break;
case FAN_5:
fanSpeed = DAISEIKAI_AIRCON1_FAN5;
break;
}
if (temperatureCmd > 16 && temperatureCmd < 31)
{
temperature = temperatureCmd;
}
sendCarrier(IR, operatingMode, fanSpeed, temperature);
}
// Send the Carrier code
// Carrier has the LSB and MSB in different format than Panasonic
void DaiseikaiHeatpumpIR::sendCarrier(IRSender& IR, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature)
{
uint8_t sendBuffer[] = { 0x4f, 0xb0, 0xc0, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00 }; // The data is on the last four bytes
static const uint8_t temperatures[] PROGMEM = { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b };
uint8_t checksum = 0;
// PROGMEM arrays cannot be addressed directly, see http://forum.arduino.cc/index.php?topic=106603.0
sendBuffer[5] = pgm_read_byte(&(temperatures[(temperature-17)]));
sendBuffer[6] = operatingMode | fanSpeed;
// Checksum
for (int i=0; i<8; i++) {
checksum += IR.bitReverse(sendBuffer[i]);
}
// There's something really strange with the checksum calculation...
// With these many of the codes matchs with the code from the real Carrier remote
// Still certain temperatures do not work with fan speeds 1, 2 or 5
switch (sendBuffer[6] & 0xF0) {
case 0x00: // MODE_AUTO - certain temperature / fan speed combinations do not work
checksum += 0x02;
switch (sendBuffer[6] & 0x0F) {
case 0x02: // FAN1
case 0x03: // FAN5
case 0x06: // FAN2
checksum += 0x80;
break;
}
break;
case 0x40: // MODE_DRY - all settings should work
checksum += 0x02;
break;
case 0xC0: // MODE_HEAT - certain temperature / fan speed combinations do not work
switch (sendBuffer[6] & 0x0F) {
case 0x05: // FAN4
case 0x06: // FAN2
checksum += 0xC0;
break;
}
break;
case 0x20: // MODE_FAN - all settings should work
checksum += 0x02;
switch (sendBuffer[6] & 0x0F) {
case 0x02: // FAN1
case 0x03: // FAN5
case 0x06: // FAN2
checksum += 0x80;
break;
}
break;
}
sendBuffer[8] = IR.bitReverse(checksum);
// 38 kHz PWM frequency
IR.setFrequency(38);
// Header
IR.mark(DAISEIKAI_AIRCON1_HDR_MARK);
IR.space(DAISEIKAI_AIRCON1_HDR_SPACE);
// Payload
for (size_t i=0; i<sizeof(sendBuffer); i++) {
IR.sendIRbyte(sendBuffer[i], DAISEIKAI_AIRCON1_BIT_MARK, DAISEIKAI_AIRCON1_ZERO_SPACE, DAISEIKAI_AIRCON1_ONE_SPACE);
}
// Pause + new header
IR.mark(DAISEIKAI_AIRCON1_BIT_MARK);
IR.space(DAISEIKAI_AIRCON1_MSG_SPACE);
IR.mark(DAISEIKAI_AIRCON1_HDR_MARK);
IR.space(DAISEIKAI_AIRCON1_HDR_SPACE);
// Payload again
for (size_t i=0; i<sizeof(sendBuffer); i++) {
IR.sendIRbyte(sendBuffer[i], DAISEIKAI_AIRCON1_BIT_MARK, DAISEIKAI_AIRCON1_ZERO_SPACE, DAISEIKAI_AIRCON1_ONE_SPACE);
}
// End mark
IR.mark(DAISEIKAI_AIRCON1_BIT_MARK);
IR.space(0);
}

View File

@ -29,29 +29,6 @@
#define CARRIER_AIRCON1_FAN4 0x05
#define CARRIER_AIRCON1_FAN5 0x03
// Toshiba Daiseikai (RAS-10G2KVP-E RAS-10G2AVP-E and RAS-13G2KVP-E RAS-13G2AVP-E) timing constants (remote control P/N WH-TA01EE)
// https://github.com/ToniA/arduino-heatpumpir/issues/23
#define DAISEIKAI_AIRCON1_HDR_MARK 4320
#define DAISEIKAI_AIRCON1_HDR_SPACE 4350
#define DAISEIKAI_AIRCON1_BIT_MARK 500
#define DAISEIKAI_AIRCON1_ONE_SPACE 1650
#define DAISEIKAI_AIRCON1_ZERO_SPACE 550
#define DAISEIKAI_AIRCON1_MSG_SPACE 7400
// Toshiba Daiseikai (Carrier) codes. Same as CarrierNQV ?
#define DAISEIKAI_AIRCON1_MODE_AUTO 0x00 // Operating mode
#define DAISEIKAI_AIRCON1_MODE_HEAT 0xC0
#define DAISEIKAI_AIRCON1_MODE_COOL 0x80
#define DAISEIKAI_AIRCON1_MODE_DRY 0x40
#define DAISEIKAI_AIRCON1_MODE_FAN 0x20
#define DAISEIKAI_AIRCON1_MODE_OFF 0xE0 // Power OFF
#define DAISEIKAI_AIRCON1_FAN_AUTO 0x00 // Fan speed
#define DAISEIKAI_AIRCON1_FAN1 0x02
#define DAISEIKAI_AIRCON1_FAN2 0x06
#define DAISEIKAI_AIRCON1_FAN3 0x01
#define DAISEIKAI_AIRCON1_FAN4 0x05
#define DAISEIKAI_AIRCON1_FAN5 0x03
// Carrier (42MCA009515LS) timing constants (remote control P/N R11CG/E)
#define CARRIER_AIRCON2_HDR_MARK 4510
@ -108,17 +85,4 @@ class CarrierMCAHeatpumpIR : public CarrierHeatpumpIR
void sendCarrier(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature);
};
class DaiseikaiHeatpumpIR : public CarrierHeatpumpIR
{
public:
DaiseikaiHeatpumpIR();
public:
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd);
private:
void sendCarrier(IRSender& IR, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature);
};
#endif

View File

@ -0,0 +1,170 @@
#include <ToshibaDaiseikaiHeatpumpIR.h>
ToshibaDaiseikaiHeatpumpIR::ToshibaDaiseikaiHeatpumpIR() : CarrierHeatpumpIR()
{
static const char PROGMEM model[] PROGMEM = "toshiba_daiseikai";
static const char PROGMEM info[] PROGMEM = "{\"mdl\":\"toshiba_daiseikai\",\"dn\":\"Toshiba Daiseikai\",\"mT\":17,\"xT\":30,\"fs\":6}";
_model = model;
_info = info;
}
void ToshibaDaiseikaiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd)
{
(void)swingVCmd;
(void)swingHCmd;
// Sensible defaults for the heat pump mode
uint8_t operatingMode = DAISEIKAI_AIRCON1_MODE_HEAT;
uint8_t fanSpeed = DAISEIKAI_AIRCON1_FAN_AUTO;
uint8_t temperature = 23;
if (powerModeCmd == POWER_OFF)
{
operatingMode = DAISEIKAI_AIRCON1_MODE_OFF;
}
else
{
switch (operatingModeCmd)
{
case MODE_AUTO:
operatingMode = DAISEIKAI_AIRCON1_MODE_AUTO;
break;
case MODE_HEAT:
operatingMode = DAISEIKAI_AIRCON1_MODE_HEAT;
break;
case MODE_COOL:
operatingMode = DAISEIKAI_AIRCON1_MODE_COOL;
break;
case MODE_DRY:
operatingMode = DAISEIKAI_AIRCON1_MODE_DRY;
fanSpeedCmd = FAN_AUTO; // Fan speed is always 'AUTO' in DRY mode
break;
case MODE_FAN:
operatingMode = DAISEIKAI_AIRCON1_MODE_FAN;
temperatureCmd = 22; // Temperature is always 22 in FAN mode
break;
}
}
switch (fanSpeedCmd)
{
case FAN_AUTO:
fanSpeed = DAISEIKAI_AIRCON1_FAN_AUTO;
break;
case FAN_1:
fanSpeed = DAISEIKAI_AIRCON1_FAN1;
break;
case FAN_2:
fanSpeed = DAISEIKAI_AIRCON1_FAN2;
break;
case FAN_3:
fanSpeed = DAISEIKAI_AIRCON1_FAN3;
break;
case FAN_4:
fanSpeed = DAISEIKAI_AIRCON1_FAN4;
break;
case FAN_5:
fanSpeed = DAISEIKAI_AIRCON1_FAN5;
break;
}
if (temperatureCmd > 16 && temperatureCmd < 31)
{
temperature = temperatureCmd;
}
sendDaiseikai(IR, operatingMode, fanSpeed, temperature);
}
// Send the Daiseikai code
// Daiseikai has the LSB and MSB in different format than Panasonic
void ToshibaDaiseikaiHeatpumpIR::sendDaiseikai(IRSender& IR, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature)
{
uint8_t sendBuffer[] = { 0x4f, 0xb0, 0xc0, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00 }; // The data is on the last four bytes
static const uint8_t temperatures[] PROGMEM = { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b };
uint8_t checksum = 0;
// PROGMEM arrays cannot be addressed directly, see http://forum.arduino.cc/index.php?topic=106603.0
sendBuffer[5] = pgm_read_byte(&(temperatures[(temperature-17)]));
sendBuffer[6] = operatingMode | fanSpeed;
// Checksum
for (int i=0; i<8; i++) {
checksum += IR.bitReverse(sendBuffer[i]);
}
// There's something really strange with the checksum calculation...
// With these many of the codes matchs with the code from the real Carrier remote
// Still certain temperatures do not work with fan speeds 1, 2 or 5
switch (sendBuffer[6] & 0xF0) {
case 0x00: // MODE_AUTO - certain temperature / fan speed combinations do not work
checksum += 0x02;
switch (sendBuffer[6] & 0x0F) {
case 0x02: // FAN1
case 0x03: // FAN5
case 0x06: // FAN2
checksum += 0x80;
break;
}
break;
case 0x40: // MODE_DRY - all settings should work
checksum += 0x02;
break;
case 0xC0: // MODE_HEAT - certain temperature / fan speed combinations do not work
switch (sendBuffer[6] & 0x0F) {
case 0x05: // FAN4
case 0x06: // FAN2
checksum += 0xC0;
break;
}
break;
case 0x20: // MODE_FAN - all settings should work
checksum += 0x02;
switch (sendBuffer[6] & 0x0F) {
case 0x02: // FAN1
case 0x03: // FAN5
case 0x06: // FAN2
checksum += 0x80;
break;
}
break;
}
sendBuffer[8] = IR.bitReverse(checksum);
// 38 kHz PWM frequency
IR.setFrequency(38);
// Header
IR.mark(DAISEIKAI_AIRCON1_HDR_MARK);
IR.space(DAISEIKAI_AIRCON1_HDR_SPACE);
// Payload
for (size_t i=0; i<sizeof(sendBuffer); i++) {
IR.sendIRbyte(sendBuffer[i], DAISEIKAI_AIRCON1_BIT_MARK, DAISEIKAI_AIRCON1_ZERO_SPACE, DAISEIKAI_AIRCON1_ONE_SPACE);
}
// Pause + new header
IR.mark(DAISEIKAI_AIRCON1_BIT_MARK);
IR.space(DAISEIKAI_AIRCON1_MSG_SPACE);
IR.mark(DAISEIKAI_AIRCON1_HDR_MARK);
IR.space(DAISEIKAI_AIRCON1_HDR_SPACE);
// Payload again
for (size_t i=0; i<sizeof(sendBuffer); i++) {
IR.sendIRbyte(sendBuffer[i], DAISEIKAI_AIRCON1_BIT_MARK, DAISEIKAI_AIRCON1_ZERO_SPACE, DAISEIKAI_AIRCON1_ONE_SPACE);
}
// End mark
IR.mark(DAISEIKAI_AIRCON1_BIT_MARK);
IR.space(0);
}

View File

@ -0,0 +1,48 @@
/*
Toshiba Daiseikai (RAS-10G2KVP-E RAS-10G2AVP-E and RAS-13G2KVP-E RAS-13G2AVP-E)
*/
#ifndef ToshibaDaiseikaiHeatpumpIR_h
#define ToshibaDaiseikaiHeatpumpIR_h
#include <HeatpumpIR.h>
#include <CarrierHeatpumpIR.h> // Toshiba Daiseikai is based on the Carrier models
// Toshiba Daiseikai (RAS-10G2KVP-E RAS-10G2AVP-E and RAS-13G2KVP-E RAS-13G2AVP-E) timing constants (remote control P/N WH-TA01EE)
// https://github.com/ToniA/arduino-heatpumpir/issues/23
#define DAISEIKAI_AIRCON1_HDR_MARK 4320
#define DAISEIKAI_AIRCON1_HDR_SPACE 4350
#define DAISEIKAI_AIRCON1_BIT_MARK 500
#define DAISEIKAI_AIRCON1_ONE_SPACE 1650
#define DAISEIKAI_AIRCON1_ZERO_SPACE 550
#define DAISEIKAI_AIRCON1_MSG_SPACE 7400
// Toshiba Daiseikai (Carrier) codes. Same as CarrierNQV ?
#define DAISEIKAI_AIRCON1_MODE_AUTO 0x00 // Operating mode
#define DAISEIKAI_AIRCON1_MODE_HEAT 0xC0
#define DAISEIKAI_AIRCON1_MODE_COOL 0x80
#define DAISEIKAI_AIRCON1_MODE_DRY 0x40
#define DAISEIKAI_AIRCON1_MODE_FAN 0x20
#define DAISEIKAI_AIRCON1_MODE_OFF 0xE0 // Power OFF
#define DAISEIKAI_AIRCON1_FAN_AUTO 0x00 // Fan speed
#define DAISEIKAI_AIRCON1_FAN1 0x02
#define DAISEIKAI_AIRCON1_FAN2 0x06
#define DAISEIKAI_AIRCON1_FAN3 0x01
#define DAISEIKAI_AIRCON1_FAN4 0x05
#define DAISEIKAI_AIRCON1_FAN5 0x03
class ToshibaDaiseikaiHeatpumpIR : public CarrierHeatpumpIR
{
public:
ToshibaDaiseikaiHeatpumpIR();
public:
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd);
private:
void sendDaiseikai(IRSender& IR, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature);
};
#endif

View File

@ -1,10 +1,10 @@
#include <Arduino.h>
#include <CarrierHeatpumpIR.h>
#include <ToshibaDaiseikaiHeatpumpIR.h>
IRSenderPWM irSender(9); // IR led on Duemilanove digital pin 3, using Arduino PWM
//IRSenderBlaster irSender(3); // IR led on Duemilanove digital pin 3, using IR Blaster (generates the 38 kHz carrier)
DaiseikaiHeatpumpIR *heatpumpIR;
ToshibaDaiseikaiHeatpumpIR *heatpumpIR;
int redLED = 6;
int orangeLED = 5;
@ -19,7 +19,7 @@ void setup()
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);
delay(500);
heatpumpIR = new DaiseikaiHeatpumpIR();
heatpumpIR = new ToshibaDaiseikaiHeatpumpIR();
Serial.println(F("Starting"));
}

View File

@ -15,6 +15,7 @@
#include <GreeHeatpumpIR.h>
#include <FuegoHeatpumpIR.h>
#include <ToshibaHeatpumpIR.h>
#include <ToshibaDaiseikaiHeatpumpIR.h>
#ifndef ESP8266
@ -34,7 +35,7 @@ HeatpumpIR *heatpumpIR[] = {new PanasonicCKPHeatpumpIR(), new PanasonicDKEHeatpu
new SamsungHeatpumpIR(), new SharpHeatpumpIR(), new DaikinHeatpumpIR(),
new MitsubishiHeavyZJHeatpumpIR(), new MitsubishiHeavyZMHeatpumpIR(),
new HyundaiHeatpumpIR(), new HisenseHeatpumpIR(), new GreeHeatpumpIR(),
new FuegoHeatpumpIR(), new ToshibaHeatpumpIR(),
new FuegoHeatpumpIR(), new ToshibaHeatpumpIR(), new ToshibaDaiseikaiHeatpumpIR(),
NULL};
void setup()

View File

@ -7,7 +7,7 @@ PanasonicNKEHeatpumpIR KEYWORD1
PanasonicLKEHeatpumpIR KEYWORD1
CarrierHeatpumpIR KEYWORD1
CarrierNQVHeatpumpIR KEYWORD1
DaiseikaiHeatpumpIR KEYWORD1
ToshibaDaiseikaiHeatpumpIR KEYWORD1
CarrierMCAHeatpumpIR KEYWORD1
MideaHeatpumpIR KEYWORD1
FujitsuHeatpumpIR KEYWORD1