Add PoC PWN duty cycle adjustment command for FaceFocus

This commit is contained in:
Lorow
2025-08-19 00:03:31 +02:00
parent 9a1f55d012
commit 21e8dbe264
13 changed files with 227 additions and 99 deletions

View File

@@ -23,53 +23,76 @@ std::unordered_map<std::string, CommandType> commandTypeMap = {
{"connect_wifi", CommandType::CONNECT_WIFI},
{"switch_mode", CommandType::SWITCH_MODE},
{"get_device_mode", CommandType::GET_DEVICE_MODE},
{"set_led_duty_cycle", CommandType::SET_LED_DUTY_CYCLE},
};
std::function<CommandResult()> CommandManager::createCommand(const CommandType type, std::string_view json) const {
std::function<CommandResult()> CommandManager::createCommand(const CommandType type, std::string_view json) const
{
switch (type)
{
case CommandType::PING:
return { PingCommand };
return {PingCommand};
case CommandType::PAUSE:
return [json] { return PauseCommand(json); };
return [json]
{ return PauseCommand(json); };
case CommandType::SET_STREAMING_MODE:
return [this, json] {return setDeviceModeCommand(this->registry, json); };
return [this, json]
{ return setDeviceModeCommand(this->registry, json); };
case CommandType::UPDATE_OTA_CREDENTIALS:
return [this, json] { return updateOTACredentialsCommand(this->registry, json); };
return [this, json]
{ return updateOTACredentialsCommand(this->registry, json); };
case CommandType::SET_WIFI:
return [this, json] { return setWiFiCommand(this->registry, json); };
return [this, json]
{ return setWiFiCommand(this->registry, json); };
case CommandType::UPDATE_WIFI:
return [this, json] { return updateWiFiCommand(this->registry, json); };
return [this, json]
{ return updateWiFiCommand(this->registry, json); };
case CommandType::UPDATE_AP_WIFI:
return [this, json] { return updateAPWiFiCommand(this->registry, json); };
return [this, json]
{ return updateAPWiFiCommand(this->registry, json); };
case CommandType::DELETE_NETWORK:
return [this, json] { return deleteWiFiCommand(this->registry, json); };
return [this, json]
{ return deleteWiFiCommand(this->registry, json); };
case CommandType::SET_MDNS:
return [this, json] { return setMDNSCommand(this->registry, json); };
return [this, json]
{ return setMDNSCommand(this->registry, json); };
case CommandType::UPDATE_CAMERA:
return [this, json] { return updateCameraCommand(this->registry, json); };
return [this, json]
{ return updateCameraCommand(this->registry, json); };
case CommandType::RESTART_CAMERA:
return [this, json] { return restartCameraCommand(this->registry, json); };
return [this, json]
{ return restartCameraCommand(this->registry, json); };
case CommandType::GET_CONFIG:
return [this] { return getConfigCommand(this->registry); };
return [this]
{ return getConfigCommand(this->registry); };
case CommandType::SAVE_CONFIG:
return [this] { return saveConfigCommand(this->registry); };
return [this]
{ return saveConfigCommand(this->registry); };
case CommandType::RESET_CONFIG:
return [this, json] { return resetConfigCommand(this->registry, json); };
return [this, json]
{ return resetConfigCommand(this->registry, json); };
case CommandType::RESTART_DEVICE:
return restartDeviceCommand;
case CommandType::SCAN_NETWORKS:
return [this] { return scanNetworksCommand(this->registry); };
return [this]
{ return scanNetworksCommand(this->registry); };
case CommandType::START_STREAMING:
return startStreamingCommand;
case CommandType::GET_WIFI_STATUS:
return [this] { return getWiFiStatusCommand(this->registry); };
return [this]
{ return getWiFiStatusCommand(this->registry); };
case CommandType::CONNECT_WIFI:
return [this] { return connectWiFiCommand(this->registry); };
return [this]
{ return connectWiFiCommand(this->registry); };
case CommandType::SWITCH_MODE:
return [this, json] { return switchModeCommand(this->registry, json); };
return [this, json]
{ return switchModeCommand(this->registry, json); };
case CommandType::GET_DEVICE_MODE:
return [this] { return getDeviceModeCommand(this->registry); };
return [this]
{ return getDeviceModeCommand(this->registry); };
case CommandType::SET_LED_DUTY_CYCLE:
return [this, json]
{ return updateLEDDutyCycleCommand(this->registry, json); };
default:
return nullptr;
}

View File

@@ -44,6 +44,7 @@ enum class CommandType
CONNECT_WIFI,
SWITCH_MODE,
GET_DEVICE_MODE,
SET_LED_DUTY_CYCLE,
};
class CommandManager

View File

@@ -25,6 +25,8 @@ CommandResult setDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry,
const auto projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
projectConfig->setDeviceMode(static_cast<StreamingMode>(mode));
cJSON_Delete(parsedJson);
return CommandResult::getSuccessResult("Device mode set");
}
@@ -64,10 +66,41 @@ CommandResult updateOTACredentialsCommand(std::shared_ptr<DependencyRegistry> re
}
}
projectConfig->setDeviceConfig(OTALogin, OTAPassword, OTAPort);
cJSON_Delete(parsedJson);
projectConfig->setOTAConfig(OTALogin, OTAPassword, OTAPort);
return CommandResult::getSuccessResult("OTA Config set");
}
CommandResult updateLEDDutyCycleCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
const auto parsedJson = cJSON_Parse(jsonPayload.data());
if (parsedJson == nullptr)
{
return CommandResult::getErrorResult("Invalid payload");
}
const auto dutyCycleObject = cJSON_GetObjectItem(parsedJson, "dutyCycle");
if (dutyCycleObject == nullptr)
{
return CommandResult::getErrorResult("Invalid payload - missing dutyCycle");
}
const auto dutyCycle = dutyCycleObject->valueint;
if (dutyCycle < 0 || dutyCycle > 100)
{
return CommandResult::getErrorResult("Invalid payload - unsupported dutyCycle");
}
const auto projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
projectConfig->setLEDDUtyCycleConfig(dutyCycle);
cJSON_Delete(parsedJson);
return CommandResult::getSuccessResult("LED duty cycle set");
}
CommandResult restartDeviceCommand()
{
OpenIrisTasks::ScheduleRestart(2000);

View File

@@ -13,6 +13,8 @@ CommandResult setDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry,
CommandResult updateOTACredentialsCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);
CommandResult updateLEDDutyCycleCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);
CommandResult restartDeviceCommand();
CommandResult startStreamingCommand();

