class Timer {
private:
unsigned long nextChangeTime;
unsigned long timeOn_;
boolean overFlow;
public:
void TimerSet (unsigned long timeOn) {
timeOn_ = timeOn;
unsigned long currentTime = micros();
nextChangeTime = currentTime + timeOn;
if (nextChangeTime > currentTime) {
overFlow = false;
} else {
overFlow = true;
}
}
boolean TimerActive() {
unsigned long currentTime = micros();
boolean val = false;
if (! overFlow) {
if (currentTime < nextChangeTime) {
val = true;
}
} else if ((currentTime + timeOn_)<(nextChangeTime + timeOn_)){
val = true;
}
return val;
}
};
#include <LiquidCrystal_I2C.h> /*include LCD I2C Library*/
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
#define LED 4
int BTN_MODE = 6;
int BTN_OK = 7;
int BTN_CANCEL = 8;
int BTN_UP = 9;
int BTN_DOWN = 10;
unsigned long debounceDuration = 50; //millis
enum currentStateType {
ready,
set,
busy
};
enum currentSetupType {
none,
power,
timer,
temp
};
currentStateType currentState = ready;
currentSetupType currentSetup = none;
int currentMode = 0; //0 OFF; 1 VENT; 2 COOL; 3 WARM; 4 AUTO
int currentTemp = random(10, 25);
int setPower = 10;
int setTimer = 0;
int setTemp = 10;
bool timerActive = false;
Timer TMR;
void setup() {
lcd.init(); // LCD display initialized
lcd.clear(); // Clear LCD Display
lcd.backlight(); // Turn on LCD backlight
lcd.print("UIT");
pinMode(LED, OUTPUT);
pinMode(BTN_MODE, INPUT_PULLUP);
pinMode(BTN_OK, INPUT_PULLUP);
pinMode(BTN_CANCEL, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
}
void loop() {
byte buttonState_BTN_MODE = digitalRead(BTN_MODE);
byte buttonState_BTN_OK = digitalRead(BTN_OK);
byte buttonState_BTN_CANCEL = digitalRead(BTN_CANCEL);
byte buttonState_BTN_UP = digitalRead(BTN_UP);
byte buttonState_BTN_DOWN = digitalRead(BTN_DOWN);
if (buttonState_BTN_MODE == HIGH && buttonState_BTN_OK == HIGH && buttonState_BTN_UP == HIGH && buttonState_BTN_DOWN == HIGH) {
checkCancelButton();
};
if (currentState != busy) {
digitalWrite(LED, LOW);
if (currentState == ready) {
if (buttonState_BTN_OK == HIGH && buttonState_BTN_CANCEL == HIGH){
checkModeButton();
}
}
if (currentState == set) {
if (buttonState_BTN_OK == HIGH && buttonState_BTN_CANCEL == HIGH && buttonState_BTN_DOWN == HIGH){
checkUpButton();
}
if (buttonState_BTN_OK == HIGH && buttonState_BTN_CANCEL == HIGH && buttonState_BTN_UP == HIGH){
checkDownButton();
}
}
if (buttonState_BTN_MODE == HIGH && buttonState_BTN_CANCEL == HIGH && buttonState_BTN_UP == HIGH && buttonState_BTN_DOWN == HIGH) {
checkOkButton();
}
} else {
digitalWrite(LED, HIGH);
if (currentMode == 4) {
if (timerActive) {
if(!TMR.TimerActive()){
if (currentTemp > setTemp) {
currentTemp --;
displayHandler();
TMR.TimerSet(random(1000000, 3000000));
} else if (currentTemp < setTemp) {
currentTemp ++;
displayHandler();
TMR.TimerSet(random(1000000, 3000000));
} else {
resetAll();
displayHandler();
}
}
}
} else {
if (setTimer == 0){
if(!TMR.TimerActive()){
displayHandler();
TMR.TimerSet(1000000);
}
} else {
if (timerActive) {
if(!TMR.TimerActive()){
setTimer --;
if (setTimer > 0) {
displayHandler();
TMR.TimerSet(1000000);
} else {
resetAll();
displayHandler();
}
}
}
}
}
}
};
//MODE Button
unsigned long lastTimeButtonStateChanged_BTN_MODE = 0;
byte lastButtonState_BTN_MODE = LOW;
void checkModeButton() {
if (millis() - lastTimeButtonStateChanged_BTN_MODE > debounceDuration) {
byte buttonState = digitalRead(BTN_MODE);
if (buttonState != lastButtonState_BTN_MODE) {
lastTimeButtonStateChanged_BTN_MODE = millis();
lastButtonState_BTN_MODE = buttonState;
if (buttonState == LOW) {
modeHandler();
displayHandler();
}
}
}
};
//OK Button
unsigned long lastTimeButtonStateChanged_BTN_OK = 0;
byte lastButtonState_BTN_OK = LOW;
void checkOkButton() {
if (millis() - lastTimeButtonStateChanged_BTN_OK > debounceDuration) {
byte buttonState = digitalRead(BTN_OK);
if (buttonState != lastButtonState_BTN_OK) {
lastTimeButtonStateChanged_BTN_OK = millis();
lastButtonState_BTN_OK = buttonState;
if (buttonState == LOW) {
okHandler();
displayHandler();
}
}
}
};
//CANCEL Button
unsigned long lastTimeButtonStateChanged_BTN_CANCEL = 0;
byte lastButtonState_BTN_CANCEL = LOW;
void checkCancelButton() {
if (millis() - lastTimeButtonStateChanged_BTN_CANCEL > debounceDuration) {
byte buttonState = digitalRead(BTN_CANCEL);
if (buttonState != lastButtonState_BTN_CANCEL) {
lastTimeButtonStateChanged_BTN_CANCEL = millis();
lastButtonState_BTN_CANCEL = buttonState;
if (buttonState == LOW) {
resetAll();
displayHandler();
}
}
}
};
//UP Button
unsigned long lastTimeButtonStateChanged_BTN_UP = 0;
byte lastButtonState_BTN_UP = LOW;
void checkUpButton() {
if (millis() - lastTimeButtonStateChanged_BTN_UP > debounceDuration) {
byte buttonState = digitalRead(BTN_UP);
if (buttonState != lastButtonState_BTN_UP) {
lastTimeButtonStateChanged_BTN_UP = millis();
lastButtonState_BTN_UP = buttonState;
if (buttonState == LOW) {
upHandler();
displayHandler();
}
}
}
};
//DOWN Button
unsigned long lastTimeButtonStateChanged_BTN_DOWN = 0;
byte lastButtonState_BTN_DOWN = LOW;
void checkDownButton() {
if (millis() - lastTimeButtonStateChanged_BTN_DOWN > debounceDuration) {
byte buttonState = digitalRead(BTN_DOWN);
if (buttonState != lastButtonState_BTN_DOWN) {
lastTimeButtonStateChanged_BTN_DOWN = millis();
lastButtonState_BTN_DOWN = buttonState;
if (buttonState == LOW) {
downHandler();
displayHandler();
}
}
}
};
void modeHandler() {
if (currentMode <= 3) {
currentMode ++;
} else {
currentMode = 0;
}
}
void okHandler(){
if (currentMode == 0) return;
if (currentState == ready) {
currentState = set;
}
if (currentState == set) {
if (currentMode == 1 || currentMode == 2 || currentMode == 3) {
if (currentSetup == none) {
currentSetup = power;
return;
} else if (currentSetup == power) {
currentSetup = timer;
return;
} else {
currentState = busy;
timerActive = true;
return;
}
} else if (currentMode == 4) {
if (currentSetup == none) {
currentSetup = temp;
return;
} else if (currentSetup == temp) {
currentSetup = power;
return;
} else {
currentState = busy;
timerActive = true;
return;
}
}
} else {
return;
}
};
void upHandler(){
if (currentMode == 0) return;
if (currentState == ready) return;
if (currentSetup == none) return;
if (currentState == set) {
switch (currentSetup){
case power:
if (setPower <= 90) {
setPower += 10;
} else {
setPower = 10;
}
break;
case timer:
if (setTimer <= 90) {
setTimer += 10;
} else {
setTimer = 0;
}
break;
case temp:
if (setTemp <= 24) {
setTemp += 1;
} else {
setTemp = 10;
}
break;
}
}
};
void downHandler(){
if (currentMode == 0) return;
if (currentState == ready) return;
if (currentSetup == none) return;
if (currentState == set) {
switch (currentSetup){
case power:
if (setPower >= 20) {
setPower -= 10;
} else {
setPower = 100;
}
break;
case timer:
if (setTimer >= 10) {
setTimer -= 10;
} else {
setTimer = 100;
}
case temp:
if (setTemp >= 11) {
setTemp -= 1;
} else {
setTemp = 25;
}
}
}
};
void displayHandler(){
lcd.clear();
lcd.setCursor(0,0);
switch(currentMode){
case 0:
lcd.print("UIT");
break;
case 1:
lcd.print("VENTILEREN");
break;
case 2:
lcd.print("VERKOELEN");
break;
case 3:
lcd.print("VERWARMEN");
break;
case 4:
lcd.print("AUTO");
break;
}
lcd.setCursor(0,1);
if (currentState != busy){
switch (currentSetup) {
case power:
lcd.print(String("Vermogen: ") + String(setPower) + String("%"));
break;
case timer:
lcd.print(String("Timer: ") + String(setTimer) + String(" sec"));
break;
case temp:
lcd.print(String("Temp: ") + String(setTemp) + String("C"));
break;
default:
lcd.print("");
break;
}
} else {
if (currentMode == 4) {
lcd.print(String("Temp ") + String(currentTemp) + String("C"));
} else if (setTimer == 0) {
lcd.print(String("BZZZZZzzzz"));
} else {
lcd.print(String("Nog ") + String(setTimer) + String(" sec"));
}
}
};
void resetAll() {
lcd.clear();
currentState = ready;
currentSetup = none;
currentMode = 0; //0 OFF; 1 VENT; 2 COOL; 3 WARM; 4 AUTO
currentTemp = random(10, 25);
setPower = 10;
setTimer = 0;
setTemp = 10;
timerActive = false;
}