#pragma GCC optimize("-Os")
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.hpp>
#define PwrPin 2 //AC OnOff Pin 2
#define SelectPin 3 //Mode Selector Pin 3
#define DHTPin 4 //DHT Pin 4
#define IRSendPin 5 //Sender Pin 5
#define IRRecPin 6 //Receiver Pin 6
bool configstatus = 0, pwrstatus = 0, lastfanspeed = 0;
int displaycount = 0, controlcount = 0, lastactemp = 0;
float temp, humid;
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(DHTPin, DHT22);
void setup() {
pinMode(IRSendPin, OUTPUT);
pinMode(PwrPin, INPUT_PULLUP);
pinMode(SelectPin, INPUT_PULLUP);
IrReceiver.begin(IRRecPin);
IrSender.begin(IRSendPin);
Serial.begin(9600);
lcd.init(); //Initialize LCD
lcd.clear(); //Clear LCD
lcd.backlight(); //Turn on LCD backlight
dht.begin();
attachInterrupt(digitalPinToInterrupt(PwrPin), pwr, FALLING);
attachInterrupt(digitalPinToInterrupt(SelectPin), config, FALLING);
}
const uint16_t pwrOn[67] PROGMEM = {8880,4470, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,570, 480,570, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,1720, 480,1670, 530,520, 530,1670, 480,570, 480,570, 480,570, 480,1670, 530,520, 530,1670, 530,1670, 480,570, 480,1720, 480,1720, 480,1670, 530,520, 530,1670, 480,570, 480};
const uint16_t pwrOff[67] PROGMEM = {8880,4520, 480,520, 530,520, 530,520, 530,520, 480,570, 480,570, 480,570, 480,520, 530,1670, 530,1670, 480,1720, 480,1720, 480,1720, 480,1670, 530,1670, 530,1670, 530,520, 480,1720, 480,570, 480,520, 530,520, 530,1670, 530,520, 480,1720, 480,1720, 480,570, 480,1670, 530,1670, 530,1670, 530,520, 480,1720, 480,570, 480};
const uint16_t htemp27[67] PROGMEM = {8880,4470, 480,570, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,570, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,1720, 480,520, 530,1670, 530,520, 480,570, 480,570, 480,570, 480,1670, 530,520, 530,1670, 530,520, 480,1720, 480,1720, 480,1720, 480,1670, 530,520, 530,1670, 480};
const uint16_t htemp26[67] PROGMEM = {8930,4470, 480,570, 480,520, 530,520, 530,520, 480,570, 480,570, 480,570, 480,520, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,1720, 480,1670, 530,1670, 530,520, 480,1720, 480,570, 480,1720, 480,1670, 530,520, 530,1670, 530,520, 480,1720, 480,570, 480,1670, 530,520, 530,520, 530,1670, 480,570, 480,1720, 480};
const uint16_t htemp25[67] PROGMEM = {8880,4470, 530,520, 530,520, 530,520, 480,570, 480,570, 480,570, 480,520, 530,520, 530,1670, 530,1670, 480,1720, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,570, 480,570, 480,570, 480,1670, 530,1670, 530,1670, 530,520, 480,570, 480,1720, 480,1670, 530,1670, 530,520, 530,520, 480,570, 480,1720, 480,1720, 480};
const uint16_t htemp24[67] PROGMEM = {8880,4470, 480,570, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,570, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,1720, 480,520, 530,520, 530,520, 530,520, 480,1720, 480,570, 480,520, 530,520, 530,1670, 530,1670, 480,1720, 480,1720, 480,570, 480,1670, 530,1670, 530,1670, 480};
const uint16_t htemp23[67] PROGMEM = {8880,4470, 530,520, 480,570, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,1720, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,570, 480,1670, 530,520, 530,1670, 480,1720, 480,1720, 480,1720, 480,520, 530,1670, 530,520, 530,1670, 480,570, 480,570, 480,570, 480,520, 530,1670, 530};
const uint16_t htemp22[67] PROGMEM = {8880,4470, 480,570, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,570, 480,1720, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,520, 530,520, 530,520, 530,1670, 480,1720, 480,570, 480,570, 480,520, 530,1670, 530,1670, 530,1670, 480,570, 480,570, 480,1670, 530,1670, 530,1670, 530};
const uint16_t ltemp27[67] PROGMEM = {8880,4470, 480,570, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,570, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,1720, 480,520, 530,1670, 530,520, 480,570, 480,570, 480,570, 480,1670, 530,520, 530,1670, 530,520, 480,1720, 480,1720, 480,1720, 480,1670, 530,520, 530,1670, 480};
const uint16_t ltemp26[67] PROGMEM = {8930,4470, 480,570, 480,520, 530,520, 530,520, 480,570, 480,570, 480,570, 480,520, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,1720, 480,1670, 530,1670, 530,520, 480,1720, 480,570, 480,1720, 480,1670, 530,520, 530,1670, 530,520, 480,1720, 480,570, 480,1670, 530,520, 530,520, 530,1670, 480,570, 480,1720, 480};
const uint16_t ltemp25[67] PROGMEM = {8880,4470, 530,520, 530,520, 530,520, 480,570, 480,570, 480,570, 480,520, 530,520, 530,1670, 530,1670, 480,1720, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,570, 480,570, 480,570, 480,1670, 530,1670, 530,1670, 530,520, 480,570, 480,1720, 480,1670, 530,1670, 530,520, 530,520, 480,570, 480,1720, 480,1720, 480};
const uint16_t ltemp24[67] PROGMEM = {8880,4470, 480,570, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,570, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,1720, 480,520, 530,520, 530,520, 530,520, 480,1720, 480,570, 480,520, 530,520, 530,1670, 530,1670, 480,1720, 480,1720, 480,570, 480,1670, 530,1670, 530,1670, 480};
const uint16_t ltemp23[67] PROGMEM = {8880,4470, 530,520, 480,570, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,1720, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,570, 480,1670, 530,520, 530,1670, 480,1720, 480,1720, 480,1720, 480,520, 530,1670, 530,520, 530,1670, 480,570, 480,570, 480,570, 480,520, 530,1670, 530};
const uint16_t ltemp22[67] PROGMEM = {8880,4470, 480,570, 480,570, 480,570, 480,520, 530,520, 530,520, 530,520, 480,570, 480,1720, 480,1720, 480,1670, 530,1670, 530,1670, 530,1670, 480,1720, 480,1720, 480,520, 530,520, 530,520, 530,1670, 480,1720, 480,570, 480,570, 480,520, 530,1670, 530,1670, 530,1670, 480,570, 480,570, 480,1670, 530,1670, 530,1670, 530};
void loop() {
if (configstatus == 1) {
calib();
} else if (pwrstatus == 0) {
scroll();
} else {
normal();
}
}
void normal() {
temp = dht.readTemperature();
humid = dht.readHumidity();
if (displaycount == 0) {
displaycount = 500;
lcdprint();
delay(1000);
}
if (controlcount == 0) {
controlcount = 5000;
hdex();
delay(1000);
}
displaycount--;
controlcount--;
}
void lcdprint() {
lcd.clear();
lcd.setCursor(2, 0); //Set cursor to character 2 on line 0
lcd.print("Temp: ");
lcd.print(temp, 1); //Output temperature
lcd.print((char) 223);
lcd.print("C"); //Output degrees character
lcd.setCursor(2, 1); //Set cursor to character 2 on line 0
lcd.print("Humid: ");
if (humid < 10) {
lcd.print(0);
}
lcd.print(humid, 1); //Output humidity
lcd.print("%"); //Output %
}
void calib() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Calibration Mode");
if (IrReceiver.decode()) {
if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_WAS_OVERFLOW) {
Serial.println("IR code too long. Edit IRremote.h and increase RAW_BUFFER_LENGTH");
} else {
IrReceiver.compensateAndPrintIRResultAsCArray( & Serial, true); //Output the results as uint16_t source code array of micros
IrReceiver.resume();
}
}
delay(500);
}
void hdex() {
int actemp = temp;
bool fanspeed;
/*
//Calculate dew point
double RATIO = 373.15 / (273.15 + temp);
double RHS = -7.90298 * (RATIO - 1);
RHS += 5.02808 * log10(RATIO);
RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / RATIO))) - 1);
RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1);
RHS += log10(1013.246);
double T = log((pow(10, RHS - 3) * humid) / 0.61078);
double dew = (241.88 * T) / (17.558 - T);
//Calculate humidex
double e = 5417.7530 * ((1 / 273.15) - (1 / (273.15 + dew)));
float humidex = temp + 0.5555 * (6.11 * exp(e) - 10);
if (humidex > 28) {
if (temp > 28 || humid > 50) {
//Decrease temp by 4 deg
actemp = temp - 4;
} else {
//Decrease temp by 2 deg
actemp = temp - 2;
}
}
Serial.print("Humidex: ");
Serial.println(humidex);
*/
if (temp <= 24) {
if (temp <= 23) {
actemp = temp + 3;
} else {
actemp = temp + 1;
}
} else if (temp >= 25) {
if (temp >= 26) {
actemp = temp - 3;
} else {
actemp = temp - 1;
}
}
if (humid < 40) {
fanspeed = 1;
} else {
fanspeed = 0;
}
accontrol(actemp, fanspeed);
}
void pwr() {
pwrstatus = !pwrstatus;
if (pwrstatus) {
IrSender.sendRaw_P(pwrOn, sizeof(pwrOn) / sizeof(pwrOn[0]), NEC_KHZ);
Serial.println("Power On");
} else {
IrSender.sendRaw_P(pwrOff, sizeof(pwrOff) / sizeof(pwrOff[0]), NEC_KHZ);
Serial.println("Power Off");
}
}
void config() {
configstatus = !configstatus;
}
void scroll() {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Press Green Button to Power On ");
for (int x = 0; x < 18; x++) {
lcd.scrollDisplayLeft();
lcd.setCursor(x, 0);
lcd.print(" POWERED OFF");
delay(500);
}
}
void accontrol(int actemp, bool fanspeed) {
if (lastactemp != actemp || lastfanspeed != fanspeed) {
if (fanspeed == 1) {
switch (actemp) {
case 27:
IrSender.sendRaw_P(htemp27, sizeof(htemp27) / sizeof(htemp27[0]), NEC_KHZ);
Serial.println("Temp set to 27. Fan High");
break;
case 26:
IrSender.sendRaw_P(htemp26, sizeof(htemp26) / sizeof(htemp26[0]), NEC_KHZ);
Serial.println("Temp set to 26. Fan High");
break;
case 25:
IrSender.sendRaw_P(htemp25, sizeof(htemp25) / sizeof(htemp25[0]), NEC_KHZ);
Serial.println("Temp set to 25. Fan High");
break;
case 24:
IrSender.sendRaw_P(htemp24, sizeof(htemp24) / sizeof(htemp24[0]), NEC_KHZ);
Serial.println("Temp set to 24. Fan High");
break;
case 23:
IrSender.sendRaw_P(htemp23, sizeof(htemp23) / sizeof(htemp23[0]), NEC_KHZ);
Serial.println("Temp set to 23. Fan High");
break;
case 22:
IrSender.sendRaw_P(htemp22, sizeof(htemp22) / sizeof(htemp22[0]), NEC_KHZ);
Serial.println("Temp set to 22. Fan High");
break;
default:
if (actemp > 27) {
IrSender.sendRaw_P(htemp27, sizeof(htemp27) / sizeof(htemp27[0]), NEC_KHZ);
Serial.println("Temp set to 27. Fan High");
} else {
IrSender.sendRaw_P(htemp22, sizeof(htemp22) / sizeof(htemp22[0]), NEC_KHZ);
Serial.println("Temp set to 22. Fan High");
}
break;
}
} else {
switch (actemp) {
case 27:
IrSender.sendRaw_P(ltemp27, sizeof(ltemp27) / sizeof(ltemp27[0]), NEC_KHZ);
Serial.println("Temp set to 27. Fan Low");
break;
case 26:
IrSender.sendRaw_P(ltemp26, sizeof(ltemp26) / sizeof(ltemp26[0]), NEC_KHZ);
Serial.println("Temp set to 26. Fan Low");
break;
case 25:
IrSender.sendRaw_P(ltemp25, sizeof(ltemp25) / sizeof(ltemp25[0]), NEC_KHZ);
Serial.println("Temp set to 25. Fan Low");
break;
case 24:
IrSender.sendRaw_P(ltemp24, sizeof(ltemp24) / sizeof(ltemp24[0]), NEC_KHZ);
Serial.println("Temp set to 24. Fan Low");
break;
case 23:
IrSender.sendRaw_P(ltemp23, sizeof(ltemp23) / sizeof(ltemp23[0]), NEC_KHZ);
Serial.println("Temp set to 23. Fan Low");
break;
case 22:
IrSender.sendRaw_P(ltemp22, sizeof(ltemp22) / sizeof(ltemp22[0]), NEC_KHZ);
Serial.println("Temp set to 22. Fan Low");
break;
default:
if (actemp > 27) {
IrSender.sendRaw_P(ltemp27, sizeof(ltemp27) / sizeof(ltemp27[0]), NEC_KHZ);
Serial.println("Temp set to 27. Fan Low");
} else {
IrSender.sendRaw_P(ltemp22, sizeof(ltemp22) / sizeof(ltemp22[0]), NEC_KHZ);
Serial.println("Temp set to 22. Fan Low");
}
break;
}
}
}
lastactemp = actemp;
lastfanspeed = fanspeed;
}