diff --git a/README.md b/README.md index ddfdd99..9b9d5ee 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| Supported Targets (IDK lol) | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ## OpenIris-ESPIDF -Firmware and tools for OpenIris on ESP32/ESP32‑S3 — Wi‑Fi, UVC streaming, and a handy Python setup CLI. - -Short, friendly, and practical. +Firmware and tools for OpenIris — Wi‑Fi, UVC streaming, and a handy Python setup CLI. --- @@ -20,7 +18,7 @@ Short, friendly, and practical. ## Prerequisites - ESP‑IDF installed and available in your terminal (`idf.py` works) -- Python 3.10+ with `pip` +- Python 3.10+ with `pip` (on Windows this is installed automatically when you set up the ESP‑IDF VS Code extension; see “First-time setup on Windows” below) - USB cable to your board - Optional: install Python dependencies for the tools diff --git a/components/LEDManager/LEDManager/LEDManager.cpp b/components/LEDManager/LEDManager/LEDManager.cpp index 8ba2460..159b750 100644 --- a/components/LEDManager/LEDManager/LEDManager.cpp +++ b/components/LEDManager/LEDManager/LEDManager.cpp @@ -152,24 +152,21 @@ void LEDManager::displayCurrentPattern() void LEDManager::updateState(const LEDStates_e newState) { - // we should change the displayed state - // only if we finished displaying the current one - which is handled by the task - // if the new state is not the same as the current one - // and if can actually display the state - - // if we've got an error state - that's it, we'll just keep repeating it indefinitely - if (ledStateMap[this->currentState].isError) + // Only update when new state differs and is known. + if (!ledStateMap.contains(newState)) return; if (newState == this->currentState) return; - if (ledStateMap.contains(newState)) - { - this->currentState = newState; - this->currentPatternIndex = 0; - this->finishedPattern = false; - } + // Allow recovery from error states: if both current and new are error, ignore. + // Otherwise permit transitioning out of error when a non-error state arrives. + if (ledStateMap[this->currentState].isError && ledStateMap[newState].isError) + return; + + this->currentState = newState; + this->currentPatternIndex = 0; + this->finishedPattern = false; } void LEDManager::toggleLED(const bool state) const @@ -203,10 +200,13 @@ void LEDManager::setExternalLEDDutyCycle(uint8_t dutyPercent) void HandleLEDDisplayTask(void *pvParameter) { auto *ledManager = static_cast(pvParameter); + TickType_t lastWakeTime = xTaskGetTickCount(); while (true) { ledManager->handleLED(); - vTaskDelay(ledManager->getTimeToDelayFor()); + const TickType_t delayTicks = pdMS_TO_TICKS(ledManager->getTimeToDelayFor()); + // Ensure at least 1 tick delay to yield CPU + vTaskDelayUntil(&lastWakeTime, delayTicks > 0 ? delayTicks : 1); } } diff --git a/components/StreamServer/StreamServer/StreamServer.cpp b/components/StreamServer/StreamServer/StreamServer.cpp index c40f5cc..5908452 100644 --- a/components/StreamServer/StreamServer/StreamServer.cpp +++ b/components/StreamServer/StreamServer/StreamServer.cpp @@ -20,7 +20,8 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) size_t _jpg_buf_len = 0; uint8_t *_jpg_buf = nullptr; - char *part_buf[256]; + // Buffer for multipart header; was mistakenly declared as array of pointers + char part_buf[256]; static int64_t last_frame = 0; if (!last_frame) last_frame = esp_timer_get_time(); @@ -55,7 +56,7 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) response = httpd_resp_send_chunk(req, STREAM_BOUNDARY, strlen(STREAM_BOUNDARY)); if (response == ESP_OK) { - size_t hlen = snprintf((char *)part_buf, 128, STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec); + size_t hlen = snprintf((char *)part_buf, sizeof(part_buf), STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec); response = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); } if (response == ESP_OK) diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 33b171d..69a4139 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -53,7 +53,7 @@ auto *restAPI = new RestAPI("http://0.0.0.0:81", commandManager); UVCStreamManager uvcStream; #endif -auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue, deviceConfig); +auto ledManager = std::make_shared(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue, deviceConfig); auto *serialManager = new SerialManager(commandManager, &timerHandle, deviceConfig); static void initNVSStorage() @@ -228,7 +228,7 @@ extern "C" void app_main(void) dependencyRegistry->registerService(DependencyType::project_config, deviceConfig); dependencyRegistry->registerService(DependencyType::camera_manager, cameraHandler); dependencyRegistry->registerService(DependencyType::wifi_manager, wifiManager); - dependencyRegistry->registerService(DependencyType::led_manager, std::shared_ptr(ledManager, [](LEDManager*){})); + dependencyRegistry->registerService(DependencyType::led_manager, ledManager); // uvc plan // cleanup the logs - done // prepare the camera to be initialized with UVC - done? @@ -294,7 +294,7 @@ extern "C" void app_main(void) HandleLEDDisplayTask, "HandleLEDDisplayTask", 1024 * 2, - ledManager, + ledManager.get(), 3, nullptr); diff --git a/sdkconfig b/sdkconfig index b9755fb..08e7daa 100644 --- a/sdkconfig +++ b/sdkconfig @@ -581,7 +581,7 @@ CONFIG_LED_BLINK_GPIO=8 CONFIG_LED_EXTERNAL_GPIO=9 CONFIG_LED_EXTERNAL_CONTROL=y CONFIG_LED_EXTERNAL_PWM_FREQ=20000 -CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=50 +CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 # end of OpenIris: LED Configuration #