diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 6909b71..1fe2f67 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "main.cpp" "motordrivers.cpp" "motorctl.cpp" "config.cpp" "joystick.cpp" "buzzer.cpp" "control.cpp" "button.cpp" +idf_component_register(SRCS "main.cpp" "motordrivers.cpp" "motorctl.cpp" "config.cpp" "joystick.cpp" "buzzer.cpp" "control.cpp" "button.cpp" "fan.cpp" INCLUDE_DIRS ".") diff --git a/main/config.cpp b/main/config.cpp index 371c701..2ab2b43 100644 --- a/main/config.cpp +++ b/main/config.cpp @@ -74,3 +74,17 @@ buzzer_t buzzer(GPIO_NUM_12, 100); //create global control object controlledArmchair control(&buzzer, &motorLeft, &motorRight); + + +//configure fan contol +fan_config_t configFanLeft = { + .gpio_fan = GPIO_NUM_2, + .msRun = 5000, + .dutyThreshold = 35 +}; +fan_config_t configFanRight = { + .gpio_fan = GPIO_NUM_15, + .msRun = 5000, + .dutyThreshold = 35 +}; + diff --git a/main/config.hpp b/main/config.hpp index 46e9474..2dce508 100644 --- a/main/config.hpp +++ b/main/config.hpp @@ -7,6 +7,7 @@ #include "gpio_evaluateSwitch.hpp" #include "buzzer.hpp" #include "control.hpp" +#include "fan.hpp" //create global controlledMotor instances for both motors @@ -25,3 +26,7 @@ extern buzzer_t buzzer; //create global control object extern controlledArmchair control; +//configuration for fans +extern fan_config_t configFanLeft; +extern fan_config_t configFanRight; + diff --git a/main/fan.cpp b/main/fan.cpp new file mode 100644 index 0000000..d6be041 --- /dev/null +++ b/main/fan.cpp @@ -0,0 +1,57 @@ +extern "C" +{ +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +} + +#include "fan.hpp" + + +//tag for logging +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; + + //initialize gpio pin + gpio_pad_select_gpio(config.gpio_fan); + gpio_set_direction(config.gpio_fan, GPIO_MODE_OUTPUT); +} + + + +//-------------------------- +//--------- handle --------- +//-------------------------- +void controlledFan::handle(){ + //get current state of the motor + motorStatus = motor->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(); + } + + //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); + } +} + + + diff --git a/main/fan.hpp b/main/fan.hpp new file mode 100644 index 0000000..1300fad --- /dev/null +++ b/main/fan.hpp @@ -0,0 +1,40 @@ +#pragma once + +extern "C" +{ +#include "driver/gpio.h" +} + +#include "motorctl.hpp" + + + +//struct with all config parameters for a fan +typedef struct fan_config_t { + gpio_num_t gpio_fan; + uint32_t msRun; + float dutyThreshold; +} fan_config; + + + +//================================== +//====== controlledFan class ======= +//================================== +class controlledFan { + public: + //--- constructor --- + controlledFan (fan_config_t config_f, controlledMotor* motor_f ); + + //--- functions --- + void handle(); + + + private: + //--- variables --- + uint32_t timestamp_lastThreshold; + fan_config_t config; + controlledMotor * motor; + + motorCommand_t motorStatus; +}; diff --git a/main/main.cpp b/main/main.cpp index be966c9..42383ab 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -77,6 +77,24 @@ void task_button( void * pvParameters ){ +//======================================= +//============== fan task =============== +//======================================= +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 + while(1){ + fanLeft.handle(); + fanRight.handle(); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +} + + + //================================= //=========== app_main ============ //================================= @@ -100,6 +118,8 @@ extern "C" void app_main(void) { //esp_log_level_set("evaluatedJoystick", ESP_LOG_DEBUG); //esp_log_level_set("joystickCommands", ESP_LOG_DEBUG); esp_log_level_set("button", ESP_LOG_INFO); + esp_log_level_set("control", ESP_LOG_INFO); + esp_log_level_set("fan-control", ESP_LOG_DEBUG); @@ -124,7 +144,13 @@ extern "C" void app_main(void) { //--- create task for button --- //------------------------------ //task that evaluates and processes the button input and runs the configured commands - xTaskCreate(&task_button, "task_buzzer", 2048, NULL, 5, NULL); + xTaskCreate(&task_button, "task_button", 2048, NULL, 5, NULL); + + //----------------------------------- + //--- create task for fan control --- + //----------------------------------- + //task that evaluates and processes the button input and runs the configured commands + xTaskCreate(&task_fans, "task_fans", 2048, NULL, 5, NULL); //beep at startup diff --git a/main/motorctl.cpp b/main/motorctl.cpp index 7ca779f..fd8cfc8 100644 --- a/main/motorctl.cpp +++ b/main/motorctl.cpp @@ -95,3 +95,18 @@ void controlledMotor::setTarget(motorstate_t state_f, float duty_f){ } + + +//=============================== +//========== getStatus ========== +//=============================== +//function which returns the current status of the motor in a motorCommand_t struct +motorCommand_t controlledMotor::getStatus(){ + motorCommand_t status = { + .state = state, + .duty = dutyNow + }; + //TODO: mutex + return status; +}; + diff --git a/main/motorctl.hpp b/main/motorctl.hpp index ec5e159..86708fe 100644 --- a/main/motorctl.hpp +++ b/main/motorctl.hpp @@ -42,6 +42,7 @@ class controlledMotor { controlledMotor(single100a_config_t config_driver, motorctl_config_t config_control); //constructor with structs for configuring motordriver and parameters for control TODO: add configuration for currentsensor void handle(); //controls motor duty with fade and current limiting feature (has to be run frequently by another task) void setTarget(motorstate_t state_f, float duty_f = 0); //adds target command to queue for handle function + motorCommand_t getStatus(); //get current status of the motor (returns struct with state and duty) private: