diff --git a/main/button.cpp b/main/button.cpp index b4a5042..d3c48f8 100644 --- a/main/button.cpp +++ b/main/button.cpp @@ -7,7 +7,6 @@ extern "C" #include "esp_log.h" } -#include "control.hpp" #include "button.hpp" @@ -20,9 +19,10 @@ static const char * TAG = "button"; //----------------------------- //-------- constructor -------- //----------------------------- -buttonCommands::buttonCommands(gpio_evaluatedSwitch * button_f, buzzer_t * buzzer_f ){ +buttonCommands::buttonCommands(gpio_evaluatedSwitch * button_f, controlledArmchair * control_f, buzzer_t * buzzer_f ){ //copy object pointers button = button_f; + control = control_f; buzzer = buzzer_f; //TODO declare / configure evaluatedSwitch here instead of config (unnecessary that button object is globally available - only used here)? } @@ -47,15 +47,13 @@ void buttonCommands::action (uint8_t count){ break; case 2: - ESP_LOGW(TAG, "cmd %d: switching to IDLE", count); - control_changeMode(controlMode_t::IDLE); - buzzer->beep(1,1000,1); + ESP_LOGW(TAG, "cmd %d: toggle IDLE", count); + control->toggleIdle(); //toggle between idle and previous/default mode break; - case 3: - ESP_LOGW(TAG, "cmd %d: switching to JOYSTICK", count); - control_changeMode(controlMode_t::JOYSTICK); - buzzer->beep(2,400,100); + case 6: + ESP_LOGW(TAG, "cmd %d: toggle between MASSAGE and JOYSTICK", count); + control->toggleModes(controlMode_t::MASSAGE, controlMode_t::JOYSTICK); //toggle between MASSAGE and JOYSTICK mode break; } } diff --git a/main/button.hpp b/main/button.hpp index a4f3d65..acaf520 100644 --- a/main/button.hpp +++ b/main/button.hpp @@ -2,6 +2,7 @@ #include "gpio_evaluateSwitch.hpp" #include "buzzer.hpp" +#include "control.hpp" @@ -14,6 +15,7 @@ class buttonCommands { //--- constructor --- buttonCommands ( gpio_evaluatedSwitch * button_f, + controlledArmchair * control_f, buzzer_t * buzzer_f ); @@ -28,6 +30,7 @@ class buttonCommands { //--- objects --- gpio_evaluatedSwitch* button; + controlledArmchair * control; buzzer_t* buzzer; //--- variables --- diff --git a/main/config.cpp b/main/config.cpp index 47494d8..371c701 100644 --- a/main/config.cpp +++ b/main/config.cpp @@ -71,3 +71,6 @@ gpio_evaluatedSwitch buttonJoystick(GPIO_NUM_33, true, false); //pullup true, no //create buzzer object on pin 12 with gap between queued events of 100ms buzzer_t buzzer(GPIO_NUM_12, 100); + +//create global control object +controlledArmchair control(&buzzer, &motorLeft, &motorRight); diff --git a/main/config.hpp b/main/config.hpp index da35463..46e9474 100644 --- a/main/config.hpp +++ b/main/config.hpp @@ -6,6 +6,7 @@ #include "gpio_evaluateSwitch.hpp" #include "buzzer.hpp" +#include "control.hpp" //create global controlledMotor instances for both motors @@ -20,3 +21,7 @@ extern gpio_evaluatedSwitch buttonJoystick; //create global buzzer object extern buzzer_t buzzer; + +//create global control object +extern controlledArmchair control; + diff --git a/main/control.cpp b/main/control.cpp index a72aa7e..8d6d0c5 100644 --- a/main/control.cpp +++ b/main/control.cpp @@ -5,30 +5,38 @@ extern "C" #include "esp_log.h" } -#include "motordrivers.hpp" -#include "motorctl.hpp" -#include "joystick.hpp" #include "config.hpp" #include "control.hpp" -//================================= -//===== variable declaration ====== -//================================= //tag for logging static const char * TAG = "control"; -//definition of mode enum -controlMode_t mode = controlMode_t::IDLE; const char* controlModeStr[6] = {"IDLE", "JOYSTICK", "MASSAGE", "MQTT", "BLUETOOTH", "AUTO"}; +//----------------------------- +//-------- constructor -------- +//----------------------------- +controlledArmchair::controlledArmchair ( + buzzer_t * buzzer_f, + controlledMotor* motorLeft_f, + controlledMotor* motorRight_f + ){ + + //copy object pointers + buzzer = buzzer_f; + motorLeft = motorLeft_f; + motorRight = motorRight_f; + //TODO declare / configure controlled motors here instead of config (unnecessary that button object is globally available - only used here)? +} -//================================== -//========== handle task =========== -//================================== -//task that repeatedly generates motor commands depending on the current mode -void task_control ( void * pvParameters ) { + +//---------------------------------- +//---------- Handle loop ----------- +//---------------------------------- +//function that repeatedly generates motor commands depending on the current mode +void controlledArmchair::startHandleLoop() { while (1){ vTaskDelay(20 / portTICK_PERIOD_MS); @@ -40,17 +48,23 @@ void task_control ( void * pvParameters ) { break; case controlMode_t::IDLE: - motorRight.setTarget(motorstate_t::IDLE, 0); - motorLeft.setTarget(motorstate_t::IDLE, 0); + motorRight->setTarget(motorstate_t::IDLE, 0); + motorLeft->setTarget(motorstate_t::IDLE, 0); break; case controlMode_t::JOYSTICK: - motorCommands_t commands = joystick_generateCommandsDriving(joystick); - motorRight.setTarget(commands.right.state, commands.right.duty); - motorLeft.setTarget(commands.left.state, commands.left.duty); + commands = joystick_generateCommandsDriving(joystick); + motorRight->setTarget(commands.right.state, commands.right.duty); + motorLeft->setTarget(commands.left.state, commands.left.duty); //TODO make motorctl.setTarget also accept motorcommand struct directly break; + case controlMode_t::MASSAGE: + motorRight->setTarget(motorstate_t::IDLE, 0); + motorLeft->setTarget(motorstate_t::IDLE, 0); + //TODO add actual command generation here + break; + //TODO: add other modes here } } @@ -58,11 +72,11 @@ void task_control ( void * pvParameters ) { -//=================================== -//=========== changeMode ============ -//=================================== +//----------------------------------- +//----------- changeMode ------------ +//----------------------------------- //function to change to a specified control mode -void control_changeMode(controlMode_t modeNew) { +void controlledArmchair::changeMode(controlMode_t modeNew) { ESP_LOGW(TAG, "changing mode from %s to %s", controlModeStr[(int)mode], controlModeStr[(int)modeNew]); mode = modeNew; //TODO: add mutex @@ -70,3 +84,41 @@ void control_changeMode(controlMode_t modeNew) { +//----------------------------------- +//----------- toggleIdle ------------ +//----------------------------------- +//function to toggle between IDLE and previous active mode +void controlledArmchair::toggleIdle() { + if (mode == controlMode_t::IDLE){ + mode = modePrevious; //restore previous mode, or default if not switched yet + buzzer->beep(2, 200, 100); + ESP_LOGW(TAG, "switched mode from IDLE to %s", controlModeStr[(int)mode]); + } else { + modePrevious = mode; //store current mode + mode = controlMode_t::IDLE; //set mode to IDLE + buzzer->beep(1, 1000, 0); + ESP_LOGW(TAG, "switched mode from IDLE to %s", controlModeStr[(int)mode]); + } +} + + + +//------------------------------------ +//----------- toggleModes ------------ +//------------------------------------ +//function to toggle between two modes, but prefer first argument if entirely different mode is currently active +void controlledArmchair::toggleModes(controlMode_t modePrimary, controlMode_t modeSecondary) { + + //switch to secondary mode when primary is already active + if (mode == modePrimary){ + ESP_LOGW(TAG, "toggleModes: switching from primaryMode %s to secondarMode %s", controlModeStr[(int)mode], controlModeStr[(int)modeSecondary]); + buzzer->beep(2,200,100); + mode = modeSecondary; //switch to secondary mode + } + //switch to primary mode when any other mode is active + else { + ESP_LOGW(TAG, "toggleModes: switching from %s to primary mode %s", controlModeStr[(int)mode], controlModeStr[(int)modePrimary]); + buzzer->beep(4,200,100); + mode = modePrimary; + } +} diff --git a/main/control.hpp b/main/control.hpp index 9c7478f..23802f5 100644 --- a/main/control.hpp +++ b/main/control.hpp @@ -1,15 +1,60 @@ #pragma once +#include "motordrivers.hpp" +#include "motorctl.hpp" +#include "buzzer.hpp" + //enum that decides how the motors get controlled enum class controlMode_t {IDLE, JOYSTICK, MASSAGE, MQTT, BLUETOOTH, AUTO}; //extern controlMode_t mode; - -//task that repeatedly generates motor commands depending on the current mode -void task_control(void * pvParameters); - -//function that changes to a specified control mode -void control_changeMode(controlMode_t modeNew); +extern const char* controlModeStr[6]; +//================================== +//========= control class ========== +//================================== +//controls the mode the armchair operates +//repeatedly generates the motor commands corresponding to current mode and sends those to motorcontrol +class controlledArmchair { + public: + //--- constructor --- + controlledArmchair ( + buzzer_t* buzzer_f, + controlledMotor* motorLeft_f, + controlledMotor* motorRight_f + ); + + //--- functions --- + //task that repeatedly generates motor commands depending on the current mode + void startHandleLoop(); + + //function that changes to a specified control mode + void changeMode(controlMode_t modeNew); + + //function that toggle between IDLE and previous active mode (or default if not switched to certain mode yet) + void toggleIdle(); + + //function that toggles between two modes, but prefers first argument if entirely different mode is currently active + void toggleModes(controlMode_t modePrimary, controlMode_t modeSecondary); + + private: + + //--- objects --- + buzzer_t* buzzer; + controlledMotor* motorLeft; + controlledMotor* motorRight; + + //---variables --- + //struct for motor commands returned by generate functions of each mode + motorCommands_t commands; + + //definition of mode enum + controlMode_t mode = controlMode_t::IDLE; + + //variable to store mode when toggling IDLE mode + controlMode_t modePrevious = controlMode_t::JOYSTICK; //default mode +}; + + diff --git a/main/main.cpp b/main/main.cpp index ee66d09..be966c9 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -53,13 +53,24 @@ void task_buzzer( void * pvParameters ){ +//======================================= +//============ control task ============= +//======================================= +void task_control( void * pvParameters ){ + ESP_LOGI(TAG, "Initializing controlledArmchair and starting handle loop"); + //start handle loop (control object declared in config.hpp) + control.startHandleLoop(); +} + + + //====================================== //============ button task ============= //====================================== void task_button( void * pvParameters ){ ESP_LOGI(TAG, "Initializing command-button and starting handle loop"); //create button instance - buttonCommands commandButton(&buttonJoystick, &buzzer); + buttonCommands commandButton(&buttonJoystick, &control, &buzzer); //start handle loop commandButton.startHandleLoop(); } @@ -106,7 +117,7 @@ extern "C" void app_main(void) { //------------------------------- //--- create task for control --- //------------------------------- - //task that generates motor commands depending on the current mode and sends those to motorctl task (task_control is defined in control.cpp) + //task that generates motor commands depending on the current mode and sends those to motorctl task xTaskCreate(&task_control, "task_control", 2048, NULL, 5, NULL); //------------------------------