#include "Arduino.h"
#include "LgapController.h"
// [00] // Group ID (4bits), Unit ID (4bits)
// [01] // Unused (1bits), Power (1bits), Mode (3bits), Fan speed (3bits) //12 = X 0 010 010
// [02] // Unused (5bits), Auto swing (1bits), Plasma (1bits), Lock (1bits)
// [03] // desiredTemp
// [04] // roomTemp
// byte defautUnitData[] = {0x00, 0x00, 0x00, 0x00, 0x00};
// TX0 start byte
// TX1 init byte
// TX2 init byte
// TX3 groupId (4bit) & UnitId (4bit)
// TX4 "000" & Plasma (1bit) & "0" & Lock (1bit) & EXE (1bit) & Power ON/OFF (1bit)
// TX5 "0" & Fan speed (3bit) & Auto Swing (1bit) & Mode (3bit)
// TX6 "000" & Desired temperature (5bit)
// TX7 Check Sum = (TX1 + ... + TX6) XOR 0x55
byte defaultPI485Data[] = {0x80, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00};
LgapController::LgapController(byte groupId, byte unitId, byte * defaultData) {
_groupId = groupId;
_unitId = unitId;
_unitData = defaultData;
}
void LgapController::initUnit() {
Serial.print("#LGAP Class# Set group and unit ID: ");
Serial.print(_groupId);
Serial.println(_unitId);
setGroupId(_groupId);
setUnitId(_unitId);
Serial.print("#LGAP Class# ID: ");
Serial.print(getGroupId());
Serial.println(getUnitId());
}
void LgapController::setGroupId(byte groupId) { _unitData[0] = (groupId << 4) + (_unitData[0] & 0x0F); }
void LgapController::setUnitId(byte unitId) { _unitData[0] = (_unitData[0] & 0xF0) + unitId; }
void LgapController::setPower(byte power) { bitWrite(_unitData[1], 7, power); }
void LgapController::setMode(byte mode) { _unitData[1] &= (mode << 3) + 0x07; }
void LgapController::setFanSpeed(byte fanSpeed) { _unitData[1] &= fanSpeed + 0xF8; }
void LgapController::setAutoSwing(byte autoSwing) { bitWrite(_unitData[2], 2, autoSwing); }
void LgapController::setPlasma(byte plasma) { bitWrite(_unitData[2], 1, plasma); }
void LgapController::setLock(byte lock) { bitWrite(_unitData[2], 0, lock); }
void LgapController::setDesiredTemp(byte desiredTemp) { _unitData[2] = desiredTemp & 0x0F; }
void LgapController::setRoomTemp(byte roomTemp) { _unitData[3] = roomTemp & 0xFF; }
byte LgapController::getGroupId() { return (_unitData[0] & 0xF0) >> 4; }
byte LgapController::getUnitId() { return _unitData[0] & 0x0F; }
byte LgapController::getPower() { return bitRead(_unitData[1], 6); }
byte LgapController::getMode() { return (_unitData[1] & 0x38) >> 3; }
byte LgapController::getFanSpeed() { return _unitData[1] & 0x07; }
byte LgapController::getAutoSwing() { return bitRead(_unitData[2], 2); }
byte LgapController::getPlasma() { return bitRead(_unitData[2], 1); }
byte LgapController::getLock() { return bitRead(_unitData[2], 0); }
byte LgapController::getDesiredTemp() { return _unitData[3] & 0x0F; }
byte LgapController::getRoomTemp() { return _unitData[4] & 0xFF; }
// Generate RS485 data for PI485
byte * LgapController::encodePi485Data(byte groupId, byte unitId, byte EXE, byte power, byte mode, byte desiredTemp, byte fanSpeed, byte autoSwing, byte plasma, byte lock) {
uint16_t checkSum = 0x00;
for (int i = 0; i < 8; i++) {
if (i == 3) { defaultPI485Data[i] = (groupId << 4) + unitId; }
if (i == 4) { defaultPI485Data[i] = plasma * 0x10 + lock * 0x04 + EXE * 0x02 + power; }
if (i == 5) { defaultPI485Data[i] = fanSpeed * 0x10 + autoSwing * 0x08 + mode; }
if (i == 6) { defaultPI485Data[i] = desiredTemp & 0x1F; }
if (i == 7) { defaultPI485Data[i] = checkSum ^ 0x55; } else { checkSum = checkSum + defaultPI485Data[i]; }
}
return defaultPI485Data;
}
// Convert RS485 received data from PI485
void LgapController::decodePi485Data(byte * datas) {
uint16_t checkSum = 0x00;
for (int i = 0; i < 15; i++) {
checkSum = checkSum + datas[i];
}
checkSum = checkSum & 0xFF;
checkSum = checkSum ^ 0x55;
bool validDatas = (checkSum == datas[15]);
if (validDatas) {
byte groupId = (datas[4] & 0xF0) >> 4;
Serial.print(" group ID: ");Serial.print(groupId);
byte unitId = datas[4] & 0x0F;
Serial.print(" Unit ID: ");Serial.print(unitId);
byte power = bitRead(datas[1], 0);
Serial.print(" Power: ");Serial.print(power);
// setPower(power);
byte mode = datas[6] & 0x07;
Serial.print(" Mode: ");Serial.print(mode);
// setMode(mode);
byte fanSpeed = datas[6] & 0x70 >> 4;
Serial.print(" Fan speed: ");Serial.print(fanSpeed);
// setFanSpeed(fanSpeed);
byte autoSwing = bitRead(datas[6], 3);
Serial.print(" Auto swing: ");Serial.print(autoSwing);
// setAutoSwing(autoSwing);
byte plasma = bitRead(datas[7], 5);
Serial.print(" Plasma: ");Serial.print(plasma);
// setPlasma(plasma);
byte lock = bitRead(datas[1], 2);
Serial.print(" Lock: ");Serial.print(lock);
// setLock(lock);
// Temperatures
byte desiredTemp = datas[7] & 0x1F;
Serial.print(" Desired temp: ");Serial.print(desiredTemp);
// setDesiredTemp(desiredTemp);
byte roomTemp = datas[8];
Serial.print(" Room temp: ");Serial.print(roomTemp);
// setRoomTemp(roomTemp);
Serial.println("");
} else {
Serial.println("Wrong reception");
}
}
void LgapController::process() {
byte dataReceived[160];
byte dataIndex = 0;
// Convert unit data from parameters
byte groupId = getGroupId(); // Group ID
byte unitId = getUnitId(); // Unit ID
byte power = getPower(); // 1 power ON - 0 power OFF
byte mode = getMode(); // 0 Cooling - 1 Dry - 2 Fan - 3 Auto (Monitoring) - 4 Heat
byte fanSpeed = getFanSpeed(); // 1 Low - 2 Middle - 3 Hight - 4 Auto (Optional) - 5 Very low (Optional) - 6 Very high (Optional)
byte autoSwing = getAutoSwing(); // 1 Auto swing ON - 0 Auto Swing OFF
byte plasma = getPlasma(); // 1 plasma ON - 0 plasma OFF
byte lock = getLock(); // 1 Lock - 0 Unlock
byte desiredTemp = getDesiredTemp(); // Temperature table
byte roomTemp = getRoomTemp(); // Temperature table
Serial.print("Send data to PI485:");
Serial.print(" UNIT ID:");Serial.print(groupId);Serial.print(unitId);
Serial.print(" Power:");Serial.print(power);
Serial.print(" Mode:");Serial.print(mode);
Serial.print(" Fan speed:");Serial.print(fanSpeed);
Serial.print(" Plasma:");Serial.print(plasma);
Serial.println("");
int EXE = 0;
for (int i = 1; i <= 4; i++) {
digitalWrite(SERIAL_COMMUNICATION_CONTROL_PIN, LGAP_TX_PIN_VALUE); // Init transmit
if (i <= 3) {
EXE = 1;
} else {
EXE = 0;
} // Set to 1 for 3times then set to 0
byte * msg = encodePi485Data(groupId, unitId, EXE, power, mode, desiredTemp, fanSpeed, autoSwing, plasma, lock);
for (int i = 0; i < 8; i++) {
Serial.print(msg[i], HEX);
if (i < 7){ Serial.print(", "); } else if (i == 7) { Serial.println(""); }
LGAPSerial.write(msg[i]);
}
delayMicroseconds(2200);
// if (EXE == 0) {
Serial.print("Receive data from PI485:");
digitalWrite(SERIAL_COMMUNICATION_CONTROL_PIN, LGAP_RX_PIN_VALUE); // Init receive
while(LGAPSerial.available() > 0) {
byte b = LGAPSerial.read();
dataReceived[dataIndex++] = b;
}
if (dataIndex == 16) {
decodePi485Data(dataReceived);
dataIndex = 0;
} else {
Serial.print("ERROR dataIndex: ");Serial.println(dataIndex);
}
// }
delay(100);
}
}