diff --git a/main/config.cpp b/main/config.cpp index f1003f3..f26d5cd 100644 --- a/main/config.cpp +++ b/main/config.cpp @@ -97,15 +97,12 @@ joystick_config_t configJoystick = { //---------------------------- //--- configure fan contol --- //---------------------------- -fan_config_t configFanLeft = { - .gpio_fan = GPIO_NUM_13, //FIXME simplify fan control! now only one pin used - might cause issues - .msRun = 5000, - .dutyThreshold = 35 -}; -fan_config_t configFanRight = { +fan_config_t configCooling = { .gpio_fan = GPIO_NUM_13, - .msRun = 5000, - .dutyThreshold = 35 + .dutyThreshold = 40, + .minOnMs = 1500, + .minOffMs = 3000, + .turnOffDelayMs = 5000, }; diff --git a/main/config.hpp b/main/config.hpp index 1857310..e81734e 100644 --- a/main/config.hpp +++ b/main/config.hpp @@ -14,7 +14,7 @@ //in IDLE mode: set loglevel for evaluatedJoystick to DEBUG //and repeatedly read joystick e.g. for manually calibrating / testing joystick -#define JOYSTICK_LOG_IN_IDLE +//#define JOYSTICK_LOG_IN_IDLE //create global controlledMotor instances for both motors @@ -39,7 +39,6 @@ extern automatedArmchair armchair; //create global httpJoystick object extern httpJoystick httpJoystickMain; -//configuration for fans -extern fan_config_t configFanLeft; -extern fan_config_t configFanRight; +//configuration for fans / cooling +extern fan_config_t configCooling; diff --git a/main/fan.cpp b/main/fan.cpp index d6be041..eeafb99 100644 --- a/main/fan.cpp +++ b/main/fan.cpp @@ -15,15 +15,16 @@ static const char * TAG = "fan-control"; //----------------------------- //-------- constructor -------- //----------------------------- -controlledFan::controlledFan(fan_config_t config_f, controlledMotor* motor_f ){ - //copy config - config = config_f; - //copy pointer to motor object - motor = motor_f; +controlledFan::controlledFan (fan_config_t config_f, controlledMotor* motor1_f, controlledMotor* motor2_f ){ + //copy config + config = config_f; + //copy pointer to motor objects + motor1 = motor1_f; + motor2 = motor2_f; - //initialize gpio pin - gpio_pad_select_gpio(config.gpio_fan); - gpio_set_direction(config.gpio_fan, GPIO_MODE_OUTPUT); + //initialize gpio pin + gpio_pad_select_gpio(config.gpio_fan); + gpio_set_direction(config.gpio_fan, GPIO_MODE_OUTPUT); } @@ -32,25 +33,50 @@ controlledFan::controlledFan(fan_config_t config_f, controlledMotor* motor_f ){ //--------- handle --------- //-------------------------- void controlledFan::handle(){ - //get current state of the motor - motorStatus = motor->getStatus(); + //get current state of the motor + motor1Status = motor1->getStatus(); + motor2Status = motor2->getStatus(); - //TODO Add statemachine for more specific control? Exponential average? - //update timestamp if threshold exceeded - if (motorStatus.duty > config.dutyThreshold){ - timestamp_lastThreshold = esp_log_timestamp(); - } + //update timestamp if any threshold exceeded + if (motor1Status.duty > config.dutyThreshold + || motor2Status.duty > config.dutyThreshold){ //TODO add temperature threshold + if (!needsCooling){ + timestamp_needsCoolingSet = esp_log_timestamp(); + needsCooling = true; + } + timestamp_lastThreshold = esp_log_timestamp(); + } else { + needsCooling = false; + } - //turn fan on if time since last exceeded threshold is less than msRun - if (esp_log_timestamp() - timestamp_lastThreshold < config.msRun) { - gpio_set_level(config.gpio_fan, 1); - ESP_LOGD(TAG, "fan is on (gpio: %d)", (int)config.gpio_fan); - } - //otherwise turn fan off - else { - gpio_set_level(config.gpio_fan, 0); - ESP_LOGD(TAG, "fan is off (gpio: %d)", (int)config.gpio_fan); - } + + //turn off condition + if (fanRunning + && !needsCooling //no more cooling required + && (motor1Status.duty == 0) && (motor2Status.duty == 0) //both motors are off + //-> keeps fans running even when lower than threshold already, however turnOffDelay already started TODO: start turn off delay after motor stop only? + && (esp_log_timestamp() - timestamp_lastThreshold) > config.turnOffDelayMs){ //turn off delay passed + fanRunning = false; + gpio_set_level(config.gpio_fan, 0); + timestamp_turnedOff = esp_log_timestamp(); + ESP_LOGI(TAG, "turned fan OFF gpio=%d, minOnMs=%d, WasOnMs=%d", (int)config.gpio_fan, config.minOnMs, esp_log_timestamp()-timestamp_turnedOn); + } + + //turn on condition + if (!fanRunning + && needsCooling + && ((esp_log_timestamp() - timestamp_turnedOff) > config.minOffMs) //fans off long enough + && ((esp_log_timestamp() - timestamp_needsCoolingSet) > config.minOnMs)){ //motors on long enough + fanRunning = true; + gpio_set_level(config.gpio_fan, 1); + timestamp_turnedOn = esp_log_timestamp(); + ESP_LOGI(TAG, "turned fan ON gpio=%d, minOffMs=%d, WasOffMs=%d", (int)config.gpio_fan, config.minOffMs, esp_log_timestamp()-timestamp_turnedOff); + } + + //TODO Add statemachine for more specific control? Exponential average? + //TODO idea: try other aproach? increment a variable with certain weights e.g. integrate over duty, then turn fans on and decrement the variable again + + ESP_LOGD(TAG, "fanState=%d, duty1=%f, duty2=%f, needsCooling=%d", fanRunning, motor1Status.duty, motor2Status.duty, needsCooling); } diff --git a/main/fan.hpp b/main/fan.hpp index 1300fad..a17c9b4 100644 --- a/main/fan.hpp +++ b/main/fan.hpp @@ -12,8 +12,10 @@ extern "C" //struct with all config parameters for a fan typedef struct fan_config_t { gpio_num_t gpio_fan; - uint32_t msRun; float dutyThreshold; + uint32_t minOnMs; + uint32_t minOffMs; + uint32_t turnOffDelayMs; } fan_config; @@ -24,7 +26,7 @@ typedef struct fan_config_t { class controlledFan { public: //--- constructor --- - controlledFan (fan_config_t config_f, controlledMotor* motor_f ); + controlledFan (fan_config_t config_f, controlledMotor* motor1_f, controlledMotor* motor2_f ); //--- functions --- void handle(); @@ -32,9 +34,16 @@ class controlledFan { private: //--- variables --- - uint32_t timestamp_lastThreshold; + bool fanRunning = false; + bool needsCooling = false; + uint32_t timestamp_needsCoolingSet; + uint32_t timestamp_lastThreshold = 0; + uint32_t timestamp_turnedOn = 0; + uint32_t timestamp_turnedOff = 0; fan_config_t config; - controlledMotor * motor; + controlledMotor * motor1; + controlledMotor * motor2; - motorCommand_t motorStatus; + motorCommand_t motor1Status; + motorCommand_t motor2Status; }; diff --git a/main/main.cpp b/main/main.cpp index a9c8e4d..f37675b 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -88,12 +88,10 @@ void task_button( void * pvParameters ){ void task_fans( void * pvParameters ){ ESP_LOGI(TAG, "Initializing fans and starting fan handle loop"); //create fan instances with config defined in config.cpp - controlledFan fanLeft(configFanLeft, &motorLeft); - controlledFan fanRight(configFanRight, &motorRight); - //repeatedly run fan handle functions in a slow loop + controlledFan fan(configCooling, &motorLeft, &motorRight); + //repeatedly run fan handle function in a slow loop while(1){ - fanLeft.handle(); - fanRight.handle(); + fan.handle(); vTaskDelay(1000 / portTICK_PERIOD_MS); } }