diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index 5c0b715..96337ca 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -2,50 +2,44 @@ const char *LED_MANAGER_TAG = "[LED_MANAGER]"; -LEDManager::ledStateMap_t LEDManager::ledStateMap = { - {LEDStates_e::_LedStateNone, {{0, 500}}}, - {LEDStates_e::_Improv_Error, - {{1, 1000}, {0, 500}, {0, 1000}, {0, 500}, {1, 1000}}}, - {LEDStates_e::_Improv_Start, - {{1, 500}, {0, 300}, {0, 300}, {0, 300}, {1, 500}}}, - {LEDStates_e::_Improv_Stop, - {{1, 300}, {0, 500}, {0, 500}, {0, 500}, {1, 300}}}, - {LEDStates_e::_Improv_Processing, - {{1, 200}, {0, 100}, {0, 500}, {0, 100}, {1, 200}}}, +// todo rethink the patterns +ledStateMap_t LEDManager::ledStateMap = { + {LEDStates_e::_LedStateNone, {{LED_OFF, 500}}}, + {LEDStates_e::_LedStateStreaming, {{LED_ON, 500}}}, + {LEDStates_e::_LedStateStoppedStreaming, {{LED_OFF, 500}}}, {LEDStates_e::_WebServerState_Error, - {{1, 200}, {0, 100}, {0, 500}, {0, 100}, {1, 200}}}, + {{LED_ON, 200}, {LED_OFF, 100}, {LED_ON, 200}, {LED_OFF, 100}, {LED_ON, 200}}}, {LEDStates_e::_WiFiState_Error, - {{1, 200}, {0, 100}, {0, 500}, {0, 100}, {1, 200}}}, + {{LED_ON, 200}, {LED_OFF, 100}, {LED_ON, 500}, {LED_OFF, 100}, {LED_ON, 200}}}, {LEDStates_e::_MDNSState_Error, - {{1, 200}, + {{LED_ON, 200}, {0, 100}, - {1, 200}, + {LED_ON, 200}, {0, 100}, - {0, 500}, + {LED_ON, 500}, {0, 100}, - {1, 200}, + {LED_ON, 200}, {0, 100}, - {1, 200}}}, + {LED_ON, 200}}}, + + // lmao no, rethink this {LEDStates_e::_Camera_Error, - {{1, 5000}}}, // this also works as a more general error - something went - // critically wrong? We go here + {{LED_ON, 5000}}}, // this also works as a more general error - something went + // critically wrong? We go here {LEDStates_e::_WiFiState_Connecting, {{1, 100}, {0, 100}}}, {LEDStates_e::_WiFiState_Connected, - {{1, 100}, + {{LED_ON, 100}, {0, 100}, - {1, 100}, + {LED_ON, 100}, {0, 100}, - {1, 100}, + {LED_ON, 100}, {0, 100}, - {1, 100}, + {LED_ON, 100}, {0, 100}, - {1, 100}, + {LED_ON, 100}, {0, 100}}}}; -std::vector LEDManager::keepAliveStates = { - LEDStates_e::_WebServerState_Error, LEDStates_e::_Camera_Error}; - -LEDManager::LEDManager(gpio_num_t pin, gpio_num_t illumninator_led_pin) : blink_led_pin(pin), illumninator_led_pin(illumninator_led_pin), state(false) {} +LEDManager::LEDManager(gpio_num_t pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue) : blink_led_pin(pin), illumninator_led_pin(illumninator_led_pin), ledStateQueue(ledStateQueue) {} void LEDManager::setup() { @@ -53,13 +47,7 @@ void LEDManager::setup() gpio_reset_pin(blink_led_pin); /* Set the GPIO as a push/pull output */ gpio_set_direction(blink_led_pin, GPIO_MODE_OUTPUT); - // the defualt state is _LedStateNone so we're fine - this->currentState = ledStateManager.getCurrentState(); - this->currentPatternIndex = 0; - BlinkPatterns_t pattern = - this->ledStateMap[this->currentState][this->currentPatternIndex]; - this->toggleLED(pattern.state); - this->nextStateChangeMillis = pattern.delayTime; + this->toggleLED(LED_OFF); #ifdef CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL ESP_LOGD(LED_MANAGER_TAG, "Setting up illuminator led."); @@ -90,59 +78,55 @@ void LEDManager::setup() ESP_LOGD(LED_MANAGER_TAG, "Done."); } -/** - * @brief Display the current state of the LED manager as a pattern of blinking - * LED - * @details This function must be called in the main loop - */ +// todo - rethink how it should work with a queue and vtaskdelay void LEDManager::handleLED() { - if (Helpers::getTimeInMillis() <= this->nextStateChangeMillis) - { - return; - } + // if (Helpers::getTimeInMillis() <= this->nextStateChangeMillis) + // { + // return; + // } - // !TODO what if we want a looping state? Or a state that needs to stay - // bright? Am overthinking this, aren't I? + // // !TODO what if we want a looping state? Or a state that needs to stay + // // bright? Am overthinking this, aren't I? I was not. - // we've reached the timeout on that state, check if we can grab next one and - // start displaying it, or if we need to keep displaying the current one - if (this->currentPatternIndex > - this->ledStateMap[this->currentState].size() - 1) - { - auto nextState = ledStateManager.getCurrentState(); - // we want to keep displaying the same state only if its an keepAlive one, - // but we should change if the incoming one is also an errours state, maybe - // more serious one this time <- this may be a bad idea - if ((std::find(this->keepAliveStates.begin(), this->keepAliveStates.end(), - this->currentState) != this->keepAliveStates.end() || - std::find(this->keepAliveStates.begin(), this->keepAliveStates.end(), - nextState) != this->keepAliveStates.end()) || - (this->currentState != nextState && - this->ledStateMap.find(nextState) != this->ledStateMap.end())) - { - ESP_LOGD(LED_MANAGER_TAG, "Updating the state and reseting"); - this->toggleLED(false); - this->currentState = nextState; - this->currentPatternIndex = 0; - BlinkPatterns_t pattern = - this->ledStateMap[this->currentState][this->currentPatternIndex]; - this->nextStateChangeMillis = Helpers::getTimeInMillis() + pattern.delayTime; - return; - } - // it wasn't a keepAlive state, nor did we have another one ready, - // we're done for now - this->toggleLED(false); - return; - } - // we can safely advance it and display the next stage - BlinkPatterns_t pattern = - this->ledStateMap[this->currentState][this->currentPatternIndex]; - this->toggleLED(pattern.state); - this->nextStateChangeMillis = Helpers::getTimeInMillis() + pattern.delayTime; - ESP_LOGD(LED_MANAGER_TAG, "before updating stage %d", this->currentPatternIndex); - this->currentPatternIndex++; - ESP_LOGD(LED_MANAGER_TAG, "updated stage %d", this->currentPatternIndex); + // // we've reached the timeout on that state, check if we can grab next one and + // // start displaying it, or if we need to keep displaying the current one + // if (this->currentPatternIndex > + // this->ledStateMap[this->currentState].size() - 1) + // { + // auto nextState = ledStateManager.getCurrentState(); + // // we want to keep displaying the same state only if its an keepAlive one, + // // but we should change if the incoming one is also an errours state, maybe + // // more serious one this time <- this may be a bad idea + // if ((std::find(this->keepAliveStates.begin(), this->keepAliveStates.end(), + // this->currentState) != this->keepAliveStates.end() || + // std::find(this->keepAliveStates.begin(), this->keepAliveStates.end(), + // nextState) != this->keepAliveStates.end()) || + // (this->currentState != nextState && + // this->ledStateMap.find(nextState) != this->ledStateMap.end())) + // { + // ESP_LOGD(LED_MANAGER_TAG, "Updating the state and reseting"); + // this->toggleLED(false); + // this->currentState = nextState; + // this->currentPatternIndex = 0; + // BlinkPatterns_t pattern = + // this->ledStateMap[this->currentState][this->currentPatternIndex]; + // this->nextStateChangeMillis = Helpers::getTimeInMillis() + pattern.delayTime; + // return; + // } + // // it wasn't a keepAlive state, nor did we have another one ready, + // // we're done for now + // this->toggleLED(false); + // return; + // } + // // we can safely advance it and display the next stage + // BlinkPatterns_t pattern = + // this->ledStateMap[this->currentState][this->currentPatternIndex]; + // this->toggleLED(pattern.state); + // this->nextStateChangeMillis = Helpers::getTimeInMillis() + pattern.delayTime; + // ESP_LOGD(LED_MANAGER_TAG, "before updating stage %d", this->currentPatternIndex); + // this->currentPatternIndex++; + // ESP_LOGD(LED_MANAGER_TAG, "updated stage %d", this->currentPatternIndex); } /** @@ -154,3 +138,15 @@ void LEDManager::toggleLED(bool state) const { gpio_set_level(blink_led_pin, state); } + +void HandleLEDDisplayTask(void *pvParameter) +{ + LEDManager *ledManager = (LEDManager *)pvParameter; + + while (1) + { + printf("Hello from a task \n"); + printf("The led manager is %d \n", bool(ledManager)); + vTaskDelay(100); + } +} \ No newline at end of file diff --git a/components/LEDManager/LEDManager/LEDManager.hpp b/components/LEDManager/LEDManager/LEDManager.hpp index b6f7bec..c533665 100644 --- a/components/LEDManager/LEDManager/LEDManager.hpp +++ b/components/LEDManager/LEDManager/LEDManager.hpp @@ -3,6 +3,8 @@ #define _LEDMANAGER_HPP_ #include "driver/gpio.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" #ifdef CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL #include "driver/ledc.h" @@ -16,10 +18,22 @@ #include #include +// it kinda looks like different boards have these states swapped +#define LED_OFF 1 +#define LED_ON 0 + +struct BlinkPatterns_t +{ + int state; + int delayTime; +}; + +typedef std::unordered_map> ledStateMap_t; + class LEDManager { public: - LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin); + LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue); void setup(); void handleLED(); @@ -27,23 +41,13 @@ public: private: gpio_num_t blink_led_pin; gpio_num_t illumninator_led_pin; + QueueHandle_t ledStateQueue; - unsigned long nextStateChangeMillis = 0; - bool state = false; - - struct BlinkPatterns_t - { - int state; - int delayTime; - }; - - typedef std::unordered_map> ledStateMap_t; static ledStateMap_t ledStateMap; - static std::vector keepAliveStates; LEDStates_e currentState; - unsigned int currentPatternIndex = 0; void toggleLED(bool state) const; }; +void HandleLEDDisplayTask(void *pvParameter); #endif \ No newline at end of file diff --git a/components/RestAPI/RestAPI/RestAPI.cpp b/components/RestAPI/RestAPI/RestAPI.cpp index 7e12c8c..d6d7fcb 100644 --- a/components/RestAPI/RestAPI/RestAPI.cpp +++ b/components/RestAPI/RestAPI/RestAPI.cpp @@ -71,6 +71,16 @@ void RestAPI::poll() mg_mgr_poll(&mgr, 100); } +void HandleRestAPIPollTask(void *pvParameter) +{ + RestAPI *rest_api_handler = static_cast(pvParameter); + while (1) + { + rest_api_handler->poll(); + vTaskDelay(1000); + } +} + // COMMANDS // updates void RestAPI::handle_update_wifi(RequestContext *context) diff --git a/components/RestAPI/RestAPI/RestAPI.hpp b/components/RestAPI/RestAPI/RestAPI.hpp index 1945648..bb7659c 100644 --- a/components/RestAPI/RestAPI/RestAPI.hpp +++ b/components/RestAPI/RestAPI/RestAPI.hpp @@ -63,4 +63,6 @@ namespace RestAPIHelpers void event_handler(struct mg_connection *connection, int event, void *event_data); }; +void HandleRestAPIPollTask(void *pvParameter); + #endif \ No newline at end of file diff --git a/components/StateManager/StateManager/StateManager.cpp b/components/StateManager/StateManager/StateManager.cpp index bbe18c7..634e94b 100644 --- a/components/StateManager/StateManager/StateManager.cpp +++ b/components/StateManager/StateManager/StateManager.cpp @@ -1,7 +1,6 @@ #include "StateManager.hpp" StateManager wifiStateManager; -StateManager webServerStateManager; StateManager mdnsStateManager; StateManager cameraStateManager; StateManager ledStateManager; diff --git a/components/StateManager/StateManager/StateManager.hpp b/components/StateManager/StateManager/StateManager.hpp index 292bc6d..1729279 100644 --- a/components/StateManager/StateManager/StateManager.hpp +++ b/components/StateManager/StateManager/StateManager.hpp @@ -10,10 +10,8 @@ struct DeviceStates enum LEDStates_e { _LedStateNone, - _Improv_Start, - _Improv_Stop, - _Improv_Processing, - _Improv_Error, + _LedStateStreaming, + _LedStateStoppedStreaming, _WebServerState_Error, _WiFiState_Error, _MDNSState_Error, @@ -46,15 +44,6 @@ struct DeviceStates WiFiState_Error }; - enum WebServerState_e - { - WebServerState_Stopped, - WebServerState_Starting, - WebServerState_Started, - WebServerState_Stopping, - WebServerState_Error - }; - enum MDNSState_e { MDNSState_Stopped, @@ -109,7 +98,6 @@ private: }; typedef DeviceStates::WiFiState_e WiFiState_e; -typedef DeviceStates::WebServerState_e WebServerState_e; typedef DeviceStates::MDNSState_e MDNSState_e; typedef DeviceStates::CameraState_e CameraState_e; typedef DeviceStates::LEDStates_e LEDStates_e; @@ -117,7 +105,6 @@ typedef DeviceStates::StreamState_e StreamState_e; typedef DeviceStates::ConfigState_e ConfigState_e; extern StateManager wifiStateManager; -extern StateManager webServerStateManager; extern StateManager mdnsStateManager; extern StateManager cameraStateManager; extern StateManager ledStateManager; diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 25ca613..e2d5317 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -2,6 +2,7 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/queue.h" #include "driver/gpio.h" #include "esp_log.h" #include "sdkconfig.h" @@ -31,6 +32,8 @@ static const char *TAG = "[MAIN]"; +QueueHandle_t ledStateQueue = xQueueCreate(10, sizeof(DeviceStates::LEDStates_e)); + std::shared_ptr dependencyRegistry = std::make_unique(); std::shared_ptr commandManager = std::make_shared(dependencyRegistry); @@ -44,13 +47,13 @@ MDNSManager mdnsManager(deviceConfig); std::shared_ptr cameraHandler = std::make_shared(deviceConfig); StreamServer streamServer(80); -RestAPI restAPI("http://0.0.0.0:81", commandManager); +RestAPI *restAPI = new RestAPI("http://0.0.0.0:81", commandManager); #ifdef CONFIG_WIRED_MODE UVCStreamManager uvcStream; #endif -LEDManager ledManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO); +LEDManager *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue); static void initNVSStorage() { @@ -73,7 +76,6 @@ extern "C" void app_main(void) { dependencyRegistry->registerService(DependencyType::project_config, deviceConfig); dependencyRegistry->registerService(DependencyType::camera_manager, cameraHandler); - // uvc plan // cleanup the logs - done // prepare the camera to be initialized with UVC - done? @@ -105,6 +107,11 @@ extern "C" void app_main(void) // here I can decouple the loading, initializing and saving logic from the config class and move // that into the separate modules, and have the config class only act as a container + // rethink led manager - we need to move the state change sending into a queue and rethink the state lighting logic + // also, the entire led manager needs to be moved to a task + // with that, I couuld use vtaskdelayuntil to advance and display states + // and with that, I should rethink how state management works + // port serial manager // implement OTA stuff, but prepare it for future use // add endpoint to check firmware version @@ -118,23 +125,36 @@ extern "C" void app_main(void) Logo::printASCII(); initNVSStorage(); - esp_log_set_vprintf(&test_log); - ledManager.setup(); + // esp_log_set_vprintf(&test_log); + ledManager->setup(); + + xTaskCreate( + HandleLEDDisplayTask, + "HandleLEDDisplayTask", + 1024 * 2, + ledManager, + 3, + NULL // // it's fine for us not get a handle back, we don't need it + ); + deviceConfig->load(); wifiManager.Begin(); mdnsManager.start(); - restAPI.begin(); + restAPI->begin(); cameraHandler->setupCamera(); // make sure the server runs on a separate core streamServer.startStreamServer(); + xTaskCreate( + HandleRestAPIPollTask, + "HandleRestAPIPollTask", + 1024 * 2, + restAPI, + 1, // it's the rest API, we only serve commands over it so we don't really need a higher priority + NULL // // it's fine for us not get a handle back, we don't need iti + ); + #ifdef CONFIG_WIRED_MODE uvcStream.setup(); #endif - while (1) - { - ledManager.handleLED(); - restAPI.poll(); - vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS); - } }