mirror of
https://github.com/MrUnknownDE/OpenIris-ESPIDF.git
synced 2026-04-19 14:33:45 +02:00
- Updated README to reflect changes in device mode terminology from "Auto" to "Setup".
- Changed configuration macros from CONFIG_GENERAL_DEFAULT_WIRED_MODE to CONFIG_GENERAL_INCLUDE_UVC_MODE across multiple files. - Introduced new command for retrieving LED current in CommandManager. - Added MonitoringManager and CurrentMonitor classes to handle LED current monitoring. - Updated Kconfig to include options for LED current monitoring. - Modified main application logic to integrate MonitoringManager and handle new device modes. - Adjusted CMakeLists and source files to include new monitoring components.
This commit is contained in:
@@ -84,7 +84,7 @@ Examples:
|
|||||||
What the CLI can do:
|
What the CLI can do:
|
||||||
- Wi‑Fi menu: automatic (scan → pick → password → connect → wait for IP) or manual (scan, show, configure, connect, status)
|
- Wi‑Fi menu: automatic (scan → pick → password → connect → wait for IP) or manual (scan, show, configure, connect, status)
|
||||||
- Set MDNS/Device name (also used for the UVC device name)
|
- Set MDNS/Device name (also used for the UVC device name)
|
||||||
- Switch mode (Wi‑Fi / UVC / Auto)
|
- Switch mode (Wi‑Fi / UVC / Setup)
|
||||||
- Adjust LED PWM
|
- Adjust LED PWM
|
||||||
- Show a Settings Summary (MAC, Wi‑Fi status, mode, PWM, …)
|
- Show a Settings Summary (MAC, Wi‑Fi status, mode, PWM, …)
|
||||||
- View logs
|
- View logs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// source: https://github.com/espressif/esp-iot-solution/blob/4730d91db70df7e6e0a3191d725ab1c5f98ff9ce/examples/usb/device/usb_webcam/bootloader_components/boot_hooks/boot_hooks.c
|
// source: https://github.com/espressif/esp-iot-solution/blob/4730d91db70df7e6e0a3191d725ab1c5f98ff9ce/examples/usb/device/usb_webcam/bootloader_components/boot_hooks/boot_hooks.c
|
||||||
|
|
||||||
#ifdef CONFIG_GENERAL_DEFAULT_WIRED_MODE
|
#ifdef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "soc/rtc_cntl_struct.h"
|
#include "soc/rtc_cntl_struct.h"
|
||||||
#include "soc/usb_serial_jtag_reg.h"
|
#include "soc/usb_serial_jtag_reg.h"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ void CameraManager::setupCameraPinout()
|
|||||||
|
|
||||||
ESP_LOGI(CAMERA_MANAGER_TAG, "CAM_BOARD");
|
ESP_LOGI(CAMERA_MANAGER_TAG, "CAM_BOARD");
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_GENERAL_DEFAULT_WIRED_MODE
|
#if CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
xclk_freq_hz = CONFIG_CAMERA_USB_XCLK_FREQ;
|
xclk_freq_hz = CONFIG_CAMERA_USB_XCLK_FREQ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ bool CameraManager::setupCamera()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_GENERAL_DEFAULT_WIRED_MODE
|
#if CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
const auto temp_sensor = esp_camera_sensor_get();
|
const auto temp_sensor = esp_camera_sensor_get();
|
||||||
|
|
||||||
// Thanks to lick_it, we discovered that OV5640 likes to overheat when
|
// Thanks to lick_it, we discovered that OV5640 likes to overheat when
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ idf_component_register(
|
|||||||
INCLUDE_DIRS
|
INCLUDE_DIRS
|
||||||
"CommandManager"
|
"CommandManager"
|
||||||
"CommandManager/commands"
|
"CommandManager/commands"
|
||||||
REQUIRES ProjectConfig cJSON CameraManager OpenIrisTasks wifiManager Helpers LEDManager
|
REQUIRES ProjectConfig cJSON CameraManager OpenIrisTasks wifiManager Helpers LEDManager Monitoring
|
||||||
)
|
)
|
||||||
@@ -26,6 +26,7 @@ std::unordered_map<std::string, CommandType> commandTypeMap = {
|
|||||||
{"set_led_duty_cycle", CommandType::SET_LED_DUTY_CYCLE},
|
{"set_led_duty_cycle", CommandType::SET_LED_DUTY_CYCLE},
|
||||||
{"get_led_duty_cycle", CommandType::GET_LED_DUTY_CYCLE},
|
{"get_led_duty_cycle", CommandType::GET_LED_DUTY_CYCLE},
|
||||||
{"get_serial", CommandType::GET_SERIAL},
|
{"get_serial", CommandType::GET_SERIAL},
|
||||||
|
{"get_led_current", CommandType::GET_LED_CURRENT},
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
||||||
@@ -103,6 +104,9 @@ std::function<CommandResult()> CommandManager::createCommand(const CommandType t
|
|||||||
case CommandType::GET_SERIAL:
|
case CommandType::GET_SERIAL:
|
||||||
return [this]
|
return [this]
|
||||||
{ return getSerialNumberCommand(this->registry); };
|
{ return getSerialNumberCommand(this->registry); };
|
||||||
|
case CommandType::GET_LED_CURRENT:
|
||||||
|
return [this]
|
||||||
|
{ return getLEDCurrentCommand(this->registry); };
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ enum class CommandType
|
|||||||
SET_LED_DUTY_CYCLE,
|
SET_LED_DUTY_CYCLE,
|
||||||
GET_LED_DUTY_CYCLE,
|
GET_LED_DUTY_CYCLE,
|
||||||
GET_SERIAL,
|
GET_SERIAL,
|
||||||
|
GET_LED_CURRENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommandManager
|
class CommandManager
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ enum class DependencyType
|
|||||||
project_config,
|
project_config,
|
||||||
camera_manager,
|
camera_manager,
|
||||||
wifi_manager,
|
wifi_manager,
|
||||||
led_manager
|
led_manager,
|
||||||
|
monitoring_manager
|
||||||
};
|
};
|
||||||
|
|
||||||
class DependencyRegistry
|
class DependencyRegistry
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "device_commands.hpp"
|
#include "device_commands.hpp"
|
||||||
#include "LEDManager.hpp"
|
#include "LEDManager.hpp"
|
||||||
|
#include "MonitoringManager.hpp"
|
||||||
#include "esp_mac.h"
|
#include "esp_mac.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
@@ -171,9 +172,9 @@ CommandResult switchModeCommand(std::shared_ptr<DependencyRegistry> registry, st
|
|||||||
{
|
{
|
||||||
newMode = StreamingMode::WIFI;
|
newMode = StreamingMode::WIFI;
|
||||||
}
|
}
|
||||||
else if (strcmp(modeStr, "auto") == 0)
|
else if (strcmp(modeStr, "setup") == 0 || strcmp(modeStr, "auto") == 0)
|
||||||
{
|
{
|
||||||
newMode = StreamingMode::AUTO;
|
newMode = StreamingMode::SETUP;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -203,8 +204,8 @@ CommandResult getDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry)
|
|||||||
case StreamingMode::WIFI:
|
case StreamingMode::WIFI:
|
||||||
modeStr = "WiFi";
|
modeStr = "WiFi";
|
||||||
break;
|
break;
|
||||||
case StreamingMode::AUTO:
|
case StreamingMode::SETUP:
|
||||||
modeStr = "Auto";
|
modeStr = "Setup";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,3 +232,19 @@ CommandResult getSerialNumberCommand(std::shared_ptr<DependencyRegistry> /*regis
|
|||||||
auto result = std::format("{{ \"serial\": \"{}\", \"mac\": \"{}\" }}", serial_no_sep, mac_colon);
|
auto result = std::format("{{ \"serial\": \"{}\", \"mac\": \"{}\" }}", serial_no_sep, mac_colon);
|
||||||
return CommandResult::getSuccessResult(result);
|
return CommandResult::getSuccessResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandResult getLEDCurrentCommand(std::shared_ptr<DependencyRegistry> registry)
|
||||||
|
{
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
auto mon = registry->resolve<MonitoringManager>(DependencyType::monitoring_manager);
|
||||||
|
if (!mon)
|
||||||
|
{
|
||||||
|
return CommandResult::getErrorResult("MonitoringManager unavailable");
|
||||||
|
}
|
||||||
|
float ma = mon->getCurrentMilliAmps();
|
||||||
|
auto result = std::format("{{ \"led_current_ma\": {:.3f} }}", static_cast<double>(ma));
|
||||||
|
return CommandResult::getSuccessResult(result);
|
||||||
|
#else
|
||||||
|
return CommandResult::getErrorResult("Monitoring disabled");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,4 +22,7 @@ CommandResult switchModeCommand(std::shared_ptr<DependencyRegistry> registry, st
|
|||||||
|
|
||||||
CommandResult getDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry);
|
CommandResult getDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry);
|
||||||
|
|
||||||
CommandResult getSerialNumberCommand(std::shared_ptr<DependencyRegistry> registry);
|
CommandResult getSerialNumberCommand(std::shared_ptr<DependencyRegistry> registry);
|
||||||
|
|
||||||
|
// Monitoring
|
||||||
|
CommandResult getLEDCurrentCommand(std::shared_ptr<DependencyRegistry> registry);
|
||||||
6
components/Monitoring/CMakeLists.txt
Normal file
6
components/Monitoring/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
idf_component_register(SRCS
|
||||||
|
"Monitoring/CurrentMonitor.cpp"
|
||||||
|
"Monitoring/MonitoringManager.cpp"
|
||||||
|
INCLUDE_DIRS "Monitoring"
|
||||||
|
REQUIRES driver esp_adc Helpers
|
||||||
|
)
|
||||||
179
components/Monitoring/Monitoring/CurrentMonitor.cpp
Normal file
179
components/Monitoring/Monitoring/CurrentMonitor.cpp
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
#include "CurrentMonitor.hpp"
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
#include "esp_adc/adc_oneshot.h"
|
||||||
|
#include "esp_adc/adc_cali.h"
|
||||||
|
#include "esp_adc/adc_cali_scheme.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char *TAG_CM = "[CurrentMonitor]";
|
||||||
|
|
||||||
|
CurrentMonitor::CurrentMonitor()
|
||||||
|
{
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
samples_.assign(CONFIG_MONITORING_LED_SAMPLES, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurrentMonitor::setup()
|
||||||
|
{
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
init_adc();
|
||||||
|
#else
|
||||||
|
ESP_LOGI(TAG_CM, "LED current monitoring disabled");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float CurrentMonitor::getCurrentMilliAmps() const
|
||||||
|
{
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
const int shunt_milliohm = CONFIG_MONITORING_LED_SHUNT_MILLIOHM; // mΩ
|
||||||
|
if (shunt_milliohm <= 0)
|
||||||
|
return 0.0f;
|
||||||
|
// Physically correct scaling:
|
||||||
|
// I[mA] = 1000 * Vshunt[mV] / R[mΩ]
|
||||||
|
return (1000.0f * static_cast<float>(filtered_mv_)) / static_cast<float>(shunt_milliohm);
|
||||||
|
#else
|
||||||
|
return 0.0f;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float CurrentMonitor::pollAndGetMilliAmps()
|
||||||
|
{
|
||||||
|
sampleOnce();
|
||||||
|
return getCurrentMilliAmps();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurrentMonitor::sampleOnce()
|
||||||
|
{
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
int mv = read_mv_once();
|
||||||
|
// Divide by analog gain/divider factor to get shunt voltage
|
||||||
|
if (CONFIG_MONITORING_LED_GAIN > 0)
|
||||||
|
mv = mv / CONFIG_MONITORING_LED_GAIN;
|
||||||
|
|
||||||
|
// Moving average over N samples
|
||||||
|
if (samples_.empty())
|
||||||
|
{
|
||||||
|
samples_.assign(CONFIG_MONITORING_LED_SAMPLES, 0);
|
||||||
|
sample_sum_ = 0;
|
||||||
|
sample_idx_ = 0;
|
||||||
|
sample_count_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sample_sum_ -= samples_[sample_idx_];
|
||||||
|
samples_[sample_idx_] = mv;
|
||||||
|
sample_sum_ += mv;
|
||||||
|
sample_idx_ = (sample_idx_ + 1) % samples_.size();
|
||||||
|
if (sample_count_ < samples_.size())
|
||||||
|
sample_count_++;
|
||||||
|
|
||||||
|
filtered_mv_ = sample_sum_ / static_cast<int>(sample_count_ > 0 ? sample_count_ : 1);
|
||||||
|
#else
|
||||||
|
(void)0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
|
||||||
|
static adc_oneshot_unit_handle_t s_adc_handle = nullptr;
|
||||||
|
static adc_cali_handle_t s_cali_handle = nullptr;
|
||||||
|
static bool s_cali_inited = false;
|
||||||
|
static adc_channel_t s_channel;
|
||||||
|
static adc_unit_t s_unit;
|
||||||
|
|
||||||
|
void CurrentMonitor::init_adc()
|
||||||
|
{
|
||||||
|
// Derive ADC unit/channel from GPIO
|
||||||
|
int gpio = CONFIG_MONITORING_LED_ADC_GPIO;
|
||||||
|
|
||||||
|
esp_err_t err;
|
||||||
|
adc_oneshot_unit_init_cfg_t unit_cfg = {
|
||||||
|
.unit_id = ADC_UNIT_1,
|
||||||
|
};
|
||||||
|
err = adc_oneshot_new_unit(&unit_cfg, &s_adc_handle);
|
||||||
|
if (err != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG_CM, "adc_oneshot_new_unit failed: %s", esp_err_to_name(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to map GPIO to ADC channel automatically if helper exists; otherwise guess for ESP32-S3 ADC1
|
||||||
|
#ifdef ADC1_GPIO1_CHANNEL
|
||||||
|
(void)0; // placeholder for potential future macros
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Use IO-to-channel helper where available
|
||||||
|
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
// ESP32-S3: ADC1 channels on GPIO1..GPIO10 map to CH0..CH9
|
||||||
|
if (gpio >= 1 && gpio <= 10)
|
||||||
|
{
|
||||||
|
s_unit = ADC_UNIT_1;
|
||||||
|
s_channel = static_cast<adc_channel_t>(gpio - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG_CM, "Configured GPIO %d may not be ADC-capable on ESP32-S3", gpio);
|
||||||
|
s_unit = ADC_UNIT_1;
|
||||||
|
s_channel = ADC_CHANNEL_0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Fallback: assume ADC1 CH0
|
||||||
|
s_unit = ADC_UNIT_1;
|
||||||
|
s_channel = ADC_CHANNEL_0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
adc_oneshot_chan_cfg_t chan_cfg = {
|
||||||
|
.atten = ADC_ATTEN_DB_11,
|
||||||
|
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||||
|
};
|
||||||
|
err = adc_oneshot_config_channel(s_adc_handle, s_channel, &chan_cfg);
|
||||||
|
if (err != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG_CM, "adc_oneshot_config_channel failed: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calibration using curve fitting if available
|
||||||
|
adc_cali_curve_fitting_config_t cal_cfg = {
|
||||||
|
.unit_id = s_unit,
|
||||||
|
.atten = chan_cfg.atten,
|
||||||
|
.bitwidth = chan_cfg.bitwidth,
|
||||||
|
};
|
||||||
|
if (adc_cali_create_scheme_curve_fitting(&cal_cfg, &s_cali_handle) == ESP_OK)
|
||||||
|
{
|
||||||
|
s_cali_inited = true;
|
||||||
|
ESP_LOGI(TAG_CM, "ADC calibration initialized (curve fitting)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_cali_inited = false;
|
||||||
|
ESP_LOGW(TAG_CM, "ADC calibration not available; using raw-to-mV approximation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CurrentMonitor::read_mv_once()
|
||||||
|
{
|
||||||
|
if (!s_adc_handle)
|
||||||
|
return 0;
|
||||||
|
int raw = 0;
|
||||||
|
if (adc_oneshot_read(s_adc_handle, s_channel, &raw) != ESP_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int mv = 0;
|
||||||
|
if (s_cali_inited)
|
||||||
|
{
|
||||||
|
if (adc_cali_raw_to_voltage(s_cali_handle, raw, &mv) != ESP_OK)
|
||||||
|
mv = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Very rough fallback for 11dB attenuation
|
||||||
|
// Typical full-scale ~2450mV at raw max 4095 (12-bit). IDF defaults may vary.
|
||||||
|
mv = (raw * 2450) / 4095;
|
||||||
|
}
|
||||||
|
return mv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONFIG_MONITORING_LED_CURRENT
|
||||||
45
components/Monitoring/Monitoring/CurrentMonitor.hpp
Normal file
45
components/Monitoring/Monitoring/CurrentMonitor.hpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
class CurrentMonitor {
|
||||||
|
public:
|
||||||
|
CurrentMonitor();
|
||||||
|
~CurrentMonitor() = default;
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
void sampleOnce();
|
||||||
|
|
||||||
|
// Returns filtered voltage in millivolts at shunt (after dividing by gain)
|
||||||
|
int getFilteredMillivolts() const { return filtered_mv_; }
|
||||||
|
// Returns current in milliamps computed as Vshunt[mV] / R[mΩ]
|
||||||
|
float getCurrentMilliAmps() const;
|
||||||
|
|
||||||
|
// convenience: combined sampling and compute; returns mA
|
||||||
|
float pollAndGetMilliAmps();
|
||||||
|
|
||||||
|
// Whether monitoring is enabled by Kconfig
|
||||||
|
static constexpr bool isEnabled()
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MONITORING_LED_CURRENT
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
void init_adc();
|
||||||
|
int read_mv_once();
|
||||||
|
int gpio_to_adc_channel(int gpio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int filtered_mv_ = 0;
|
||||||
|
int sample_sum_ = 0;
|
||||||
|
std::vector<int> samples_;
|
||||||
|
size_t sample_idx_ = 0;
|
||||||
|
size_t sample_count_ = 0;
|
||||||
|
};
|
||||||
58
components/Monitoring/Monitoring/MonitoringManager.cpp
Normal file
58
components/Monitoring/Monitoring/MonitoringManager.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "MonitoringManager.hpp"
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
static const char* TAG_MM = "[MonitoringManager]";
|
||||||
|
|
||||||
|
void MonitoringManager::setup()
|
||||||
|
{
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
cm_.setup();
|
||||||
|
ESP_LOGI(TAG_MM, "Monitoring enabled. Interval=%dms, Samples=%d, Gain=%d, R=%dmΩ",
|
||||||
|
CONFIG_MONITORING_LED_INTERVAL_MS,
|
||||||
|
CONFIG_MONITORING_LED_SAMPLES,
|
||||||
|
CONFIG_MONITORING_LED_GAIN,
|
||||||
|
CONFIG_MONITORING_LED_SHUNT_MILLIOHM);
|
||||||
|
#else
|
||||||
|
ESP_LOGI(TAG_MM, "Monitoring disabled by Kconfig");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitoringManager::start()
|
||||||
|
{
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
if (task_ == nullptr)
|
||||||
|
{
|
||||||
|
xTaskCreate(&MonitoringManager::taskEntry, "MonitoringTask", 2048, this, 1, &task_);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitoringManager::stop()
|
||||||
|
{
|
||||||
|
if (task_)
|
||||||
|
{
|
||||||
|
TaskHandle_t toDelete = task_;
|
||||||
|
task_ = nullptr;
|
||||||
|
vTaskDelete(toDelete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitoringManager::taskEntry(void* arg)
|
||||||
|
{
|
||||||
|
static_cast<MonitoringManager*>(arg)->run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitoringManager::run()
|
||||||
|
{
|
||||||
|
#if CONFIG_MONITORING_LED_CURRENT
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
float ma = cm_.pollAndGetMilliAmps();
|
||||||
|
last_current_ma_.store(ma);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_MONITORING_LED_INTERVAL_MS));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
vTaskDelete(nullptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
26
components/Monitoring/Monitoring/MonitoringManager.hpp
Normal file
26
components/Monitoring/Monitoring/MonitoringManager.hpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
|
#include <atomic>
|
||||||
|
#include "CurrentMonitor.hpp"
|
||||||
|
|
||||||
|
class MonitoringManager {
|
||||||
|
public:
|
||||||
|
MonitoringManager() = default;
|
||||||
|
~MonitoringManager() = default;
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
// Latest filtered current in mA
|
||||||
|
float getCurrentMilliAmps() const { return last_current_ma_.load(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void taskEntry(void* arg);
|
||||||
|
void run();
|
||||||
|
|
||||||
|
TaskHandle_t task_{nullptr};
|
||||||
|
std::atomic<float> last_current_ma_{0.0f};
|
||||||
|
CurrentMonitor cm_;
|
||||||
|
};
|
||||||
@@ -23,7 +23,7 @@ struct BaseConfigModel
|
|||||||
|
|
||||||
enum class StreamingMode
|
enum class StreamingMode
|
||||||
{
|
{
|
||||||
AUTO,
|
SETUP,
|
||||||
UVC,
|
UVC,
|
||||||
WIFI,
|
WIFI,
|
||||||
};
|
};
|
||||||
@@ -31,18 +31,18 @@ enum class StreamingMode
|
|||||||
struct DeviceMode_t : BaseConfigModel
|
struct DeviceMode_t : BaseConfigModel
|
||||||
{
|
{
|
||||||
StreamingMode mode;
|
StreamingMode mode;
|
||||||
explicit DeviceMode_t(Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::AUTO) {}
|
explicit DeviceMode_t(Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::SETUP) {}
|
||||||
|
|
||||||
void load()
|
void load()
|
||||||
{
|
{
|
||||||
// Default mode can be controlled via sdkconfig:
|
// Default mode can be controlled via sdkconfig:
|
||||||
// - If CONFIG_START_IN_UVC_MODE is enabled, default to UVC
|
// - If CONFIG_START_IN_UVC_MODE is enabled, default to UVC
|
||||||
// - Otherwise default to AUTO
|
// - Otherwise default to SETUP
|
||||||
int default_mode =
|
int default_mode =
|
||||||
#if CONFIG_START_IN_UVC_MODE
|
#if CONFIG_START_IN_UVC_MODE
|
||||||
static_cast<int>(StreamingMode::UVC);
|
static_cast<int>(StreamingMode::UVC);
|
||||||
#else
|
#else
|
||||||
static_cast<int>(StreamingMode::AUTO);
|
static_cast<int>(StreamingMode::SETUP);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int stored_mode = this->pref->getInt("mode", default_mode);
|
int stored_mode = this->pref->getInt("mode", default_mode);
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ static void UVCStreamHelpers::camera_fb_return_cb(uvc_fb_t *fb, void *cb_ctx)
|
|||||||
esp_err_t UVCStreamManager::setup()
|
esp_err_t UVCStreamManager::setup()
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifndef CONFIG_GENERAL_DEFAULT_WIRED_MODE
|
#ifndef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
ESP_LOGE(UVC_STREAM_TAG, "The board does not support UVC, please, setup WiFi connection.");
|
ESP_LOGE(UVC_STREAM_TAG, "The board does not support UVC, please, setup WiFi connection.");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ menu "OpenIris: General Configuration"
|
|||||||
When enabled, the default device streaming mode will be UVC unless overridden by a
|
When enabled, the default device streaming mode will be UVC unless overridden by a
|
||||||
saved preference. When disabled, the default mode is AUTO.
|
saved preference. When disabled, the default mode is AUTO.
|
||||||
|
|
||||||
config GENERAL_DEFAULT_WIRED_MODE
|
config GENERAL_INCLUDE_UVC_MODE
|
||||||
bool "Wired mode"
|
bool "Wired mode"
|
||||||
default false
|
default false
|
||||||
help
|
help
|
||||||
@@ -114,4 +114,54 @@ menu "OpenIris: LED Configuration"
|
|||||||
Duty cycle of the PWM signal for external IR LEDs, in percent.
|
Duty cycle of the PWM signal for external IR LEDs, in percent.
|
||||||
0 means always off, 100 means always on.
|
0 means always off, 100 means always on.
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
menu "OpenIris: Monitoring"
|
||||||
|
|
||||||
|
config MONITORING_LED_CURRENT
|
||||||
|
bool "Enable LED current monitoring"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable sampling LED current via ADC and report it over commands.
|
||||||
|
|
||||||
|
config MONITORING_LED_ADC_GPIO
|
||||||
|
int "ADC GPIO for LED current sense"
|
||||||
|
depends on MONITORING_LED_CURRENT
|
||||||
|
range 0 48
|
||||||
|
default 3
|
||||||
|
help
|
||||||
|
GPIO connected to the current sense input (ADC1 on ESP32-S3: 1..10 supported).
|
||||||
|
|
||||||
|
config MONITORING_LED_GAIN
|
||||||
|
int "Analog front-end gain/divider"
|
||||||
|
depends on MONITORING_LED_CURRENT
|
||||||
|
range 1 1024
|
||||||
|
default 11
|
||||||
|
help
|
||||||
|
Divider or amplifier gain between shunt and ADC. The measured mV are divided by this value.
|
||||||
|
|
||||||
|
config MONITORING_LED_SHUNT_MILLIOHM
|
||||||
|
int "Shunt resistance (milli-ohms)"
|
||||||
|
depends on MONITORING_LED_CURRENT
|
||||||
|
range 1 1000000
|
||||||
|
default 22000
|
||||||
|
help
|
||||||
|
Shunt resistor value in milli-ohms. Current[mA] = 1000 * Vshunt[mV] / R[mΩ].
|
||||||
|
|
||||||
|
config MONITORING_LED_SAMPLES
|
||||||
|
int "Filter window size (samples)"
|
||||||
|
depends on MONITORING_LED_CURRENT
|
||||||
|
range 1 200
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
Moving-average window length for voltage filtering.
|
||||||
|
|
||||||
|
config MONITORING_LED_INTERVAL_MS
|
||||||
|
int "Sampling interval (ms)"
|
||||||
|
depends on MONITORING_LED_CURRENT
|
||||||
|
range 10 60000
|
||||||
|
default 500
|
||||||
|
help
|
||||||
|
Period between samples when background monitoring is active.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
@@ -21,8 +21,9 @@
|
|||||||
#include <SerialManager.hpp>
|
#include <SerialManager.hpp>
|
||||||
#include <RestAPI.hpp>
|
#include <RestAPI.hpp>
|
||||||
#include <main_globals.hpp>
|
#include <main_globals.hpp>
|
||||||
|
#include <MonitoringManager.hpp>
|
||||||
|
|
||||||
#ifdef CONFIG_GENERAL_DEFAULT_WIRED_MODE
|
#ifdef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
#include <UVCStream.hpp>
|
#include <UVCStream.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -52,12 +53,13 @@ StreamServer streamServer(80, stateManager);
|
|||||||
|
|
||||||
auto *restAPI = new RestAPI("http://0.0.0.0:81", commandManager);
|
auto *restAPI = new RestAPI("http://0.0.0.0:81", commandManager);
|
||||||
|
|
||||||
#ifdef CONFIG_GENERAL_DEFAULT_WIRED_MODE
|
#ifdef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
UVCStreamManager uvcStream;
|
UVCStreamManager uvcStream;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto ledManager = std::make_shared<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);
|
auto *serialManager = new SerialManager(commandManager, &timerHandle, deviceConfig);
|
||||||
|
MonitoringManager monitoringManager;
|
||||||
|
|
||||||
void startWiFiMode(bool shouldCloseSerialManager);
|
void startWiFiMode(bool shouldCloseSerialManager);
|
||||||
void startWiredMode(bool shouldCloseSerialManager);
|
void startWiredMode(bool shouldCloseSerialManager);
|
||||||
@@ -81,14 +83,14 @@ int websocket_logger(const char *format, va_list args)
|
|||||||
|
|
||||||
void launch_streaming()
|
void launch_streaming()
|
||||||
{
|
{
|
||||||
// Note, when switching and later right away activating UVC mode when we were previously in WiFi or Auto mode, the WiFi
|
// Note, when switching and later right away activating UVC mode when we were previously in WiFi or Setup mode, the WiFi
|
||||||
// utilities will still be running since we've launched them with startAutoMode() -> startWiFiMode()
|
// utilities will still be running since we've launched them with startAutoMode() -> startWiFiMode()
|
||||||
// we could add detection of this case, but it's probably not worth it since the next start of the device literally won't launch them
|
// we could add detection of this case, but it's probably not worth it since the next start of the device literally won't launch them
|
||||||
// and we're telling folks to just reboot the device anyway
|
// and we're telling folks to just reboot the device anyway
|
||||||
// same case goes for when switching from UVC to WiFi
|
// same case goes for when switching from UVC to WiFi
|
||||||
|
|
||||||
StreamingMode deviceMode = deviceConfig->getDeviceMode();
|
StreamingMode deviceMode = deviceConfig->getDeviceMode();
|
||||||
// if we've changed the mode from auto to something else, we can clean up serial manager
|
// if we've changed the mode from setup to something else, we can clean up serial manager
|
||||||
// either the API endpoints or CDC will take care of further configuration
|
// either the API endpoints or CDC will take care of further configuration
|
||||||
if (deviceMode == StreamingMode::WIFI)
|
if (deviceMode == StreamingMode::WIFI)
|
||||||
{
|
{
|
||||||
@@ -98,10 +100,10 @@ void launch_streaming()
|
|||||||
{
|
{
|
||||||
startWiredMode(true);
|
startWiredMode(true);
|
||||||
}
|
}
|
||||||
else if (deviceMode == StreamingMode::AUTO)
|
else if (deviceMode == StreamingMode::SETUP)
|
||||||
{
|
{
|
||||||
// we're still in auto, the user didn't select anything yet, let's give a bit of time for them to make a choice
|
// we're still in setup, the user didn't select anything yet, let's give a bit of time for them to make a choice
|
||||||
ESP_LOGI("[MAIN]", "No mode was selected, staying in AUTO mode. WiFi streaming will be enabled still. \nPlease select another mode if you'd like.");
|
ESP_LOGI("[MAIN]", "No mode was selected, staying in SETUP mode. WiFi streaming will be enabled still. \nPlease select another mode if you'd like.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -150,7 +152,7 @@ void force_activate_streaming()
|
|||||||
|
|
||||||
void startWiredMode(bool shouldCloseSerialManager)
|
void startWiredMode(bool shouldCloseSerialManager)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_GENERAL_DEFAULT_WIRED_MODE
|
#ifndef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
ESP_LOGE("[MAIN]", "UVC mode selected but the board likely does not support it.");
|
ESP_LOGE("[MAIN]", "UVC mode selected but the board likely does not support it.");
|
||||||
ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available");
|
ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available");
|
||||||
deviceMode = StreamingMode::WIFI;
|
deviceMode = StreamingMode::WIFI;
|
||||||
@@ -220,7 +222,7 @@ void startWiFiMode(bool shouldCloseSerialManager)
|
|||||||
|
|
||||||
void startSetupMode()
|
void startSetupMode()
|
||||||
{
|
{
|
||||||
// If we're in an auto mode - Device starts with a 20-second delay before deciding on what to do
|
// If we're in SETUP mode - Device starts with a 20-second delay before deciding on what to do
|
||||||
// during this time we await any commands
|
// during this time we await any commands
|
||||||
ESP_LOGI("[MAIN]", "=====================================");
|
ESP_LOGI("[MAIN]", "=====================================");
|
||||||
ESP_LOGI("[MAIN]", "STARTUP: 20-SECOND DELAY MODE ACTIVE");
|
ESP_LOGI("[MAIN]", "STARTUP: 20-SECOND DELAY MODE ACTIVE");
|
||||||
@@ -247,6 +249,7 @@ extern "C" void app_main(void)
|
|||||||
dependencyRegistry->registerService<CameraManager>(DependencyType::camera_manager, cameraHandler);
|
dependencyRegistry->registerService<CameraManager>(DependencyType::camera_manager, cameraHandler);
|
||||||
dependencyRegistry->registerService<WiFiManager>(DependencyType::wifi_manager, wifiManager);
|
dependencyRegistry->registerService<WiFiManager>(DependencyType::wifi_manager, wifiManager);
|
||||||
dependencyRegistry->registerService<LEDManager>(DependencyType::led_manager, ledManager);
|
dependencyRegistry->registerService<LEDManager>(DependencyType::led_manager, ledManager);
|
||||||
|
dependencyRegistry->registerService<MonitoringManager>(DependencyType::monitoring_manager, std::shared_ptr<MonitoringManager>(&monitoringManager, [](MonitoringManager*){}));
|
||||||
|
|
||||||
// add endpoint to check firmware version
|
// add endpoint to check firmware version
|
||||||
// add firmware version somewhere
|
// add firmware version somewhere
|
||||||
@@ -259,6 +262,8 @@ extern "C" void app_main(void)
|
|||||||
initNVSStorage();
|
initNVSStorage();
|
||||||
deviceConfig->load();
|
deviceConfig->load();
|
||||||
ledManager->setup();
|
ledManager->setup();
|
||||||
|
monitoringManager.setup();
|
||||||
|
monitoringManager.start();
|
||||||
|
|
||||||
xTaskCreate(
|
xTaskCreate(
|
||||||
HandleStateManagerTask,
|
HandleStateManagerTask,
|
||||||
|
|||||||
69
sdkconfig
69
sdkconfig
@@ -514,9 +514,9 @@ CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y
|
|||||||
# CONFIG_ESPTOOLPY_NO_STUB is not set
|
# CONFIG_ESPTOOLPY_NO_STUB is not set
|
||||||
# CONFIG_ESPTOOLPY_OCT_FLASH is not set
|
# CONFIG_ESPTOOLPY_OCT_FLASH is not set
|
||||||
CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y
|
CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y
|
||||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set
|
# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set
|
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
|
||||||
# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
|
# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
|
||||||
CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y
|
CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y
|
||||||
CONFIG_ESPTOOLPY_FLASHMODE="dio"
|
CONFIG_ESPTOOLPY_FLASHMODE="dio"
|
||||||
@@ -527,13 +527,13 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
|||||||
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
CONFIG_ESPTOOLPY_FLASHSIZE="8MB"
|
||||||
# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
|
# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
|
||||||
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
||||||
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
||||||
@@ -571,7 +571,7 @@ CONFIG_ENV_GPIO_OUT_RANGE_MAX=48
|
|||||||
# OpenIris: General Configuration
|
# OpenIris: General Configuration
|
||||||
#
|
#
|
||||||
# CONFIG_START_IN_UVC_MODE is not set
|
# CONFIG_START_IN_UVC_MODE is not set
|
||||||
CONFIG_GENERAL_DEFAULT_WIRED_MODE=y
|
CONFIG_GENERAL_INCLUDE_UVC_MODE=y
|
||||||
CONFIG_GENERAL_UVC_DELAY=30
|
CONFIG_GENERAL_UVC_DELAY=30
|
||||||
# end of OpenIris: General Configuration
|
# end of OpenIris: General Configuration
|
||||||
|
|
||||||
@@ -596,32 +596,43 @@ CONFIG_WIFI_AP_PASSWORD="12345678"
|
|||||||
# OpenIris: LED Configuration
|
# OpenIris: LED Configuration
|
||||||
#
|
#
|
||||||
CONFIG_LED_BLINK_GPIO=8
|
CONFIG_LED_BLINK_GPIO=8
|
||||||
CONFIG_LED_EXTERNAL_GPIO=1
|
CONFIG_LED_EXTERNAL_GPIO=9
|
||||||
CONFIG_LED_EXTERNAL_CONTROL=y
|
CONFIG_LED_EXTERNAL_CONTROL=y
|
||||||
CONFIG_LED_EXTERNAL_PWM_FREQ=5000
|
CONFIG_LED_EXTERNAL_PWM_FREQ=20000
|
||||||
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100
|
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100
|
||||||
# end of OpenIris: LED Configuration
|
# end of OpenIris: LED Configuration
|
||||||
|
|
||||||
|
#
|
||||||
|
# OpenIris: Monitoring
|
||||||
|
#
|
||||||
|
CONFIG_MONITORING_LED_CURRENT=y
|
||||||
|
CONFIG_MONITORING_LED_ADC_GPIO=3
|
||||||
|
CONFIG_MONITORING_LED_GAIN=11
|
||||||
|
CONFIG_MONITORING_LED_SHUNT_MILLIOHM=22000
|
||||||
|
CONFIG_MONITORING_LED_SAMPLES=10
|
||||||
|
CONFIG_MONITORING_LED_INTERVAL_MS=500
|
||||||
|
# end of OpenIris: Monitoring
|
||||||
|
|
||||||
#
|
#
|
||||||
# Camera sensor pinout configuration
|
# Camera sensor pinout configuration
|
||||||
#
|
#
|
||||||
CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3"
|
CONFIG_CAMERA_MODULE_NAME="FaceFocusVR_Face"
|
||||||
CONFIG_PWDN_GPIO_NUM=-1
|
CONFIG_PWDN_GPIO_NUM=-1
|
||||||
CONFIG_RESET_GPIO_NUM=-1
|
CONFIG_RESET_GPIO_NUM=-1
|
||||||
CONFIG_XCLK_GPIO_NUM=4
|
CONFIG_XCLK_GPIO_NUM=10
|
||||||
CONFIG_SIOD_GPIO_NUM=48
|
CONFIG_SIOD_GPIO_NUM=40
|
||||||
CONFIG_SIOC_GPIO_NUM=47
|
CONFIG_SIOC_GPIO_NUM=39
|
||||||
CONFIG_Y9_GPIO_NUM=13
|
CONFIG_Y9_GPIO_NUM=48
|
||||||
CONFIG_Y8_GPIO_NUM=5
|
CONFIG_Y8_GPIO_NUM=11
|
||||||
CONFIG_Y7_GPIO_NUM=6
|
CONFIG_Y7_GPIO_NUM=12
|
||||||
CONFIG_Y6_GPIO_NUM=15
|
CONFIG_Y6_GPIO_NUM=14
|
||||||
CONFIG_Y5_GPIO_NUM=17
|
CONFIG_Y5_GPIO_NUM=16
|
||||||
CONFIG_Y4_GPIO_NUM=8
|
CONFIG_Y4_GPIO_NUM=18
|
||||||
CONFIG_Y3_GPIO_NUM=18
|
CONFIG_Y3_GPIO_NUM=17
|
||||||
CONFIG_Y2_GPIO_NUM=16
|
CONFIG_Y2_GPIO_NUM=15
|
||||||
CONFIG_VSYNC_GPIO_NUM=21
|
CONFIG_VSYNC_GPIO_NUM=38
|
||||||
CONFIG_HREF_GPIO_NUM=14
|
CONFIG_HREF_GPIO_NUM=47
|
||||||
CONFIG_PCLK_GPIO_NUM=7
|
CONFIG_PCLK_GPIO_NUM=13
|
||||||
# end of Camera sensor pinout configuration
|
# end of Camera sensor pinout configuration
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1156,21 +1167,19 @@ CONFIG_SPIRAM=y
|
|||||||
#
|
#
|
||||||
# SPI RAM config
|
# SPI RAM config
|
||||||
#
|
#
|
||||||
CONFIG_SPIRAM_MODE_QUAD=y
|
# CONFIG_SPIRAM_MODE_QUAD is not set
|
||||||
# CONFIG_SPIRAM_MODE_OCT is not set
|
CONFIG_SPIRAM_MODE_OCT=y
|
||||||
CONFIG_SPIRAM_TYPE_AUTO=y
|
CONFIG_SPIRAM_TYPE_AUTO=y
|
||||||
# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set
|
|
||||||
# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
|
|
||||||
# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
|
||||||
CONFIG_SPIRAM_CLK_IO=30
|
CONFIG_SPIRAM_CLK_IO=30
|
||||||
CONFIG_SPIRAM_CS_IO=26
|
CONFIG_SPIRAM_CS_IO=26
|
||||||
# CONFIG_SPIRAM_XIP_FROM_PSRAM is not set
|
# CONFIG_SPIRAM_XIP_FROM_PSRAM is not set
|
||||||
# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
|
# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
|
||||||
# CONFIG_SPIRAM_RODATA is not set
|
# CONFIG_SPIRAM_RODATA is not set
|
||||||
# CONFIG_SPIRAM_SPEED_120M is not set
|
|
||||||
CONFIG_SPIRAM_SPEED_80M=y
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
# CONFIG_SPIRAM_SPEED_40M is not set
|
# CONFIG_SPIRAM_SPEED_40M is not set
|
||||||
CONFIG_SPIRAM_SPEED=80
|
CONFIG_SPIRAM_SPEED=80
|
||||||
|
# CONFIG_SPIRAM_ECC_ENABLE is not set
|
||||||
CONFIG_SPIRAM_BOOT_INIT=y
|
CONFIG_SPIRAM_BOOT_INIT=y
|
||||||
CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y
|
CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y
|
||||||
# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
|
# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
|
||||||
@@ -2387,9 +2396,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
|
|||||||
CONFIG_LOG_BOOTLOADER_LEVEL=3
|
CONFIG_LOG_BOOTLOADER_LEVEL=3
|
||||||
# CONFIG_APP_ROLLBACK_ENABLE is not set
|
# CONFIG_APP_ROLLBACK_ENABLE is not set
|
||||||
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
|
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
|
||||||
CONFIG_FLASHMODE_QIO=y
|
# CONFIG_FLASHMODE_QIO is not set
|
||||||
# CONFIG_FLASHMODE_QOUT is not set
|
# CONFIG_FLASHMODE_QOUT is not set
|
||||||
# CONFIG_FLASHMODE_DIO is not set
|
CONFIG_FLASHMODE_DIO=y
|
||||||
# CONFIG_FLASHMODE_DOUT is not set
|
# CONFIG_FLASHMODE_DOUT is not set
|
||||||
CONFIG_MONITOR_BAUD=115200
|
CONFIG_MONITOR_BAUD=115200
|
||||||
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
|
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||||
|
|||||||
@@ -570,7 +570,7 @@ CONFIG_ENV_GPIO_OUT_RANGE_MAX=48
|
|||||||
#
|
#
|
||||||
# OpenIris: General Configuration
|
# OpenIris: General Configuration
|
||||||
#
|
#
|
||||||
# CONFIG_GENERAL_DEFAULT_WIRED_MODE is not set
|
# CONFIG_GENERAL_INCLUDE_UVC_MODE is not set
|
||||||
# CONFIG_START_IN_UVC_MODE is not set
|
# CONFIG_START_IN_UVC_MODE is not set
|
||||||
# CONFIG_GENERAL_UVC_DELAY is not set
|
# CONFIG_GENERAL_UVC_DELAY is not set
|
||||||
# end of OpenIris: General Configuration
|
# end of OpenIris: General Configuration
|
||||||
|
|||||||
@@ -59,5 +59,5 @@ CONFIG_LED_EXTERNAL_GPIO=9
|
|||||||
CONFIG_LED_EXTERNAL_PWM_FREQ=20000
|
CONFIG_LED_EXTERNAL_PWM_FREQ=20000
|
||||||
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=50
|
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=50
|
||||||
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
|
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
|
||||||
CONFIG_GENERAL_DEFAULT_WIRED_MODE=y
|
CONFIG_GENERAL_INCLUDE_UVC_MODE=y
|
||||||
CONFIG_START_IN_UVC_MODE=y
|
CONFIG_START_IN_UVC_MODE=y
|
||||||
@@ -59,5 +59,5 @@ CONFIG_LED_EXTERNAL_GPIO=9
|
|||||||
CONFIG_LED_EXTERNAL_PWM_FREQ=20000
|
CONFIG_LED_EXTERNAL_PWM_FREQ=20000
|
||||||
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100
|
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100
|
||||||
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
|
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
|
||||||
CONFIG_GENERAL_DEFAULT_WIRED_MODE=y
|
CONFIG_GENERAL_INCLUDE_UVC_MODE=y
|
||||||
CONFIG_START_IN_UVC_MODE=y
|
CONFIG_START_IN_UVC_MODE=y
|
||||||
@@ -51,5 +51,5 @@ CONFIG_LED_EXTERNAL_PWM_FREQ=5000
|
|||||||
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100
|
CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100
|
||||||
CONFIG_LED_EXTERNAL_GPIO=1
|
CONFIG_LED_EXTERNAL_GPIO=1
|
||||||
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
|
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
|
||||||
CONFIG_GENERAL_DEFAULT_WIRED_MODE=y
|
CONFIG_GENERAL_INCLUDE_UVC_MODE=y
|
||||||
# CONFIG_START_IN_UVC_MODE is not set
|
# CONFIG_START_IN_UVC_MODE is not set
|
||||||
@@ -56,5 +56,5 @@ CONFIG_SPIRAM_SPEED=80
|
|||||||
CONFIG_SPIRAM_SPEED_80M=y
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
# CONFIG_LED_EXTERNAL_CONTROL is not set
|
# CONFIG_LED_EXTERNAL_CONTROL is not set
|
||||||
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
|
CONFIG_CAMERA_USB_XCLK_FREQ=23000000
|
||||||
CONFIG_GENERAL_DEFAULT_WIRED_MODE=y
|
CONFIG_GENERAL_INCLUDE_UVC_MODE=y
|
||||||
# CONFIG_START_IN_UVC_MODE is not set
|
# CONFIG_START_IN_UVC_MODE is not set
|
||||||
@@ -378,7 +378,7 @@ class OpenIrisDevice:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def switch_mode(self, mode: str) -> bool:
|
def switch_mode(self, mode: str) -> bool:
|
||||||
"""Switch device mode between WiFi, UVC, and Auto"""
|
"""Switch device mode between WiFi, UVC, and Setup"""
|
||||||
print(f"🔄 Switching device mode to '{mode}'...")
|
print(f"🔄 Switching device mode to '{mode}'...")
|
||||||
|
|
||||||
params = {"mode": mode}
|
params = {"mode": mode}
|
||||||
@@ -906,7 +906,7 @@ def switch_device_mode(device: OpenIrisDevice, args = None):
|
|||||||
print("\n🔄 Select new device mode:")
|
print("\n🔄 Select new device mode:")
|
||||||
print("1. WiFi - Stream over WiFi connection")
|
print("1. WiFi - Stream over WiFi connection")
|
||||||
print("2. UVC - Stream as USB webcam")
|
print("2. UVC - Stream as USB webcam")
|
||||||
print("3. Auto - Automatic mode selection")
|
print("3. Setup - Configuration mode")
|
||||||
|
|
||||||
mode_choice = input("\nSelect mode (1-3): ").strip()
|
mode_choice = input("\nSelect mode (1-3): ").strip()
|
||||||
|
|
||||||
@@ -915,7 +915,7 @@ def switch_device_mode(device: OpenIrisDevice, args = None):
|
|||||||
elif mode_choice == "2":
|
elif mode_choice == "2":
|
||||||
device.switch_mode("uvc")
|
device.switch_mode("uvc")
|
||||||
elif mode_choice == "3":
|
elif mode_choice == "3":
|
||||||
device.switch_mode("auto")
|
device.switch_mode("setup")
|
||||||
else:
|
else:
|
||||||
print("❌ Invalid mode selection")
|
print("❌ Invalid mode selection")
|
||||||
|
|
||||||
@@ -980,6 +980,23 @@ def _probe_led_pwm(device: OpenIrisDevice) -> Dict:
|
|||||||
duty = device.get_led_duty_cycle()
|
duty = device.get_led_duty_cycle()
|
||||||
return {"led_external_pwm_duty_cycle": duty}
|
return {"led_external_pwm_duty_cycle": duty}
|
||||||
|
|
||||||
|
def _probe_led_current(device: OpenIrisDevice) -> Dict:
|
||||||
|
# Query device for current in mA via new command
|
||||||
|
resp = device.send_command("get_led_current")
|
||||||
|
if "error" in resp:
|
||||||
|
return {"led_current_ma": None, "error": resp["error"]}
|
||||||
|
try:
|
||||||
|
results = resp.get("results", [])
|
||||||
|
if results:
|
||||||
|
result_data = json.loads(results[0])
|
||||||
|
payload = result_data["result"]
|
||||||
|
if isinstance(payload, str):
|
||||||
|
payload = json.loads(payload)
|
||||||
|
return {"led_current_ma": float(payload.get("led_current_ma"))}
|
||||||
|
except Exception as e:
|
||||||
|
return {"led_current_ma": None, "error": str(e)}
|
||||||
|
return {"led_current_ma": None}
|
||||||
|
|
||||||
|
|
||||||
def _probe_mode(device: OpenIrisDevice) -> Dict:
|
def _probe_mode(device: OpenIrisDevice) -> Dict:
|
||||||
mode = device.get_device_mode()
|
mode = device.get_device_mode()
|
||||||
@@ -998,6 +1015,7 @@ def get_settings(device: OpenIrisDevice, args=None):
|
|||||||
probes = [
|
probes = [
|
||||||
("Identity", _probe_serial),
|
("Identity", _probe_serial),
|
||||||
("LED", _probe_led_pwm),
|
("LED", _probe_led_pwm),
|
||||||
|
("Current", _probe_led_current),
|
||||||
("Mode", _probe_mode),
|
("Mode", _probe_mode),
|
||||||
("WiFi", _probe_wifi_status),
|
("WiFi", _probe_wifi_status),
|
||||||
]
|
]
|
||||||
@@ -1035,6 +1053,17 @@ def get_settings(device: OpenIrisDevice, args=None):
|
|||||||
mode = summary.get("Mode", {}).get("mode")
|
mode = summary.get("Mode", {}).get("mode")
|
||||||
print(f"🎚️ Mode: {mode if mode else 'unknown'}")
|
print(f"🎚️ Mode: {mode if mode else 'unknown'}")
|
||||||
|
|
||||||
|
# Current
|
||||||
|
current = summary.get("Current", {}).get("led_current_ma")
|
||||||
|
if current is not None:
|
||||||
|
print(f"🔌 LED Current: {current:.3f} mA")
|
||||||
|
else:
|
||||||
|
err = summary.get("Current", {}).get("error")
|
||||||
|
if err:
|
||||||
|
print(f"🔌 LED Current: unavailable ({err})")
|
||||||
|
else:
|
||||||
|
print("🔌 LED Current: unavailable")
|
||||||
|
|
||||||
# WiFi
|
# WiFi
|
||||||
wifi = summary.get("WiFi", {}).get("wifi_status", {})
|
wifi = summary.get("WiFi", {}).get("wifi_status", {})
|
||||||
if wifi:
|
if wifi:
|
||||||
|
|||||||
Reference in New Issue
Block a user