#include <IRremote.h> //versione libreria 3.5.0
#include <JC_Button.h>
#include <LiquidCrystal.h>
#include <Servo.h>
// hardware buttons
#define BTN_POWER 4
// IR & IR commands
// Signal Pin of IR receiver
#define PIN_RECEIVER 2
#define IRCMD_POWER 162
// stati
#define S_POWER_ON 1
#define S_POWER_OFF 2
#define S_ENTER_SLEEP 3
#define S_ENTER_POWER_ON 4
#define S_POWER_INIT S_POWER_OFF
Button btnPower(BTN_POWER);
IRrecv receiver(PIN_RECEIVER);
// powerState è variabile di stato su switch case
uint8_t powerState = S_POWER_INIT;
uint8_t oldPowerState = S_POWER_ON;
uint8_t saveCommand;
uint32_t powerTimer;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
void setup() {
Serial.begin(115200);
receiver.enableIRIn(); // Start the receiver
lcd.begin(16, 2);
btnPower.begin();
}
void onLoop() {
static uint32_t time = millis();
if (millis() - time >= 500) {
Serial.print('.');
}
}
void loop() {
btnPower.read();
uint8_t command = 0;
if (receiver.decode()) {
command = receiver.decodedIRData.command;
receiver.resume(); // Receive the next value
Serial.println(command);
} else {
/*if (btnPower.pressedFor(300) && saveCommand != IRCMD_POWER) {
command = IRCMD_POWER;
saveCommand = command;
} else if (btnPower.isReleased()) {
saveCommand = 0;
}*/
if (btnPower.wasPressed())
command = IRCMD_POWER;
}
switch (powerState) {
case S_ENTER_POWER_ON:
if (command == 0 && millis() - powerTimer >= 1000)
powerState = S_POWER_ON;
// chiama funzione che accende gli alimentatori
// attende il riscaldamento con millis
// ok è pronto e passa a S_POWER_ON
break;
case S_POWER_ON:
if (command == IRCMD_POWER) {
Serial.println("go to sleep");
powerState = S_ENTER_SLEEP;
// salva il tempo in cui abbandona questo stato
//powerTimer = millis();
}
// chiama funzione onLoop();
onLoop();
// la funzione è equivalente al void loop()
// solo che adesso onLoop() viene chiamata
// dallo stato S_POWER_ON e pertanto tutto il
// codice contenuto in onLoop() viene eseguito
// perché la macchina è in S_POWER_ON.
break;
case S_ENTER_SLEEP:
// chiama funzione che spegne gli alimentatori
// se questi risultano accesi, diversamente non
// la chiama, ad esempio:
// if (powerSupply.isOn()) {
// powerSupply.off();
// }
// entra in modo sonno
// simula con delay un sonno di 2 secondi
//Serial.println("sono entrato in sleep");
//delay(2000);
// e resta qui fino a quando
// arriva una IRQ e si sveglia
// salva l'istante del risveglio
//if (btnPower.isPressed()) {
powerTimer = millis();
// cambia stato per S_POWER_OFF
powerState = S_POWER_OFF;
//Serial.println("esco da sleep e passo a power off");
//}
break;
case S_POWER_OFF:
if (command == IRCMD_POWER ) {
Serial.println("go to power on");
powerState = S_ENTER_POWER_ON;
powerTimer = millis();
} else if (millis() - powerTimer >= 1000) {
// dopo un secondo dal risveglio
// torna a dormire.
// Oppure se entro 1 secondo
// command vale IRCMD_POWER
powerState = S_ENTER_SLEEP;
}
break;
}
}