Rework fan control: single pin, more delay, config
- remove second fan instance since both fans are controlled via one pin now - more config options so fans turn on less at short movements => less noise and less relay cycles
This commit is contained in:
parent
3f73344b93
commit
be40a8c2d3
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
76
main/fan.cpp
76
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);
|
||||
}
|
||||
|
||||
|
||||
|
19
main/fan.hpp
19
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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user