View File

@@ -1,4 +1,4 @@
idf_component_register(SRCS "LEDManager/LEDManager.cpp"
INCLUDE_DIRS "LEDManager"
REQUIRES StateManager driver esp_driver_ledc Helpers
REQUIRES StateManager driver esp_driver_ledc Helpers ProjectConfig
)

View File

@@ -48,10 +48,7 @@ ledStateMap_t LEDManager::ledStateMap = {
{
false,
false,
{
{LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200},
{LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}
},
{{LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}, {LED_ON, 200}, {LED_OFF, 200}},
},
},
{
@@ -65,32 +62,38 @@ ledStateMap_t LEDManager::ledStateMap = {
};
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),
currentState(LEDStates_e::LedStateNone) {
QueueHandle_t ledStateQueue, std::shared_ptr<ProjectConfig> deviceConfig) : blink_led_pin(pin),
illumninator_led_pin(illumninator_led_pin),
ledStateQueue(ledStateQueue),
currentState(LEDStates_e::LedStateNone),
deviceConfig(deviceConfig)
{
}
void LEDManager::setup() {
ESP_LOGD(LED_MANAGER_TAG, "Setting up status led.");
void LEDManager::setup()
{
ESP_LOGI(LED_MANAGER_TAG, "Setting up status led.");
gpio_reset_pin(blink_led_pin);
/* Set the GPIO as a push/pull output */
gpio_set_direction(blink_led_pin, GPIO_MODE_OUTPUT);
this->toggleLED(LED_OFF);
#ifdef CONFIG_LED_EXTERNAL_CONTROL
ESP_LOGD(LED_MANAGER_TAG, "Setting up illuminator led.");
ESP_LOGI(LED_MANAGER_TAG, "Setting up illuminator led.");
const int freq = CONFIG_LED_EXTERNAL_PWM_FREQ;
const auto resolution = LEDC_TIMER_8_BIT;
const int dutyCycle = (CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE * 255) / 100;
const auto deviceConfig = this->deviceConfig->getDeviceConfig();
const uint32_t dutyCycle = (deviceConfig.led_external_pwm_duty_cycle * 255) / 100;
ESP_LOGI(LED_MANAGER_TAG, "Setting dutyCycle to: %lu ", dutyCycle);
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = resolution,
.timer_num = LEDC_TIMER_0,
.freq_hz = freq,
.clk_cfg = LEDC_AUTO_CLK
};
.clk_cfg = LEDC_AUTO_CLK};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
@@ -101,8 +104,7 @@ void LEDManager::setup() {
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = LEDC_TIMER_0,
.duty = dutyCycle,
.hpoint = 0
};
.hpoint = 0};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
#endif
@@ -110,37 +112,46 @@ void LEDManager::setup() {
ESP_LOGD(LED_MANAGER_TAG, "Done.");
}
void LEDManager::handleLED() {
if (!this->finishedPattern) {
void LEDManager::handleLED()
{
if (!this->finishedPattern)
{
displayCurrentPattern();
return;
}
if (xQueueReceive(this->ledStateQueue, &buffer, 10)) {
if (xQueueReceive(this->ledStateQueue, &buffer, 10))
{
this->updateState(buffer);
} else {
}
else
{
// we've finished displaying the pattern, so let's check if it's repeatable and if so - reset it
if (ledStateMap[this->currentState].isRepeatable || ledStateMap[this->currentState].isError) {
if (ledStateMap[this->currentState].isRepeatable || ledStateMap[this->currentState].isError)
{
this->currentPatternIndex = 0;
this->finishedPattern = false;
}
}
}
void LEDManager::displayCurrentPattern() {
void LEDManager::displayCurrentPattern()
{
auto [state, delayTime] = ledStateMap[this->currentState].patterns[this->currentPatternIndex];
this->toggleLED(state);
this->timeToDelayFor = delayTime;
if (this->currentPatternIndex < ledStateMap[this->currentState].patterns.size() - 1)
this->currentPatternIndex++;
else {
else
{
this->finishedPattern = true;
this->toggleLED(LED_OFF);
}
}
void LEDManager::updateState(const LEDStates_e newState) {
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
@@ -153,21 +164,25 @@ void LEDManager::updateState(const LEDStates_e newState) {
if (newState == this->currentState)
return;
if (ledStateMap.contains(newState)) {
if (ledStateMap.contains(newState))
{
this->currentState = newState;
this->currentPatternIndex = 0;
this->finishedPattern = false;
}
}
void LEDManager::toggleLED(const bool state) const {
void LEDManager::toggleLED(const bool state) const
{
gpio_set_level(blink_led_pin, state);
}
void HandleLEDDisplayTask(void *pvParameter) {
void HandleLEDDisplayTask(void *pvParameter)
{
auto *ledManager = static_cast<LEDManager *>(pvParameter);
while (true) {
while (true)
{
ledManager->handleLED();
vTaskDelay(ledManager->getTimeToDelayFor());
}

View File

@@ -16,6 +16,7 @@
#include <unordered_map>
#include <vector>
#include <StateManager.hpp>
#include <ProjectConfig.hpp>
#include <helpers.hpp>
// it kinda looks like different boards have these states swapped
@@ -41,7 +42,7 @@ typedef std::unordered_map<LEDStates_e, LEDStage>
class LEDManager
{
public:
LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue);
LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin, QueueHandle_t ledStateQueue, std::shared_ptr<ProjectConfig> deviceConfig);
void setup();
void handleLED();
@@ -60,6 +61,7 @@ private:
LEDStates_e buffer;
LEDStates_e currentState;
std::shared_ptr<ProjectConfig> deviceConfig;
size_t currentPatternIndex = 0;
size_t timeToDelayFor = 100;

View File

@@ -21,35 +21,39 @@ struct BaseConfigModel
Preferences *pref;
};
enum class StreamingMode {
enum class StreamingMode
{
AUTO,
UVC,
WIFI,
};
struct DeviceMode_t : BaseConfigModel {
struct DeviceMode_t : BaseConfigModel
{
StreamingMode mode;
explicit DeviceMode_t( Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::AUTO){}
explicit DeviceMode_t(Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::AUTO) {}
void load() {
void load()
{
int stored_mode = this->pref->getInt("mode", 0);
this->mode = static_cast<StreamingMode>(stored_mode);
ESP_LOGI("DeviceMode", "Loaded device mode: %d", stored_mode);
}
void save() const {
void save() const
{
this->pref->putInt("mode", static_cast<int>(this->mode));
ESP_LOGI("DeviceMode", "Saved device mode: %d", static_cast<int>(this->mode));
}
};
struct DeviceConfig_t : BaseConfigModel
{
DeviceConfig_t(Preferences *pref) : BaseConfigModel(pref) {}
std::string OTALogin;
std::string OTAPassword;
int led_external_pwm_duty_cycle;
int OTAPort;
void load()
@@ -57,20 +61,23 @@ struct DeviceConfig_t : BaseConfigModel
this->OTALogin = this->pref->getString("OTALogin", "openiris");
this->OTAPassword = this->pref->getString("OTAPassword", "openiris");
this->OTAPort = this->pref->getInt("OTAPort", 3232);
this->led_external_pwm_duty_cycle = this->pref->getInt("led_ext_pwm", CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE);
};
void save() const {
void save() const
{
this->pref->putString("OTALogin", this->OTALogin.c_str());
this->pref->putString("OTAPassword", this->OTAPassword.c_str());
this->pref->putInt("OTAPort", this->OTAPort);
this->pref->putInt("led_ext_pwm", this->led_external_pwm_duty_cycle);
};
std::string toRepresentation() const
{
return Helpers::format_string(
"\"device_config\": {\"OTALogin\": \"%s\", \"OTAPassword\": \"%s\", "
"\"OTAPort\": %u}",
this->OTALogin.c_str(), this->OTAPassword.c_str(), this->OTAPort);
"\"OTAPort\": %u, \"led_external_pwm_duty_cycle\": %u}",
this->OTALogin.c_str(), this->OTAPassword.c_str(), this->OTAPort, this->led_external_pwm_duty_cycle);
};
};
@@ -94,7 +101,8 @@ struct MDNSConfig_t : BaseConfigModel
this->hostname = this->pref->getString("hostname", default_hostname);
};
void save() const {
void save() const
{
this->pref->putString("hostname", this->hostname.c_str());
};
@@ -125,7 +133,8 @@ struct CameraConfig_t : BaseConfigModel
this->brightness = this->pref->getInt("brightness", 2);
};
void save() const {
void save() const
{
this->pref->putInt("vflip", this->vflip);
this->pref->putInt("href", this->href);
this->pref->putInt("framesize", this->framesize);
@@ -186,12 +195,13 @@ struct WiFiConfig_t : BaseConfigModel
this->password = this->pref->getString(("password" + iter_str).c_str(), "");
this->channel = this->pref->getUInt(("channel" + iter_str).c_str());
this->power = this->pref->getUInt(("power" + iter_str).c_str());
ESP_LOGI("WiFiConfig", "Loaded network %d: name=%s, ssid=%s, channel=%d",
ESP_LOGI("WiFiConfig", "Loaded network %d: name=%s, ssid=%s, channel=%d",
index, this->name.c_str(), this->ssid.c_str(), this->channel);
};
void save() const {
void save() const
{
char buffer[2];
auto const iter_str = std::string(Helpers::itoa(this->index, buffer, 10));
@@ -200,8 +210,8 @@ struct WiFiConfig_t : BaseConfigModel
this->pref->putString(("password" + iter_str).c_str(), this->password.c_str());
this->pref->putUInt(("channel" + iter_str).c_str(), this->channel);
this->pref->putUInt(("power" + iter_str).c_str(), this->power);
ESP_LOGI("WiFiConfig", "Saved network %d: name=%s, ssid=%s, channel=%d",
ESP_LOGI("WiFiConfig", "Saved network %d: name=%s, ssid=%s, channel=%d",
this->index, this->name.c_str(), this->ssid.c_str(), this->channel);
};
@@ -228,7 +238,8 @@ struct AP_WiFiConfig_t : BaseConfigModel
this->password = this->pref->getString("apPassword", CONFIG_WIFI_AP_PASSWORD);
};
void save() const {
void save() const
{
this->pref->putString("apSSID", this->ssid.c_str());
this->pref->putString("apPass", this->password.c_str());
this->pref->putUInt("apChannel", this->channel);
@@ -254,7 +265,8 @@ struct WiFiTxPower_t : BaseConfigModel
this->power = this->pref->getUInt("txpower", 52);
};
void save() const {
void save() const
{
this->pref->putUInt("txpower", this->power);
};

View File

@@ -24,7 +24,8 @@ ProjectConfig::ProjectConfig(Preferences *pref) : pref(pref),
ProjectConfig::~ProjectConfig() = default;
void ProjectConfig::save() const {
void ProjectConfig::save() const
{
ESP_LOGD(CONFIGURATION_TAG, "Saving project config");
this->config.device.save();
this->config.device_mode.save();
@@ -92,14 +93,22 @@ bool ProjectConfig::reset()
//! DeviceConfig
//*
//**********************************************************************************************************************
void ProjectConfig::setDeviceConfig(const std::string &OTALogin,
const std::string &OTAPassword,
const int OTAPort)
void ProjectConfig::setOTAConfig(const std::string &OTALogin,
const std::string &OTAPassword,
const int OTAPort)
{
ESP_LOGD(CONFIGURATION_TAG, "Updating device config");
this->config.device.OTALogin.assign(OTALogin);
this->config.device.OTAPassword.assign(OTAPassword);
this->config.device.OTAPort = OTAPort;
this->config.device.save();
}
void ProjectConfig::setLEDDUtyCycleConfig(int led_external_pwm_duty_cycle)
{
this->config.device.led_external_pwm_duty_cycle = led_external_pwm_duty_cycle;
ESP_LOGI(CONFIGURATION_TAG, "Setting duty cycle to %d", led_external_pwm_duty_cycle);
this->config.device.save();
}
void ProjectConfig::setMDNSConfig(const std::string &hostname)
@@ -120,6 +129,7 @@ void ProjectConfig::setCameraConfig(const uint8_t vflip,
this->config.camera.framesize = framesize;
this->config.camera.quality = quality;
this->config.camera.brightness = brightness;
this->config.camera.save();
ESP_LOGD(CONFIGURATION_TAG, "Updating Camera config");
}
@@ -133,8 +143,8 @@ void ProjectConfig::setWifiConfig(const std::string &networkName,
const auto size = this->config.networks.size();
const auto it = std::ranges::find_if(this->config.networks,
[&](const WiFiConfig_t &network)
{ return network.name == networkName; });
[&](const WiFiConfig_t &network)
{ return network.name == networkName; });
if (it != this->config.networks.end())
{
@@ -191,8 +201,8 @@ void ProjectConfig::deleteWifiConfig(const std::string &networkName)
}
const auto it = std::ranges::find_if(this->config.networks,
[&](const WiFiConfig_t &network)
{ return network.name == networkName; });
[&](const WiFiConfig_t &network)
{ return network.name == networkName; });
if (it != this->config.networks.end())
{
@@ -205,6 +215,7 @@ void ProjectConfig::deleteWifiConfig(const std::string &networkName)
void ProjectConfig::setWiFiTxPower(uint8_t power)
{
this->config.txpower.power = power;
this->config.txpower.save();
ESP_LOGD(CONFIGURATION_TAG, "Updating wifi tx power");
}
@@ -215,12 +226,14 @@ void ProjectConfig::setAPWifiConfig(const std::string &ssid,
this->config.ap_network.ssid.assign(ssid);
this->config.ap_network.password.assign(password);
this->config.ap_network.channel = channel;
this->config.ap_network.save();
ESP_LOGD(CONFIGURATION_TAG, "Updating access point config");
}
void ProjectConfig::setDeviceMode(const StreamingMode deviceMode) {
void ProjectConfig::setDeviceMode(const StreamingMode deviceMode)
{
this->config.device_mode.mode = deviceMode;
this->config.device_mode.save(); // Save immediately
this->config.device_mode.save(); // Save immediately
}
//**********************************************************************************************************************
@@ -258,10 +271,12 @@ TrackerConfig_t &ProjectConfig::getTrackerConfig()
return this->config;
}
DeviceMode_t &ProjectConfig::getDeviceModeConfig() {
DeviceMode_t &ProjectConfig::getDeviceModeConfig()
{
return this->config.device_mode;
}
StreamingMode ProjectConfig::getDeviceMode() {
StreamingMode ProjectConfig::getDeviceMode()
{
return this->config.device_mode.mode;
}

View File

@@ -22,11 +22,6 @@ public:
void load();
void save() const;
void wifiConfigSave();
void cameraConfigSave();
void deviceConfigSave();
void mdnsConfigSave();
void wifiTxPowerConfigSave();
bool reset();
DeviceConfig_t &getDeviceConfig();
@@ -38,9 +33,10 @@ public:
WiFiTxPower_t &getWiFiTxPowerConfig();
TrackerConfig_t &getTrackerConfig();
void setDeviceConfig(const std::string &OTALogin,
const std::string &OTAPassword,
int OTAPort);
void setOTAConfig(const std::string &OTALogin,
const std::string &OTAPassword,
int OTAPort);
void setLEDDUtyCycleConfig(int led_external_pwm_duty_cycle);
void setMDNSConfig(const std::string &hostname);
void setCameraConfig(uint8_t vflip,
uint8_t framesize,

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);
auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue, deviceConfig);
auto *serialManager = new SerialManager(commandManager, &timerHandle, deviceConfig);
static void initNVSStorage()
@@ -274,10 +274,10 @@ extern "C" void app_main(void)
// setup CI and building for other boards
// finish todos, overhaul stuff a bit
// esp_log_set_vprintf(&websocket_logger);
Logo::printASCII();
initNVSStorage();
// esp_log_set_vprintf(&websocket_logger);
deviceConfig->load();
ledManager->setup();
xTaskCreate(
@@ -297,7 +297,6 @@ extern "C" void app_main(void)
3,
nullptr);
deviceConfig->load();
serialManager->setup();
static TaskHandle_t serialManagerHandle = nullptr;
@@ -308,8 +307,7 @@ extern "C" void app_main(void)
1024 * 6,
serialManager,
1, // we only rely on the serial manager during provisioning, we can run it slower
&serialManagerHandle
);
&serialManagerHandle);
wifiManager->Begin();
mdnsManager.start();

View File

@@ -50,5 +50,5 @@ CONFIG_LED_EXTERNAL_CONTROL=y
CONFIG_LED_EXTERNAL_PWM_FREQ=5000
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100
CONFIG_LED_EXTERNAL_GPIO=1
CONFIG_CAMERA_USB_XCLK_FREQ=23000000 # NOT TESTED
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
CONFIG_GENERAL_WIRED_MODE=y

View File

@@ -410,6 +410,17 @@ class OpenIrisDevice:
print(f"❌ Failed to parse mode response: {e}")
return "unknown"
def set_led_duty_cycle(self, duty_cycle):
"""Sets the PWN duty cycle of the LED"""
print(f"🌟 Setting LED duty cycle to {duty_cycle}%...")
response = self.send_command("set_led_duty_cycle", {"dutyCycle": duty_cycle})
if "error" in response:
print(f"❌ Failed to set LED duty cycle: {response['error']}")
return False
print("✅ LED duty cycle set successfully")
return True
def monitor_logs(self):
"""Monitor device logs until interrupted"""
print("📋 Monitoring device logs (Press Ctrl+C to exit)...")
@@ -736,6 +747,24 @@ def switch_device_mode(device: OpenIrisDevice, args = None):
print("❌ Invalid mode selection")
def set_led_duty_cycle(device: OpenIrisDevice, args=None):
while True:
input_data = input("Enter LED external PWM duty cycle (0-100) or `back` to exit: \n")
if input_data.lower() == "back":
break
try:
duty_cycle = int(input_data)
except ValueError:
print("❌ Invalid input. Please enter a number between 0 and 100.")
if duty_cycle < 0 or duty_cycle > 100:
print("❌ Duty cycle must be between 0 and 100.")
else:
device.set_led_duty_cycle(duty_cycle)
break
def monitor_logs(device: OpenIrisDevice, args = None):
device.monitor_logs()
@@ -750,7 +779,8 @@ COMMANDS_MAP = {
"7": attempt_wifi_connection,
"8": start_streaming,
"9": switch_device_mode,
"10": monitor_logs,
"10": set_led_duty_cycle,
"11": monitor_logs,
}
@@ -848,9 +878,10 @@ def main():
print("7. 🔗 Connect to WiFi")
print("8. 🚀 Start streaming mode")
print("9. 🔄 Switch device mode (WiFi/UVC/Auto)")
print("10. 📋 Monitor logs")
print("10. 💡 Update PWM Duty Cycle")
print("11. 📋 Monitor logs")
print("exit. 🚪 Exit")
choice = input("\nSelect option (1-10): ").strip()
choice = input("\nSelect option (1-11): ").strip()
if choice == "exit":
break