271 lines
6.0 KiB
C++

/*
* StateHandler.cpp
*
* Created on: Sep 21, 2022
* Author: tylen
*/
#include "StateHandler/StateHandler.h"
#define PID 1
StateHandler::StateHandler (LiquidCrystal *lcd, ModbusRegister *A01,
PressureWrapper *pressure, Timer *global)
{
this->_lcd = lcd;
this->A01 = A01;
this->pressure = pressure;
this->state_timer = global;
current = &StateHandler::stateInit;
(this->*current) (Event (Event::eEnter));
current_mode = MANUAL;
}
StateHandler::~StateHandler ()
{
// TODO Auto-generated destructor stub
}
void
StateHandler::displaySet (bool sensors)
{
char line_up[16] = { 0 };
char line_down[16] = { 0 };
if(sensors) {
snprintf (line_up, 16, "PRE:%02d TEM:%02d", sensors_data[PRESSUREDAT],
sensors_data[TEMPERATURE]);
snprintf (line_down, 16, "HUM:%02d CO2:%02d", sensors_data[HUMIDITY],
sensors_data[CO2]);
} else if (current_mode == MANUAL)
{
snprintf (line_up, 16, "SPEED: %02d%", saved_set_value[current_mode]);
snprintf (line_down, 16, "PRESSURE: %02dPa", saved_curr_value[current_mode]);
} else if(current_mode == AUTO)
{
snprintf (line_up, 16, "P. SET: %02dPa", saved_set_value[current_mode]);
snprintf (line_down, 16, "P. CURR: %02dPa", saved_curr_value[current_mode]);
}
_lcd->clear ();
_lcd->setCursor (0, 0);
_lcd->print (line_up);
_lcd->setCursor (0, 1);
_lcd->print (line_down);
}
void
StateHandler::displaySens ()
{
}
unsigned int
StateHandler::getSetPressure ()
{
return (unsigned int)this->value[PRESSURE].getCurrent ();
}
unsigned int
StateHandler::getSetSpeed ()
{
return (unsigned int)this->value[FAN_SPEED].getCurrent ();
}
void
StateHandler::HandleState (const Event &event)
{
(this->*current) (event);
}
void
StateHandler::SetState (state_pointer newstate)
{
(this->*current) (Event (Event::eExit));
current = newstate;
(this->*current) (Event (Event::eEnter));
}
void
StateHandler::stateInit (const Event &event)
{
switch (event.type)
{
case Event::eEnter:
break;
case Event::eExit:
_lcd->clear ();
break;
case Event::eKey:
handleControlButtons (event.value);
break;
case Event::eTick:
if (current_mode == MANUAL)
{
SetState (&StateHandler::stateManual);
}
else
{
SetState (&StateHandler::stateAuto);
}
break;
}
}
void
StateHandler::stateManual (const Event &event)
{
switch (event.type)
{
case Event::eEnter:
this->A01->write (fan_speed_normalized());
break;
case Event::eExit:
break;
case Event::eKey:
handleControlButtons (event.value);
break;
case Event::eTick:
if(event.value % 5000 == 0) {
SetState(&StateHandler::stateSensors);
displaySet(SENSORS);
}
if (event.value % 500 == 0)
{
SetState (&StateHandler::stateGetPressure);
break;
}
}
}
void
StateHandler::stateAuto (const Event &event)
{
switch (event.type)
{
case Event::eEnter:
this->A01->write (fan_speed.getCurrent ());
break;
case Event::eExit:
break;
case Event::eKey:
handleControlButtons (event.value);
break;
case Event::eTick:
if (event.value % 2 == 0)
{
SetState (&StateHandler::stateGetPressure);
}
if(event.value % 150 == 0) {
SetState(&StateHandler::stateSensors);
// displaySens ();
}
pid();
this->A01->write (fan_speed.getCurrent ());
break;
}
}
void
StateHandler::stateSensors (const Event &event)
{
switch (event.type)
{
case Event::eEnter:
sensors_data[PRESSUREDAT] = pressure->getPressure ();
sensors_data[TEMPERATURE] = humidity.readT ();
sensors_data[HUMIDITY] = humidity.readRH ();
sensors_data[CO2] = co2.read ();
// displaySens ();
break;
case Event::eExit:
break;
case Event::eKey:
handleControlButtons (event.value);
break;
case Event::eTick:
// save (pressure->getPressure (), ((current_mode) ? AUTO : MANUAL));
SetState (current_mode ? &StateHandler::stateAuto
: &StateHandler::stateManual);
break;
}
}
void
StateHandler::stateGetPressure (const Event &event)
{
switch (event.type)
{
case Event::eEnter:
pressure_status = pressure->isAwake ();
break;
case Event::eExit:
break;
case Event::eKey:
handleControlButtons (event.value);
break;
case Event::eTick:
if (!pressure_status)
{
pressure->wakeUp ();
break;
}
save (pressure->getPressure (), ((current_mode) ? AUTO : MANUAL));
SetState (current_mode ? &StateHandler::stateAuto
: &StateHandler::stateManual);
break;
}
}
void
StateHandler::handleControlButtons (uint8_t button)
{
switch (button)
{
case BUTTON_CONTROL_DOWN:
this->value[(current_mode) ? AUTO : MANUAL].dec ();
break;
case BUTTON_CONTROL_UP:
this->value[(current_mode) ? AUTO : MANUAL].inc ();
break;
case BUTTON_CONTROL_TOG_MODE:
current_mode = !current_mode;
SetState (&StateHandler::stateInit);
break;
default:
break;
}
}
void
StateHandler::save (int eventValue, size_t mode)
{
int counterValue = value[mode].getCurrent ();
if (saved_curr_value[mode] != eventValue
|| saved_set_value[mode] != counterValue)
{
saved_curr_value[mode] = eventValue;
saved_set_value[mode] = counterValue;
displaySet (MODES);
}
}
int
StateHandler::fan_speed_normalized() {
int speed = value[MANUAL].getCurrent();
if(speed <=92)
speed += 8;
return speed * 10;
}
void
StateHandler::pid ()
{
float kP = 1.0, kI = 0.1, kD = 0.125;
int error = 0, last_error = 0, derivative = 0;
error = saved_set_value[AUTO] - saved_curr_value[AUTO];
last_error = error;
integral += error;
derivative = error - last_error;
fan_speed.setInit ((kP * error) + (kI * integral) + (kD * derivative));
}