Added options for camera

This commit is contained in:
Rene Zeldenthuis
2023-02-08 23:45:03 +01:00
parent 9b33b341c6
commit c5c4f87d47
3 changed files with 267 additions and 62 deletions

View File

@@ -3,9 +3,8 @@
#include <string.h> #include <string.h>
#include <esp_camera.h> #include <esp_camera.h>
typedef char camera_config_name_t[18]; typedef char camera_config_name_t[11];
typedef struct
typedef struct camera_config_entry
{ {
const camera_config_name_t name; const camera_config_name_t name;
const camera_config_t config; const camera_config_t config;
@@ -137,19 +136,94 @@ constexpr camera_config_t esp32cam_wrover_kit_settings = {
.fb_count = 2}; .fb_count = 2};
constexpr const camera_config_entry_t camera_configs[] = { constexpr const camera_config_entry_t camera_configs[] = {
{"ESP32CAM", esp32cam_settings}, {"ESP32CAM", esp32cam_settings},
{"AI THINKER", esp32cam_aithinker_settings}, {"AI THINKER", esp32cam_aithinker_settings},
{"TTGO T-CAM", esp32cam_ttgo_t_settings}, {"TTGO T-CAM", esp32cam_ttgo_t_settings},
{"M5 STACK", esp32cam_m5stack_settings}, {"M5 STACK", esp32cam_m5stack_settings},
{"WROVER KIT", esp32cam_wrover_kit_settings}}; {"WROVER KIT", esp32cam_wrover_kit_settings}};
const camera_config_t lookup_camera_config(const char *pin) const camera_config_t lookup_camera_config(const char *name)
{ {
// Lookup table for the frame name to framesize_t // Lookup table for the frame name to framesize_t
for (const auto &entry : camera_configs) for (const auto &entry : camera_configs)
if (strncmp(entry.name, pin, sizeof(camera_config_name_t)) == 0) if (strncmp(entry.name, name, sizeof(camera_config_name_t)) == 0)
return entry.config; return entry.config;
return camera_config_t{}; return camera_config_t{};
} }
typedef char camera_effect_name_t[11];
typedef struct
{
const camera_effect_name_t name;
const int value;
} camera_effect_entry_t;
constexpr const camera_effect_entry_t camera_effects[] = {
{"Normal", 0},
{"Negative", 1},
{"Grayscale", 2},
{"Red tint", 3},
{"Green tint", 4},
{"Blue tint", 5},
{"Sepia", 6}};
const int lookup_camera_effect(const char *name)
{
// Lookup table for the frame name to framesize_t
for (const auto &entry : camera_effects)
if (strncmp(entry.name, name, sizeof(camera_effect_entry_t)) == 0)
return entry.value;
return 0;
}
typedef char camera_white_balance_mode_name_t[7];
typedef struct
{
const camera_white_balance_mode_name_t name;
const int value;
} camera_white_balance_mode_entry_t;
constexpr const camera_white_balance_mode_entry_t camera_white_balance_modes[] = {
{"Auto", 0},
{"Sunny", 1},
{"Cloudy", 2},
{"Office", 3},
{"Home", 4}};
const int lookup_camera_white_balance_mode(const char *name)
{
// Lookup table for the frame name to framesize_t
for (const auto &entry : camera_white_balance_modes)
if (strncmp(entry.name, name, sizeof(camera_white_balance_mode_entry_t)) == 0)
return entry.value;
return 0;
}
typedef char camera_gain_ceiling_name_t[5];
typedef struct
{
const camera_gain_ceiling_name_t name;
const gainceiling_t value;
} camera_gain_ceiling_entry_t;
constexpr const camera_gain_ceiling_entry_t camera_gain_ceilings[] = {
{"2X", GAINCEILING_2X},
{"4X", GAINCEILING_4X},
{"8X", GAINCEILING_8X},
{"16X", GAINCEILING_16X},
{"32X", GAINCEILING_32X},
{"64X", GAINCEILING_64X},
{"128X", GAINCEILING_128X}};
const gainceiling_t lookup_camera_gain_ceiling_mode(const char *name)
{
// Lookup table for the frame name to framesize_t
for (const auto &entry : camera_gain_ceilings)
if (strncmp(entry.name, name, sizeof(camera_gain_ceiling_entry_t)) == 0)
return entry.value;
return GAINCEILING_2X;
}

View File

@@ -5,14 +5,39 @@
#define WIFI_SSID "ESP32CAM-RTSP" #define WIFI_SSID "ESP32CAM-RTSP"
#define WIFI_PASSWORD nullptr #define WIFI_PASSWORD nullptr
#define CONFIG_VERSION "1.3" #define CONFIG_VERSION "1._4"
#define OTA_PASSWORD "ESP32CAM-RTSP" #define OTA_PASSWORD "ESP32CAM-RTSP"
#define RTSP_PORT 554 #define RTSP_PORT 554
#define DEFAULT_CAMERA_CONFIG "AI THINKER" #define DEFAULT_CAMERA_CONFIG "AI THINKER"
#define DEFAULT_FRAME_DURATION "20" #define DEFAULT_FRAME_DURATION 20
#define DEFAULT_FRAME_BUFFERS "2" #define DEFAULT_FRAME_BUFFERS 2
#define DEFAULT_FRAME_SIZE "SVGA (800x600)" #define DEFAULT_FRAME_SIZE "SVGA (800x600)"
#define DEFAULT_JPEG_QUALITY "12" #define DEFAULT_JPEG_QUALITY 12
#define DEFAULT_LIGHT_INTENSITY "1"
#define DEFAULT_BRIGHTNESS 0
#define DEFAULT_CONTRAST 0
#define DEFAULT_SATURATION 0
#define DEFAULT_EFFECT "Normal"
#define DEFAULT_WHITE_BALANCE true
#define DEFAULT_WHITE_BALANCE_GAIN true
#define DEFAULT_WHITE_BALANCE_MODE "Auto"
#define DEFAULT_EXPOSURE_CONTROL true
#define DEFAULT_AEC2 true
#define DEFAULT_AE_LEVEL 0
#define DEFAULT_AEC_VALUE 300
#define DEFAULT_GAIN_CONTROL true
#define DEFAULT_AGC_GAIN 0
#define DEFAULT_GAIN_CEILING "2X"
#define DEFAULT_BPC false
#define DEFAULT_WPC true
#define DEFAULT_RAW_GAMMA true
#define DEFAULT_LENC true
#define DEFAULT_HORIZONTAL_MIRROR false
#define DEFAULT_VERTICAL_MIRROR false
#define DEFAULT_DCW true
#define DEFAULT_COLORBAR false
#define DEFAULT_LED_INTENSITY 0

View File

@@ -15,20 +15,39 @@
#include <html_data_gzip.h> #include <html_data_gzip.h>
#include <settings.h> #include <settings.h>
char camera_config_val[sizeof(camera_config_entry)]; auto param_group_board = iotwebconf::ParameterGroup("board", "Board settings");
char frame_duration_val[6]; auto param_board = iotwebconf::Builder<iotwebconf::SelectTParameter<sizeof(camera_configs[0])>>("bt").label("Board").optionValues((const char *)&camera_configs).optionNames((const char *)&camera_configs).optionCount(sizeof(camera_configs) / sizeof(camera_configs[0])).nameLength(sizeof(camera_configs[0])).defaultValue(DEFAULT_CAMERA_CONFIG).build();
char frame_size_val[sizeof(frame_size_entry_t)];
char frame_buffers_val[3];
char jpeg_quality_val[4];
char flash_led_intensity_val[4];
auto config_group_stream_settings = iotwebconf::ParameterGroup("settings", "Streaming settings"); auto param_group_camera = iotwebconf::ParameterGroup("camera", "Camera settings");
auto config_camera_config = iotwebconf::SelectParameter("Camera config", "config", camera_config_val, sizeof(camera_config_val), (const char *)camera_configs, (const char *)camera_configs, sizeof(camera_configs) / sizeof(camera_configs[0]), sizeof(camera_configs[0]), DEFAULT_CAMERA_CONFIG); auto param_frame_duration = iotwebconf::Builder<iotwebconf::UIntTParameter<unsigned long>>("fd").label("Frame duration (ms)").defaultValue(DEFAULT_FRAME_DURATION).min(10).build();
auto config_frame_rate = iotwebconf::NumberParameter("Frame duration (ms)", "fd", frame_duration_val, sizeof(frame_duration_val), DEFAULT_FRAME_DURATION, nullptr, "min=\"10\""); auto param_frame_size = iotwebconf::Builder<iotwebconf::SelectTParameter<sizeof(frame_sizes[0])>>("fs").label("Frame size").optionValues((const char *)&frame_sizes).optionNames((const char *)&frame_sizes).optionCount(sizeof(frame_sizes) / sizeof(frame_sizes[0])).nameLength(sizeof(frame_sizes[0])).defaultValue(DEFAULT_FRAME_SIZE).build();
auto config_frame_size = iotwebconf::SelectParameter("Frame size", "fs", frame_size_val, sizeof(frame_size_val), (const char *)frame_sizes, (const char *)frame_sizes, sizeof(frame_sizes) / sizeof(frame_sizes[0]), sizeof(frame_sizes[0]), DEFAULT_FRAME_SIZE); auto param_frame_buffers = iotwebconf::Builder<iotwebconf::UIntTParameter<byte>>("fb").label("Frame buffers").defaultValue(DEFAULT_FRAME_BUFFERS).min(1).max(16).build();
auto config_frame_buffers = iotwebconf::NumberParameter("Frame buffers", "fb", frame_buffers_val, sizeof(frame_buffers_val), DEFAULT_FRAME_BUFFERS, nullptr, "min=\"1\" max=\"16\""); auto param_jpg_quality = iotwebconf::Builder<iotwebconf::UIntTParameter<byte>>("q").label("JPG quality").defaultValue(DEFAULT_JPEG_QUALITY).min(1).max(100).build();
auto config_jpg_quality = iotwebconf::NumberParameter("JPEG quality", "q", jpeg_quality_val, sizeof(jpeg_quality_val), DEFAULT_JPEG_QUALITY, nullptr, "min=\"1\" max=\"100\""); auto param_brightness = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("b").label("Brightness").defaultValue(DEFAULT_BRIGHTNESS).min(-2).max(2).build();
auto config_flash_led_intensity = iotwebconf::NumberParameter("Flash LED intensity", "li", flash_led_intensity_val, sizeof(flash_led_intensity_val), DEFAULT_LIGHT_INTENSITY, nullptr, "min=\"0\" max=\"100\""); auto param_contrast = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("c").label("Contrast").defaultValue(DEFAULT_CONTRAST).min(-2).max(2).build();
auto param_saturation = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("s").label("Saturation").defaultValue(DEFAULT_SATURATION).min(-2).max(2).build();
auto param_special_effect = iotwebconf::Builder<iotwebconf::SelectTParameter<sizeof(camera_effects[0])>>("e").label("Effect").optionValues((const char *)&camera_effects).optionNames((const char *)&camera_effects).optionCount(sizeof(camera_effects) / sizeof(camera_effects[0])).nameLength(sizeof(camera_effects[0])).defaultValue(DEFAULT_EFFECT).build();
auto param_white_balance = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("wb").label("White balance").defaultValue(DEFAULT_WHITE_BALANCE).build();
auto param_automatic_white_balance_gain = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("awbg").label("Automatic white balance gain").defaultValue(DEFAULT_WHITE_BALANCE_GAIN).build();
auto param_white_balance_mode = iotwebconf::Builder<iotwebconf::SelectTParameter<sizeof(camera_white_balance_modes[0])>>("wbm").label("White balance mode").optionValues((const char *)&camera_white_balance_modes).optionNames((const char *)&camera_white_balance_modes).optionCount(sizeof(camera_white_balance_modes) / sizeof(camera_white_balance_modes[0])).nameLength(sizeof(camera_white_balance_modes[0])).defaultValue(DEFAULT_WHITE_BALANCE_MODE).build();
auto param_exposure_control = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("ec").label("Exposure control").defaultValue(DEFAULT_EXPOSURE_CONTROL).build();
auto param_aec2 = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("aec2").label("AEC2").defaultValue(DEFAULT_AEC2).build();
auto param_ae_level = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("ael").label("AE level").defaultValue(DEFAULT_AE_LEVEL).min(-2).max(2).build();
auto param_aec_value = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("aecv").label("AEC value").defaultValue(DEFAULT_AEC_VALUE).min(9).max(1200).build();
auto param_gain_control = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("gc").label("Gain control").defaultValue(DEFAULT_GAIN_CONTROL).build();
auto param_agc_gain = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("agcg").label("AGC gain").defaultValue(DEFAULT_AGC_GAIN).min(0).max(30).build();
auto param_gain_ceiling = iotwebconf::Builder<iotwebconf::SelectTParameter<sizeof(camera_gain_ceilings[0])>>("gcl").label("Gain ceilings").optionValues((const char *)&camera_gain_ceilings).optionNames((const char *)&camera_gain_ceilings).optionCount(sizeof(camera_gain_ceilings) / sizeof(camera_gain_ceilings[0])).nameLength(sizeof(camera_gain_ceilings[0])).defaultValue(DEFAULT_GAIN_CEILING).build();
auto param_bpc = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("bpc").label("BPC").defaultValue(DEFAULT_BPC).build();
auto param_wpc = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("wpc").label("WPC").defaultValue(DEFAULT_WPC).build();
auto param_raw_gamma = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("rg").label("Raw gamma").defaultValue(DEFAULT_RAW_GAMMA).build();
auto param_lenc = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("lenc").label("LENC").defaultValue(DEFAULT_LENC).build();
auto param_horizontal_mirror = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("hm").label("Horizontal mirror").defaultValue(DEFAULT_HORIZONTAL_MIRROR).build();
auto param_vertical_flip = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("vm").label("Vertical mirror").defaultValue(DEFAULT_VERTICAL_MIRROR).build();
auto param_dcw = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("dcw").label("DCW").defaultValue(DEFAULT_DCW).build();
auto param_colorbar = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("cb").label("Colorbar").defaultValue(DEFAULT_COLORBAR).build();
auto param_group_peripheral = iotwebconf::ParameterGroup("io", "peripheral settings");
auto param_led_intensity = iotwebconf::Builder<iotwebconf::UIntTParameter<byte>>("li").label("LED intensity").defaultValue(DEFAULT_LED_INTENSITY).min(0).max(100).build();
// Camera // Camera
OV2640 cam; OV2640 cam;
@@ -100,16 +119,40 @@ void handle_root()
{"NetworkState.ApMode", String(iotWebConf.getState() == iotwebconf::NetworkState::ApMode)}, {"NetworkState.ApMode", String(iotWebConf.getState() == iotwebconf::NetworkState::ApMode)},
{"NetworkState.OnLine", String(iotWebConf.getState() == iotwebconf::NetworkState::OnLine)}, {"NetworkState.OnLine", String(iotWebConf.getState() == iotwebconf::NetworkState::OnLine)},
// Camera // Camera
{"CameraType", camera_config_val}, {"CameraType", String(param_board.value())},
{"FrameSize", frame_size_val}, {"FrameSize", String(param_frame_size.value())},
{"FrameDuration", frame_duration_val}, {"FrameDuration", String(param_frame_duration.value())},
{"FrameFrequency", String(1000.0 / atol(frame_duration_val), 1)}, {"FrameFrequency", String(1000.0 / param_frame_duration.value(), 1)},
{"FrameBufferLocation", psramFound() ? "PSRAM" : "DRAM)"}, {"FrameBufferLocation", psramFound() ? "PSRAM" : "DRAM)"},
{"FrameBuffers", frame_buffers_val}, {"FrameBuffers", String(param_frame_buffers.value())},
{"JpegQuality", jpeg_quality_val}, {"JpegQuality", String(param_jpg_quality.value())},
{"CameraInitialized", String(camera_init_result == ESP_OK)}, {"CameraInitialized", String(camera_init_result == ESP_OK)},
{"CameraInitResultText", esp_err_to_name(camera_init_result)}, {"CameraInitResultText", esp_err_to_name(camera_init_result)},
{"FlashLedIntensity", flash_led_intensity_val}, // Settings
{"Brightness", String(param_brightness.value())},
{"Contrast", String(param_contrast.value())},
{"Saturation", String(param_saturation.value())},
{"Effect", String(param_special_effect.value())},
{"WhiteBalance", String(param_white_balance.value())},
{"AutomaticWhiteBalancebGain", String(param_automatic_white_balance_gain.value())},
{"WhiteBalanceMode", String(param_white_balance_mode.value())},
{"ExposureControl", String(param_exposure_control.value())},
{"AEC2", String(param_aec2.value())},
{"AELevel", String(param_ae_level.value())},
{"AECValue", String(param_aec_value.value())},
{"GainControl", String(param_gain_control.value())},
{"AGCGain", String(param_agc_gain.value())},
{"GainCeiling", String(param_gain_ceiling.value())},
{"BPC", String(param_bpc.value())},
{"WPC", String(param_wpc.value())},
{"RawGamma", String(param_raw_gamma.value())},
{"LENC", String(param_lenc.value())},
{"HorizontalMirror", String(param_horizontal_mirror.value())},
{"VericalFlip", String(param_vertical_flip.value())},
{"WCW", String(param_dcw.value())},
{"ColorBar", String(param_colorbar.value())},
// LED
{"FlashLedIntensity", String(param_led_intensity.value())},
// RTSP // RTSP
{"RtspPort", String(RTSP_PORT)}}; {"RtspPort", String(RTSP_PORT)}};
@@ -150,7 +193,7 @@ void handle_snapshot()
} }
// Remove old images stored in the framebuffer // Remove old images stored in the framebuffer
auto frame_buffers = atoi(frame_buffers_val); auto frame_buffers = param_frame_buffers.value();
while (frame_buffers--) while (frame_buffers--)
cam.run(); cam.run();
@@ -179,10 +222,17 @@ void handle_flash()
} }
// If no value present, use value from config // If no value present, use value from config
auto value = web_server.hasArg("v") ? web_server.arg("v") : flash_led_intensity_val; if (web_server.hasArg("v"))
{
auto v = (uint8_t)min(web_server.arg("v").toInt(), 255L);
// If conversion fails, v = 0 // If conversion fails, v = 0
auto v = (uint8_t)min(value.toInt(), 255l);
analogWrite(LED_FLASH, v); analogWrite(LED_FLASH, v);
}
else
{
analogWrite(LED_FLASH, param_led_intensity.value());
}
web_server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); web_server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
web_server.send(200); web_server.send(200);
} }
@@ -191,44 +241,73 @@ void on_config_saved()
{ {
log_v("on_config_saved"); log_v("on_config_saved");
// Set flash led intensity // Set flash led intensity
analogWrite(LED_FLASH, atoi(flash_led_intensity_val)); analogWrite(LED_FLASH, param_led_intensity.value());
config_changed = true; config_changed = true;
} }
esp_err_t initialize_camera() esp_err_t initialize_camera()
{ {
log_v("initialize_camera"); log_v("initialize_camera");
log_i("Camera config: %s", camera_config_val); log_i("Camera config: %s", param_board.value());
auto camera_config = lookup_camera_config(camera_config_val); auto camera_config = lookup_camera_config(param_board.value());
log_i("Frame size: %s", frame_size_val); log_i("Frame size: %s", param_frame_size.value());
auto frame_size = lookup_frame_size(frame_size_val); auto frame_size = lookup_frame_size(param_frame_size.value());
log_i("Frame buffers: %s", frame_buffers_val); log_i("Frame buffers: %d", param_frame_buffers.value());
auto frame_buffers = atoi(frame_buffers_val); // auto frame_buffers = atoi(frame_buffers_val);
log_i("JPEG quality: %s", jpeg_quality_val); log_i("JPEG quality: %d", param_jpg_quality.value());
auto jpeg_quality = atoi(jpeg_quality_val); log_i("Frame duration: %d ms", param_frame_duration.value());
log_i("Frame rate: %s ms", frame_duration_val);
camera_config.frame_size = frame_size; camera_config.frame_size = frame_size;
camera_config.fb_count = frame_buffers; camera_config.fb_count = param_frame_buffers.value();
camera_config.fb_location = psramFound() ? CAMERA_FB_IN_PSRAM : CAMERA_FB_IN_DRAM; camera_config.fb_location = psramFound() ? CAMERA_FB_IN_PSRAM : CAMERA_FB_IN_DRAM;
camera_config.jpeg_quality = jpeg_quality; camera_config.jpeg_quality = param_jpg_quality.value();
return cam.init(camera_config); return cam.init(camera_config);
} }
void update_camera_settings()
{
auto camera = esp_camera_sensor_get();
camera->set_brightness(camera, param_brightness.value());
camera->set_contrast(camera, param_contrast.value());
camera->set_saturation(camera, param_saturation.value());
camera->set_special_effect(camera, lookup_camera_effect(param_special_effect.value()));
camera->set_whitebal(camera, param_white_balance.value());
camera->set_awb_gain(camera, param_automatic_white_balance_gain.value());
camera->set_wb_mode(camera, lookup_camera_white_balance_mode(param_white_balance_mode.value()));
camera->set_exposure_ctrl(camera, param_exposure_control.value());
camera->set_aec2(camera, param_aec2.value());
camera->set_ae_level(camera, param_ae_level.value());
camera->set_aec_value(camera, param_aec_value.value());
camera->set_gain_ctrl(camera, param_gain_control.value());
camera->set_agc_gain(camera, param_agc_gain.value());
camera->set_gainceiling(camera, lookup_camera_gain_ceiling_mode(param_gain_ceiling.value()));
camera->set_bpc(camera, param_bpc.value());
camera->set_wpc(camera, param_wpc.value());
camera->set_raw_gma(camera, param_raw_gamma.value());
camera->set_lenc(camera, param_lenc.value());
camera->set_hmirror(camera, param_horizontal_mirror.value());
camera->set_vflip(camera, param_vertical_flip.value());
camera->set_dcw(camera, param_dcw.value());
camera->set_colorbar(camera, param_colorbar.value());
}
void start_rtsp_server() void start_rtsp_server()
{ {
log_v("start_rtsp_server"); log_v("start_rtsp_server");
camera_init_result = initialize_camera(); camera_init_result = initialize_camera();
if (camera_init_result != ESP_OK) if (camera_init_result != ESP_OK)
{ {
log_e("Failed to initialize camera: 0x%0x. Type: %s, frame size: %s, frame buffers: %s, frame rate: %s ms, jpeg quality: %s", camera_init_result, camera_config_val, frame_size_val, frame_buffers_val, frame_duration_val, jpeg_quality_val); log_e("Failed to initialize camera: 0x%0x. Type: %s, frame size: %s, frame buffers: %d, frame rate: %d ms, jpeg quality: %d", camera_init_result, param_board.value(), param_frame_size.value(), param_frame_buffers.value(), param_frame_duration.value(), param_jpg_quality.value());
return; return;
} }
log_i("Camera initialized"); log_i("Camera initialized");
auto frame_rate = atol(frame_duration_val);
camera_server = std::unique_ptr<rtsp_server>(new rtsp_server(cam, frame_rate, RTSP_PORT)); update_camera_settings();
log_i("Camera settings updated");
camera_server = std::unique_ptr<rtsp_server>(new rtsp_server(cam, param_frame_duration.value(), RTSP_PORT));
// Add service to mDNS - rtsp // Add service to mDNS - rtsp
MDNS.addService("rtsp", "tcp", 554); MDNS.addService("rtsp", "tcp", 554);
} }
@@ -239,7 +318,7 @@ void on_connected()
// Turn LED off (has inverted logic GPIO33) => red LED off => connected // Turn LED off (has inverted logic GPIO33) => red LED off => connected
digitalWrite(LED_BUILTIN, true); digitalWrite(LED_BUILTIN, true);
// Set flash led intensity // Set flash led intensity
analogWrite(LED_FLASH, atoi(flash_led_intensity_val)); analogWrite(LED_FLASH, param_led_intensity.value());
// Start (OTA) Over The Air programming when connected // Start (OTA) Over The Air programming when connected
ArduinoOTA.begin(); ArduinoOTA.begin();
// Start the RTSP Server // Start the RTSP Server
@@ -268,13 +347,40 @@ void setup()
log_i("Free heap: %d bytes", ESP.getFreeHeap()); log_i("Free heap: %d bytes", ESP.getFreeHeap());
log_i("Starting " APP_TITLE "..."); log_i("Starting " APP_TITLE "...");
config_group_stream_settings.addItem(&config_camera_config); param_group_board.addItem(&param_board);
config_group_stream_settings.addItem(&config_frame_rate); iotWebConf.addParameterGroup(&param_group_board);
config_group_stream_settings.addItem(&config_frame_size);
config_group_stream_settings.addItem(&config_frame_buffers); param_group_camera.addItem(&param_frame_duration);
config_group_stream_settings.addItem(&config_jpg_quality); param_group_camera.addItem(&param_frame_size);
config_group_stream_settings.addItem(&config_flash_led_intensity); param_group_camera.addItem(&param_frame_buffers);
iotWebConf.addParameterGroup(&config_group_stream_settings); param_group_camera.addItem(&param_jpg_quality);
param_group_camera.addItem(&param_brightness);
param_group_camera.addItem(&param_contrast);
param_group_camera.addItem(&param_saturation);
param_group_camera.addItem(&param_special_effect);
param_group_camera.addItem(&param_white_balance);
param_group_camera.addItem(&param_automatic_white_balance_gain);
param_group_camera.addItem(&param_white_balance_mode);
param_group_camera.addItem(&param_exposure_control);
param_group_camera.addItem(&param_aec2);
param_group_camera.addItem(&param_ae_level);
param_group_camera.addItem(&param_aec_value);
param_group_camera.addItem(&param_gain_control);
param_group_camera.addItem(&param_agc_gain);
param_group_camera.addItem(&param_gain_ceiling);
param_group_camera.addItem(&param_bpc);
param_group_camera.addItem(&param_wpc);
param_group_camera.addItem(&param_raw_gamma);
param_group_camera.addItem(&param_lenc);
param_group_camera.addItem(&param_horizontal_mirror);
param_group_camera.addItem(&param_vertical_flip);
param_group_camera.addItem(&param_dcw);
param_group_camera.addItem(&param_colorbar);
iotWebConf.addParameterGroup(&param_group_camera);
param_group_peripheral.addItem(&param_led_intensity);
iotWebConf.addParameterGroup(&param_group_peripheral);
iotWebConf.getApTimeoutParameter()->visible = true; iotWebConf.getApTimeoutParameter()->visible = true;
iotWebConf.setConfigSavedCallback(on_config_saved); iotWebConf.setConfigSavedCallback(on_config_saved);
iotWebConf.setWifiConnectionCallback(on_connected); iotWebConf.setWifiConnectionCallback(on_connected);