Update README and improve LEDManager and StreamServer functionality

- Enhanced LEDManager state update logic to allow recovery from error states
- Fixed buffer declaration in StreamServer for multipart headers
- Updated LEDManager instantiation to use shared_ptr for better memory management
This commit is contained in:
PhosphorosVR
2025-08-23 15:28:55 +02:00
parent 05e122ffdd
commit 4778ae6c52
5 changed files with 24 additions and 25 deletions

View File

@@ -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/ESP32S3 — WiFi, UVC streaming, and a handy Python setup CLI.
Short, friendly, and practical.
Firmware and tools for OpenIris — WiFi, UVC streaming, and a handy Python setup CLI.
---
@@ -20,7 +18,7 @@ Short, friendly, and practical.
## Prerequisites
- ESPIDF 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 ESPIDF VS Code extension; see “First-time setup on Windows” below)
- USB cable to your board
- Optional: install Python dependencies for the tools

View File

@@ -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<LEDManager *>(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);
}
}

View File

@@ -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)

View File

@@ -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<LEDManager>(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<ProjectConfig>(DependencyType::project_config, deviceConfig);
dependencyRegistry->registerService<CameraManager>(DependencyType::camera_manager, cameraHandler);
dependencyRegistry->registerService<WiFiManager>(DependencyType::wifi_manager, wifiManager);
dependencyRegistry->registerService<LEDManager>(DependencyType::led_manager, std::shared_ptr<LEDManager>(ledManager, [](LEDManager*){}));
dependencyRegistry->registerService<LEDManager>(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);

View File

@@ -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
#