Updating build system
38
README.md
@@ -30,15 +30,12 @@ This software supports the following ESP32-CAM (and alike) modules:
|
||||
- WROVER-KIT
|
||||
- M5STACK
|
||||
|
||||

|
||||
|
||||
The software provides a **configuration web server**, that can be used to:
|
||||
|
||||
- Provide information about the state of the device, wifi connection and camera,
|
||||
- Set the WiFi parameters,
|
||||
- Set the timeout for connecting to the access point,
|
||||
- Set an access password,
|
||||
- Select the board type,
|
||||
- Select the image size,
|
||||
- Select the frame rate,
|
||||
- Select the JPEG quality
|
||||
@@ -77,25 +74,30 @@ It advertises HTTP (port 80) and RTSP (port 554)
|
||||
- USB to Serial (TTL level) converter, piggyback board ESP32-CAM-MB or other way to connect to the device,
|
||||
- [**PlatformIO**](https://platformio.org/) software (free download)
|
||||
|
||||
## Boards
|
||||
|
||||
There are a lot of boards available that are all called ESP32-CAM.
|
||||
However, there are differences in CPU (type/speed/cores), how the camera is connected, presence of PSRAM or not...
|
||||
To select the right board use the table below and use the configuration that is listed below for your board:
|
||||
|
||||
| Board | Configuration | Image | CPU | RAM | Camera | Site |
|
||||
|--- |--- |--- |--- |--- |--- |--- |
|
||||
| Espressif ESP32-Wropver CAM | | <img src="assets/boards/esp32-wrover-cam.jpg" height="100" /> | ESP32 | 520KB SRAM 4MB PSRAM | OV2640 | |
|
||||
| AI-Thinker ESP32-CAM | ai_thinker_esp32cam | <img src="assets/boards/ai-thinker-esp32-cam-ipex.jpg" height="100" /> <img src="assets/boards/ai-thinker-esp32-cam.jpg" height="100" /> | ESP32-S / 160Mhz | 520KB SRAM 4MB PSRAM | OV2640 | https://docs.ai-thinker.com/en/esp32-cam |
|
||||
| Espressif ESP-EYE | | <img src="assets/boards/espressif-esp-eye.jpg" height="100" /> | ESP32 | 520KB SRAM 4MB PSRAM | OV2640 | |
|
||||
| Espressif ESP-S3-EYE| | <img src="assets/boards/espressif-esps3-eye.jpg" height="100" /> | ESP32-S3 | 520KB SRAM 4MB PSRAM | OV2640 | https://www.espressif.com/en/products/devkits/esp-eye/overview |
|
||||
| LilyGo camera module| | <img src="assets/boards/lilygo-camera-module.jpg" height="100" /> | ESP32 Wrover | 520KB SRAM 4MB PSRAM | OV2640 / OV5640
|
||||
| LilyGo Simcam| | <img src="assets/boards/lilygo-simcam.jpg" height="100" /> | | | OV2640 | |
|
||||
| LilyGo TTGO-T Camera| | <img src="assets/boards/lilygo-ttgo-t-camera.jpg" height="100" /> || | OV2640 | |
|
||||
| M5 Stack Camera| | <img src="assets/boards/m5stack-esp32-camera.jpg" height="100" /> ||| OV2640 | |
|
||||
| Seeed studio Xiao ESPS3 Sense| seeed_xiao_esp32s3_sense | <img src="assets/boards/seeed-studio-xiao-esp32s3-sense.jpg" height="100" /> | ESP32-S3 | 520KB SRAM 4MB PSRAM | OV2640 | |
|
||||
|
||||
## Installing and running PlatformIO
|
||||
|
||||
PlatformIO is available for all major operating systems: Windows, Linux and MacOS. It is also provided as a plugin to [Visual Studio Code](https://visualstudio.microsoft.com).
|
||||
More information can be found at: [https://docs.platformio.org/en/latest/installation.html](https://docs.platformio.org/en/latest/installation.html) below the basics.
|
||||
|
||||
### Debian based systems command-line install
|
||||
|
||||
Install platformIO
|
||||
|
||||
```sh
|
||||
sudo apt-get install python-pip
|
||||
sudo pip install platformio
|
||||
pio upgrade
|
||||
```
|
||||
|
||||
### Windows, Linux and MacOS
|
||||
|
||||
Install [**Visual Studio code**](https://code.visualstudio.com) and install the PlatformIO plugin.
|
||||
For command line usage Python and PlatformIO-Core is sufficient.
|
||||
Install [**Visual Studio Code**](https://code.visualstudio.com) and install the PlatformIO plugin.
|
||||
|
||||
## Putting the ESP32-CAM in download mode
|
||||
|
||||
@@ -284,7 +286,7 @@ Not all the boards are equipped with PSRAM:
|
||||
| ESP32CAM (USB-C) | No |
|
||||
| AI THINKER | Yes |
|
||||
| TTGO T-CAM | No |
|
||||
| M5 STACK| | No |
|
||||
| M5 STACK | No |
|
||||
| WROVER KIT | Yes |
|
||||
|
||||
Depending on the image resolution, framerate and quality, the PSRAM must be enabled and/or the number of frame buffers increased to keep up with the data generated by the sensor.
|
||||
|
||||
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 152 KiB |
BIN
assets/boards/ai-thinker-esp32-cam-ipex.jpg
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
assets/boards/ai-thinker-esp32-cam-mb.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
assets/boards/ai-thinker-esp32-cam.jpg
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
assets/boards/esp32-wrover-cam.jpg
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
assets/boards/espressif-esp-eye.jpg
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
assets/boards/espressif-esps3-eye.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
assets/boards/lilygo-camera-module.jpg
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
assets/boards/lilygo-simcam.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
assets/boards/lilygo-ttgo-t-camera.jpg
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
assets/boards/m5stack-esp32-camera.jpg
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
assets/boards/seeed-studio-xiao-esp32s3-sense.jpg
Normal file
|
After Width: | Height: | Size: 156 KiB |
@@ -1,5 +1,4 @@
|
||||
. python3 -m pip install --upgrade pip setuptools wheel
|
||||
. python3 -m pip install minify-html
|
||||
|
||||
. python3 ./minify.py ./html/index.html ./html/index.min.html
|
||||
. python3 ./minify.py ./html/restart.html ./html/restart.min.html
|
||||
. python3 ./minify.py ./html/index.html ./html/index.min.html
|
||||
@@ -3,5 +3,4 @@
|
||||
python3 -m pip install --upgrade pip setuptools wheel
|
||||
python3 -m pip install minify-html
|
||||
|
||||
python3 ./minify.py ./html/index.html ./html/index.min.html
|
||||
python3 ./minify.py ./html/restart.html ./html/restart.min.html
|
||||
python3 ./minify.py ./html/index.html ./html/index.min.html
|
||||
@@ -104,17 +104,11 @@
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{{#ConfigChanged}}
|
||||
<div class="alert alert-danger">
|
||||
<h3 class="text-center">
|
||||
The configuration has been changed.<br>
|
||||
It is recommended to restart the device.<br><br>
|
||||
<button type="button" class="btn btn-danger" onclick="location.href='restart'">Restart</button>
|
||||
</h3>
|
||||
</div>
|
||||
{{/ConfigChanged}}
|
||||
|
||||
<h2 class="text-center">ESP32</h2>
|
||||
<div class="flex-table">
|
||||
<div class="row">Board type:</div>
|
||||
<div>{{BoardType}}</div>
|
||||
<div class="row">SDK Version:</div>
|
||||
<div>{{SDKVersion}}</div>
|
||||
<div class="row">CPU model:</div>
|
||||
@@ -135,8 +129,6 @@
|
||||
<div class="flex-table">
|
||||
<div class="row">Uptime:</div>
|
||||
<div>{{Uptime}}</div>
|
||||
<div class="row">Chip temperature:</div>
|
||||
<div>{{Temperature}} °C</div>
|
||||
<div class="row">RTSP sessions:</div>
|
||||
<div>{{NumRTSPSessions}}</div>
|
||||
<div class="row">Free heap:</div>
|
||||
@@ -145,14 +137,6 @@
|
||||
<div>{{MaxAllocHeap}}</div>
|
||||
</div>
|
||||
|
||||
<h2 class="text-center">Peripheral</h2>
|
||||
<div class="flex-table">
|
||||
<div class="row">Board type:</div>
|
||||
<div>{{BoardType}}</div>
|
||||
<div class="row">LED intensity:</div>
|
||||
<div>{{LedIntensity}} [0-100]</div>
|
||||
</div>
|
||||
|
||||
<h2 class="text-center">Network</h2>
|
||||
<div class="flex-table">
|
||||
<div class="row">Host name:</div>
|
||||
@@ -191,10 +175,6 @@
|
||||
<div>{{FrameSize}}</div>
|
||||
<div class="row">JPEG quality:</div>
|
||||
<div>{{JpegQuality}} [1-100]</div>
|
||||
<div class="row">Enable PSRAM:</div>
|
||||
<div>{{#EnablePSRAM}}Enabled{{/EnablePSRAM}}{{^EnablePSRAM}}Disabled{{/EnablePSRAM}}</div>
|
||||
<div class="row">Number of frame buffers:</div>
|
||||
<div>{{FrameBuffers}}</div>
|
||||
<div class="row">Brightness:</div>
|
||||
<div>{{Brightness}} [-2,2]</div>
|
||||
<div class="row">Contrast:</div>
|
||||
@@ -262,13 +242,9 @@
|
||||
<div class="row">RTSP camera stream:</div>
|
||||
<div><a href="rtsp://{{IpV4}}:{{RtspPort}}/mjpeg/1">rtsp://{{IpV4}}:{{RtspPort}}/mjpeg/1</a></div>
|
||||
<div class="row">JPEG Motion stream:</div>
|
||||
<div><a href="http://{{IpV4}}/stream" target="_blank">http://{{IpV4}}/stream</a></div>
|
||||
<div><a href="http://{{IpV4}}/stream" target="_blank" rel="noopener">http://{{IpV4}}/stream</a></div>
|
||||
<div class="row">Snapshot of the camera:</div>
|
||||
<div><a href="http://{{IpV4}}/snapshot " target="_blank">http://{{IpV4}}/snapshot</a> </div>
|
||||
<div class="row">Intensity of the flash led (0-255):</div>
|
||||
<div><a href="http: //{{IpV4}}/flash?v=0">http://{{IpV4}}/flash?v=0</a> (Authentication required)</div>
|
||||
<div class="row">Restart the camera:</div>
|
||||
<div><a href="http://{{IpV4}}/restart">http://{{IpV4}}/restart</a> (Authentication required)</div>
|
||||
<div><a href="http://{{IpV4}}/snapshot " target="_blank" rel="noopener">http://{{IpV4}}/snapshot</a> </div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="refresh" content="10;url=/index.html">
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
color: #222;
|
||||
font-size: 16px;
|
||||
font-family: Arial, Verdana, Helvetica, sans-serif;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
color: #31708f;
|
||||
background-color: #d9edf7;
|
||||
border-color: #bce8f1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<title>{{AppTitle}} v{{AppVersion}}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 class="text-center">{{ThingName}}</h1>
|
||||
<hr>
|
||||
|
||||
<div class="alert-info">
|
||||
<h3 class="text-center">Restarting</h3>
|
||||
<h4 class="text-center">
|
||||
The device is restarting...<br><br>
|
||||
If this page takes longer than a minute, consider performing a power cycle.
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
<!doctypehtml><html lang=en><meta charset=utf-8><meta content=width=device-width,initial-scale=1,shrink-to-fit=no name=viewport><meta content=10;url=/index.html http-equiv=refresh><style>body,html{color:#222;font-size:16px;font-family:Arial,Verdana,Helvetica,sans-serif;min-height:100%}.text-center{text-align:center}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}</style><title>{{AppTitle}} v{{AppVersion}}</title><body><h1 class=text-center>{{ThingName}}</h1><hr><div class=alert-info><h3 class=text-center>Restarting</h3><h4 class=text-center>The device is restarting...<br><br> If this page takes longer than a minute, consider performing a power cycle.</h4></div>
|
||||
@@ -1,15 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include <esp_camera.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char name[17];
|
||||
const camera_config_t config;
|
||||
} camera_config_entry_t;
|
||||
|
||||
constexpr camera_config_t esp32cam_settings = {
|
||||
constexpr camera_config_t esp32cam_camera_settings = {
|
||||
.pin_pwdn = -1,
|
||||
.pin_reset = 15,
|
||||
.pin_xclk = 27,
|
||||
@@ -32,10 +25,38 @@ constexpr camera_config_t esp32cam_settings = {
|
||||
.pixel_format = PIXFORMAT_JPEG,
|
||||
.frame_size = FRAMESIZE_SVGA,
|
||||
.jpeg_quality = 12,
|
||||
.fb_count = 2,
|
||||
.grab_mode = CAMERA_GRAB_WHEN_EMPTY};
|
||||
.fb_count = 1,
|
||||
.fb_location = CAMERA_FB_IN_DRAM,
|
||||
.grab_mode = CAMERA_GRAB_LATEST};
|
||||
|
||||
constexpr camera_config_t esp32cam_aithinker_settings = {
|
||||
constexpr camera_config_t esp_eye_camera_settings = {
|
||||
.pin_pwdn = -1,
|
||||
.pin_reset = -1,
|
||||
.pin_xclk = 4,
|
||||
.pin_sscb_sda = 18,
|
||||
.pin_sscb_scl = 23,
|
||||
.pin_d7 = 36,
|
||||
.pin_d6 = 37,
|
||||
.pin_d5 = 38,
|
||||
.pin_d4 = 39,
|
||||
.pin_d3 = 35,
|
||||
.pin_d2 = 14,
|
||||
.pin_d1 = 13,
|
||||
.pin_d0 = 34,
|
||||
.pin_vsync = 5,
|
||||
.pin_href = 27,
|
||||
.pin_pclk = 25,
|
||||
.xclk_freq_hz = 20000000,
|
||||
.ledc_timer = LEDC_TIMER_0,
|
||||
.ledc_channel = LEDC_CHANNEL_0,
|
||||
.pixel_format = PIXFORMAT_JPEG,
|
||||
.frame_size = FRAMESIZE_SVGA,
|
||||
.jpeg_quality = 12,
|
||||
.fb_count = 1,
|
||||
.fb_location = CAMERA_FB_IN_DRAM,
|
||||
.grab_mode = CAMERA_GRAB_LATEST};
|
||||
|
||||
constexpr camera_config_t aithinker_camera_settings = {
|
||||
.pin_pwdn = 32,
|
||||
.pin_reset = -1,
|
||||
.pin_xclk = 0,
|
||||
@@ -59,9 +80,10 @@ constexpr camera_config_t esp32cam_aithinker_settings = {
|
||||
.frame_size = FRAMESIZE_SVGA,
|
||||
.jpeg_quality = 12,
|
||||
.fb_count = 2,
|
||||
.grab_mode = CAMERA_GRAB_WHEN_EMPTY};
|
||||
.fb_location = CAMERA_FB_IN_PSRAM,
|
||||
.grab_mode = CAMERA_GRAB_LATEST};
|
||||
|
||||
constexpr camera_config_t esp32cam_ttgo_t_settings = {
|
||||
constexpr camera_config_t ttgo_t_camera_settings = {
|
||||
.pin_pwdn = 26,
|
||||
.pin_reset = -1,
|
||||
.pin_xclk = 32,
|
||||
@@ -84,10 +106,11 @@ constexpr camera_config_t esp32cam_ttgo_t_settings = {
|
||||
.pixel_format = PIXFORMAT_JPEG,
|
||||
.frame_size = FRAMESIZE_SVGA,
|
||||
.jpeg_quality = 12,
|
||||
.fb_count = 2,
|
||||
.grab_mode = CAMERA_GRAB_WHEN_EMPTY};
|
||||
.fb_count = 1,
|
||||
.fb_location = CAMERA_FB_IN_DRAM,
|
||||
.grab_mode = CAMERA_GRAB_LATEST};
|
||||
|
||||
constexpr camera_config_t esp32cam_m5stack_settings = {
|
||||
constexpr camera_config_t m5stack_camera_settings = {
|
||||
.pin_pwdn = -1,
|
||||
.pin_reset = 15,
|
||||
.pin_xclk = 27,
|
||||
@@ -110,10 +133,11 @@ constexpr camera_config_t esp32cam_m5stack_settings = {
|
||||
.pixel_format = PIXFORMAT_JPEG,
|
||||
.frame_size = FRAMESIZE_SVGA,
|
||||
.jpeg_quality = 12,
|
||||
.fb_count = 2,
|
||||
.grab_mode = CAMERA_GRAB_WHEN_EMPTY};
|
||||
.fb_count = 1,
|
||||
.fb_location = CAMERA_FB_IN_DRAM,
|
||||
.grab_mode = CAMERA_GRAB_LATEST};
|
||||
|
||||
constexpr camera_config_t esp32cam_wrover_kit_settings = {
|
||||
constexpr camera_config_t wrover_kit_camera_settings = {
|
||||
.pin_pwdn = -1,
|
||||
.pin_reset = -1,
|
||||
.pin_xclk = 21,
|
||||
@@ -137,9 +161,10 @@ constexpr camera_config_t esp32cam_wrover_kit_settings = {
|
||||
.frame_size = FRAMESIZE_SVGA,
|
||||
.jpeg_quality = 12,
|
||||
.fb_count = 2,
|
||||
.grab_mode = CAMERA_GRAB_WHEN_EMPTY};
|
||||
.fb_location = CAMERA_FB_IN_PSRAM,
|
||||
.grab_mode = CAMERA_GRAB_LATEST};
|
||||
|
||||
constexpr camera_config_t esp32cam_xiaoesp32s3_settings = {
|
||||
constexpr camera_config_t xiao_esp32s3_camera_settings = {
|
||||
.pin_pwdn = -1,
|
||||
.pin_reset = -1,
|
||||
.pin_xclk = 10,
|
||||
@@ -162,23 +187,6 @@ constexpr camera_config_t esp32cam_xiaoesp32s3_settings = {
|
||||
.pixel_format = PIXFORMAT_JPEG, // for streaming
|
||||
.frame_size = FRAMESIZE_UXGA,
|
||||
.jpeg_quality = 12,
|
||||
.fb_count = 1,
|
||||
.grab_mode = CAMERA_GRAB_WHEN_EMPTY};
|
||||
|
||||
constexpr const camera_config_entry_t camera_configs[] = {
|
||||
{"ESP32CAM", esp32cam_settings},
|
||||
{"ESP32CAM_XIAO_S3", esp32cam_xiaoesp32s3_settings},
|
||||
{"AI THINKER", esp32cam_aithinker_settings},
|
||||
{"TTGO T-CAM", esp32cam_ttgo_t_settings},
|
||||
{"M5 STACK", esp32cam_m5stack_settings},
|
||||
{"WROVER KIT", esp32cam_wrover_kit_settings}};
|
||||
|
||||
const camera_config_t lookup_camera_config(const char *name)
|
||||
{
|
||||
// Lookup table for the frame name to framesize_t
|
||||
for (const auto &entry : camera_configs)
|
||||
if (strncmp(entry.name, name, sizeof(entry.name)) == 0)
|
||||
return entry.config;
|
||||
|
||||
return camera_config_t{};
|
||||
}
|
||||
.fb_count = 2,
|
||||
.fb_location = CAMERA_FB_IN_PSRAM,
|
||||
.grab_mode = CAMERA_GRAB_LATEST};
|
||||
@@ -5,23 +5,45 @@
|
||||
|
||||
#define WIFI_SSID "ESP32CAM-RTSP"
|
||||
#define WIFI_PASSWORD nullptr
|
||||
#define CONFIG_VERSION "1.5"
|
||||
#define CONFIG_VERSION "1.6"
|
||||
|
||||
#define OTA_PASSWORD "ESP32CAM-RTSP"
|
||||
|
||||
#define RTSP_PORT 554
|
||||
|
||||
#define DEFAULT_CAMERA_CONFIG "AI THINKER"
|
||||
#define DEFAULT_ENABLE_PSRAM psramFound()
|
||||
#define DEFAULT_BUFFERS (psramFound() ? 2 : 1)
|
||||
#if defined(BOARD_ESP32CAM)
|
||||
constexpr const char *board_name = "ESP32CAM";
|
||||
constexpr camera_config_t default_camera_config = esp32cam_camera_settings;
|
||||
#elif defined(BOARD_AITHINKER_ESP32CAM)
|
||||
constexpr const char *board_name = "AI-Thinker ESP32CAM";
|
||||
constexpr camera_config_t default_camera_config = aithinker_camera_settings;
|
||||
#elif defined(BOARD_ESP_EYE)
|
||||
constexpr const char *board_name = "ESP-EYE";
|
||||
constexpr camera_config_t default_camera_config = exp_eye_camera_settings;
|
||||
#elif defined(BOARD_TTGO_T_CAMERA)
|
||||
constexpr const char *board_name = "TTGO-T-CAMERA";
|
||||
constexpr camera_config_t default_camera_config = ttgo_t_camera_settings;
|
||||
#elif defined(BOARD_M5STACK_ESP32CAM)
|
||||
constexpr const char *board_name = "M5STACK-CAMERA";
|
||||
constexpr camera_config_t default_camera_config = m5stack_camera_settings;
|
||||
#elif defined(BOARD_ESP32_WROVER_CAM)
|
||||
constexpr const char *board_name = "WROVER-KIT";
|
||||
constexpr camera_config_t default_camera_config = wrover_kit_camera_settings;
|
||||
#elif defined(BOARD_SEEED_XIAO_ESP32S3_SENSE)
|
||||
constexpr const char *board_name = "Seed Xiao ESP32S3 Sense";
|
||||
constexpr camera_config_t default_camera_config = xiao_esp32s3_camera_settings;
|
||||
#elif
|
||||
#error No board defined
|
||||
#endif
|
||||
|
||||
#define DEFAULT_FRAME_DURATION 200
|
||||
#define DEFAULT_FRAME_SIZE "VGA (640x480)"
|
||||
#define DEFAULT_JPEG_QUALITY (psramFound() ? 12 : 14)
|
||||
|
||||
#define DEFAULT_BRIGHTNESS 0
|
||||
#define DEFAULT_CONTRAST 0
|
||||
#define DEFAULT_SATURATION 0
|
||||
#define DEFAULT_EFFECT "Normal"
|
||||
#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"
|
||||
|
||||
@@ -29,7 +29,7 @@ private:
|
||||
std::shared_ptr<CRtspSession> session;
|
||||
};
|
||||
|
||||
OV2640 cam_;
|
||||
OV2640 cam_;
|
||||
std::list<std::unique_ptr<rtsp_client>> clients_;
|
||||
uintptr_t task_;
|
||||
Timer<> timer_;
|
||||
|
||||
195
platformio.ini
@@ -8,15 +8,15 @@
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
###############################################################################
|
||||
[env:esp32cam]
|
||||
platform = espressif32
|
||||
board = esp32cam
|
||||
framework = arduino
|
||||
|
||||
#upload_protocol = espota
|
||||
#upload_port = 192.168.50.222
|
||||
#upload_flags =
|
||||
# --auth='ESP32CAM-RTSP'
|
||||
#upload_port = 192.168.178.223
|
||||
#upload_flags = --auth='ESP32CAM-RTSP'
|
||||
|
||||
# Partition scheme for OTA
|
||||
board_build.partitions = min_spiffs.csv
|
||||
@@ -28,28 +28,30 @@ monitor_filters = log2file, time, default, esp32_exception_decoder
|
||||
|
||||
build_flags =
|
||||
-O2
|
||||
-D BOARD_ESP32CAM
|
||||
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
-D LED_FLASH=4
|
||||
-D LED_BUILTIN=33
|
||||
-D BOARD_HAS_PSRAM
|
||||
-D TEMPRATURE_SENS_READ
|
||||
-mfix-esp32-psram-cache-issue
|
||||
-D IOTWEBCONF_PASSWORD_LEN=64
|
||||
|
||||
board_build.embed_txtfiles =
|
||||
html/index.min.html
|
||||
html/restart.min.html
|
||||
|
||||
lib_deps =
|
||||
prampec/IotWebConf @ ^3.2.1
|
||||
geeksville/Micro-RTSP @ ^0.1.6
|
||||
rzeldent/micro-moustache@^1.0.1
|
||||
|
||||
[env:seeed_xiao_esp32s3]
|
||||
###############################################################################
|
||||
[env:ai_thinker_esp32cam]
|
||||
platform = espressif32
|
||||
board = esp32s3box
|
||||
board = esp32cam
|
||||
framework = arduino
|
||||
|
||||
#upload_protocol = espota
|
||||
#upload_port = 192.168.178.223
|
||||
#upload_flags = --auth='ESP32CAM-RTSP'
|
||||
|
||||
# Partition scheme for OTA
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
||||
@@ -60,16 +62,183 @@ monitor_filters = log2file, time, default, esp32_exception_decoder
|
||||
|
||||
build_flags =
|
||||
-O2
|
||||
-D BOARD_AITHINKER_ESP32CAM
|
||||
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
-D LED_BUILTIN=33
|
||||
-mfix-esp32-psram-cache-issue
|
||||
-D IOTWEBCONF_PASSWORD_LEN=64
|
||||
|
||||
board_build.embed_txtfiles =
|
||||
html/index.min.html
|
||||
|
||||
lib_deps =
|
||||
prampec/IotWebConf @ ^3.2.1
|
||||
geeksville/Micro-RTSP @ ^0.1.6
|
||||
rzeldent/micro-moustache@^1.0.1
|
||||
|
||||
###############################################################################
|
||||
[env:esp_eye]
|
||||
platform = espressif32
|
||||
board = esp32cam
|
||||
framework = arduino
|
||||
|
||||
#upload_protocol = espota
|
||||
#upload_port = 192.168.178.223
|
||||
#upload_flags = --auth='ESP32CAM-RTSP'
|
||||
|
||||
# Partition scheme for OTA
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
monitor_filters = log2file, time, default, esp32_exception_decoder
|
||||
|
||||
build_flags =
|
||||
-O2
|
||||
-D BOARD_ESP_EYE
|
||||
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
-D LED_BUILTIN=33
|
||||
-mfix-esp32-psram-cache-issue
|
||||
-D IOTWEBCONF_PASSWORD_LEN=64
|
||||
|
||||
board_build.embed_txtfiles =
|
||||
html/index.min.html
|
||||
|
||||
lib_deps =
|
||||
prampec/IotWebConf @ ^3.2.1
|
||||
geeksville/Micro-RTSP @ ^0.1.6
|
||||
rzeldent/micro-moustache@^1.0.1
|
||||
|
||||
###############################################################################
|
||||
[env:ttgo_t_camers]
|
||||
platform = espressif32
|
||||
board = ttgo-t-beam
|
||||
framework = arduino
|
||||
|
||||
#upload_protocol = espota
|
||||
#upload_port = 192.168.178.223
|
||||
#upload_flags = --auth='ESP32CAM-RTSP'
|
||||
|
||||
# Partition scheme for OTA
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
monitor_filters = log2file, time, default, esp32_exception_decoder
|
||||
|
||||
build_flags =
|
||||
-O2
|
||||
-D BOARD_TTGO_T_CAMERA
|
||||
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
-D LED_BUILTIN=33
|
||||
-mfix-esp32-psram-cache-issue
|
||||
-D IOTWEBCONF_PASSWORD_LEN=64
|
||||
|
||||
board_build.embed_txtfiles =
|
||||
html/index.min.html
|
||||
|
||||
lib_deps =
|
||||
prampec/IotWebConf @ ^3.2.1
|
||||
geeksville/Micro-RTSP @ ^0.1.6
|
||||
rzeldent/micro-moustache@^1.0.1
|
||||
|
||||
###############################################################################
|
||||
[env:m5stack_esp32cam]
|
||||
platform = espressif32
|
||||
board = m5stack-core-esp32
|
||||
framework = arduino
|
||||
|
||||
#upload_protocol = espota
|
||||
#upload_port = 192.168.178.223
|
||||
#upload_flags = --auth='ESP32CAM-RTSP'
|
||||
|
||||
# Partition scheme for OTA
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
monitor_filters = log2file, time, default, esp32_exception_decoder
|
||||
|
||||
build_flags =
|
||||
-O2
|
||||
-D BOARD_M5STACK_ESP32CAM
|
||||
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
-D LED_BUILTIN=33
|
||||
-mfix-esp32-psram-cache-issue
|
||||
-D IOTWEBCONF_PASSWORD_LEN=64
|
||||
|
||||
board_build.embed_txtfiles =
|
||||
html/index.min.html
|
||||
|
||||
lib_deps =
|
||||
prampec/IotWebConf @ ^3.2.1
|
||||
geeksville/Micro-RTSP @ ^0.1.6
|
||||
rzeldent/micro-moustache@^1.0.1
|
||||
|
||||
###############################################################################
|
||||
[env:esp32_wrover_cam]
|
||||
platform = espressif32
|
||||
board = esp-wrover-kit
|
||||
framework = arduino
|
||||
|
||||
#upload_protocol = espota
|
||||
#upload_port = 192.168.178.223
|
||||
#upload_flags = --auth='ESP32CAM-RTSP'
|
||||
|
||||
# Partition scheme for OTA
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
monitor_filters = log2file, time, default, esp32_exception_decoder
|
||||
|
||||
build_flags =
|
||||
-O2
|
||||
-D BOARD_ESP32_WROVER_CAM
|
||||
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
-D LED_BUILTIN=2
|
||||
-mfix-esp32-psram-cache-issue
|
||||
-D IOTWEBCONF_PASSWORD_LEN=64
|
||||
|
||||
board_build.embed_txtfiles =
|
||||
html/index.min.html
|
||||
|
||||
lib_deps =
|
||||
prampec/IotWebConf @ ^3.2.1
|
||||
geeksville/Micro-RTSP @ ^0.1.6
|
||||
rzeldent/micro-moustache@^1.0.1
|
||||
|
||||
###############################################################################
|
||||
[env:seeed_xiao_esp32s3_sense]
|
||||
platform = espressif32
|
||||
board = seeed_xiao_esp32s3
|
||||
framework = arduino
|
||||
|
||||
# Partition scheme for OTA
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
||||
#upload_protocol = espota
|
||||
#upload_port = 192.168.178.223
|
||||
#upload_flags = --auth='ESP32CAM-RTSP'
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
monitor_filters = log2file, time, default, esp32_exception_decoder
|
||||
|
||||
build_flags =
|
||||
-O2
|
||||
-D BOARD_SEEED_XIAO_ESP32S3_SENSE
|
||||
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
-D LED_FLASH=8
|
||||
-D LED_BUILTIN=21
|
||||
-D BOARD_HAS_PSRAM
|
||||
-mfix-esp32-psram-cache-issue
|
||||
-D IOTWEBCONF_PASSWORD_LEN=64
|
||||
|
||||
board_build.embed_txtfiles =
|
||||
html/index.min.html
|
||||
html/restart.min.html
|
||||
|
||||
lib_deps =
|
||||
prampec/IotWebConf @ ^3.2.1
|
||||
|
||||
134
src/main.cpp
@@ -7,7 +7,7 @@
|
||||
#include <OV2640.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <rtsp_server.h>
|
||||
#include <lookup_camera_config.h>
|
||||
#include <camera_config.h>
|
||||
#include <lookup_camera_effect.h>
|
||||
#include <lookup_camera_frame_size.h>
|
||||
#include <lookup_camera_gainceiling.h>
|
||||
@@ -17,21 +17,13 @@
|
||||
#include <moustache.h>
|
||||
#include <settings.h>
|
||||
|
||||
extern "C" uint8_t temprature_sens_read();
|
||||
|
||||
// HTML files
|
||||
extern const char index_html_min_start[] asm("_binary_html_index_min_html_start");
|
||||
extern const char restart_html_min_start[] asm("_binary_html_restart_min_html_start");
|
||||
|
||||
auto param_group_board = iotwebconf::ParameterGroup("board", "Board settings");
|
||||
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();
|
||||
|
||||
auto param_group_camera = iotwebconf::ParameterGroup("camera", "Camera settings");
|
||||
auto param_frame_duration = iotwebconf::Builder<iotwebconf::UIntTParameter<unsigned long>>("fd").label("Frame duration (ms)").defaultValue(DEFAULT_FRAME_DURATION).min(10).build();
|
||||
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 param_jpg_quality = iotwebconf::Builder<iotwebconf::UIntTParameter<byte>>("q").label("JPG quality").defaultValue(DEFAULT_JPEG_QUALITY).min(1).max(100).build();
|
||||
auto param_enable_psram = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("eps").label("Enable PSRAM if available").defaultValue(DEFAULT_ENABLE_PSRAM).build();
|
||||
auto param_frame_buffers = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("fb").label("Buffers").defaultValue(DEFAULT_BUFFERS).min(1).max(4).build();
|
||||
auto param_brightness = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("b").label("Brightness").defaultValue(DEFAULT_BRIGHTNESS).min(-2).max(2).build();
|
||||
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();
|
||||
@@ -55,9 +47,6 @@ auto param_vflip = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("vm").lab
|
||||
auto param_dcw = iotwebconf::Builder<iotwebconf::CheckboxTParameter>("dcw").label("Downsize enable").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
|
||||
OV2640 cam;
|
||||
// DNS Server
|
||||
@@ -70,8 +59,6 @@ WebServer web_server(80);
|
||||
auto thingName = String(WIFI_SSID) + "-" + String(ESP.getEfuseMac(), 16);
|
||||
IotWebConf iotWebConf(thingName.c_str(), &dnsServer, &web_server, WIFI_PASSWORD, CONFIG_VERSION);
|
||||
|
||||
// Keep track of config changes. This will allow a reset of the device
|
||||
bool config_changed = false;
|
||||
// Camera initialization result
|
||||
esp_err_t camera_init_result;
|
||||
|
||||
@@ -103,11 +90,10 @@ void handle_root()
|
||||
auto ipv6 = WiFi.getMode() == WIFI_MODE_AP ? WiFi.softAPIPv6() : WiFi.localIPv6();
|
||||
|
||||
moustache_variable_t substitutions[] = {
|
||||
// Config Changed?
|
||||
{"ConfigChanged", String(config_changed)},
|
||||
// Version / CPU
|
||||
{"AppTitle", APP_TITLE},
|
||||
{"AppVersion", APP_VERSION},
|
||||
{"BoardType", board_name},
|
||||
{"ThingName", iotWebConf.getThingName()},
|
||||
{"SDKVersion", ESP.getSdkVersion()},
|
||||
{"ChipModel", ESP.getChipModel()},
|
||||
@@ -119,11 +105,6 @@ void handle_root()
|
||||
{"PsRamSize", format_memory(ESP.getPsramSize(), 0)},
|
||||
// Diagnostics
|
||||
{"Uptime", String(format_duration(millis() / 1000))},
|
||||
#ifdef TEMPRATURE_SENS_READ
|
||||
{"Temperature", String((temprature_sens_read() - 32) / 1.8)},
|
||||
#else
|
||||
{"Temperature", "N/A"},
|
||||
#endif
|
||||
{"FreeHeap", format_memory(ESP.getFreeHeap())},
|
||||
{"MaxAllocHeap", format_memory(ESP.getMaxAllocHeap())},
|
||||
{"NumRTSPSessions", camera_server != nullptr ? String(camera_server->num_connected()) : "RTSP server disabled"},
|
||||
@@ -138,13 +119,10 @@ void handle_root()
|
||||
{"NetworkState.ApMode", String(iotWebConf.getState() == iotwebconf::NetworkState::ApMode)},
|
||||
{"NetworkState.OnLine", String(iotWebConf.getState() == iotwebconf::NetworkState::OnLine)},
|
||||
// Camera
|
||||
{"BoardType", String(param_board.value())},
|
||||
{"FrameSize", String(param_frame_size.value())},
|
||||
{"FrameDuration", String(param_frame_duration.value())},
|
||||
{"FrameFrequency", String(1000.0 / param_frame_duration.value(), 1)},
|
||||
{"JpegQuality", String(param_jpg_quality.value())},
|
||||
{"EnablePSRAM", String(param_enable_psram.value())},
|
||||
{"FrameBuffers", String(param_frame_buffers.value())},
|
||||
{"CameraInitialized", String(camera_init_result == ESP_OK)},
|
||||
{"CameraInitResult", String(camera_init_result)},
|
||||
{"CameraInitResultText", esp_err_to_name(camera_init_result)},
|
||||
@@ -171,8 +149,6 @@ void handle_root()
|
||||
{"VFlip", String(param_vflip.value())},
|
||||
{"Dcw", String(param_dcw.value())},
|
||||
{"ColorBar", String(param_colorbar.value())},
|
||||
// LED
|
||||
{"LedIntensity", String(param_led_intensity.value())},
|
||||
// RTSP
|
||||
{"RtspPort", String(RTSP_PORT)}};
|
||||
|
||||
@@ -181,28 +157,6 @@ void handle_root()
|
||||
web_server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void handle_restart()
|
||||
{
|
||||
log_v("Handle restart");
|
||||
|
||||
if (!web_server.authenticate("admin", iotWebConf.getApPasswordParameter()->valueBuffer))
|
||||
{
|
||||
web_server.requestAuthentication(BASIC_AUTH, APP_TITLE, "401 Unauthorized<br><br>The password is incorrect.");
|
||||
return;
|
||||
}
|
||||
|
||||
moustache_variable_t substitutions[] = {
|
||||
{"AppTitle", APP_TITLE},
|
||||
{"AppVersion", APP_VERSION},
|
||||
{"ThingName", iotWebConf.getThingName()}};
|
||||
|
||||
auto html = moustache_render(restart_html_min_start, substitutions);
|
||||
web_server.send(200, "text/html", html);
|
||||
log_v("Restarting... Press refresh to connect again");
|
||||
sleep(100);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
void handle_snapshot()
|
||||
{
|
||||
log_v("handle_snapshot");
|
||||
@@ -213,7 +167,7 @@ void handle_snapshot()
|
||||
}
|
||||
|
||||
// Remove old images stored in the frame buffer
|
||||
auto frame_buffers = param_frame_buffers.value();
|
||||
auto frame_buffers = default_camera_config.fb_count;
|
||||
while (frame_buffers--)
|
||||
cam.run();
|
||||
|
||||
@@ -261,64 +215,19 @@ void handle_stream()
|
||||
client.stop();
|
||||
log_v("stopped streaming");
|
||||
}
|
||||
|
||||
void handle_flash()
|
||||
{
|
||||
log_v("handle_flash");
|
||||
|
||||
if (!web_server.authenticate("admin", iotWebConf.getApPasswordParameter()->valueBuffer))
|
||||
{
|
||||
web_server.requestAuthentication(BASIC_AUTH, APP_TITLE, "401 Unauthorized<br><br>The password is incorrect.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If no value present, use value from config
|
||||
if (web_server.hasArg("v"))
|
||||
{
|
||||
auto v = (uint8_t)min(web_server.arg("v").toInt(), 255L);
|
||||
// If conversion fails, v = 0
|
||||
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.send(200);
|
||||
}
|
||||
|
||||
esp_err_t initialize_camera()
|
||||
{
|
||||
log_v("initialize_camera");
|
||||
log_i("Camera config: %s", param_board.value());
|
||||
auto camera_config_template = lookup_camera_config(param_board.value());
|
||||
// Copy the settings
|
||||
camera_config_t camera_config;
|
||||
memset(&camera_config, 0, sizeof(camera_config_t));
|
||||
memcpy(&camera_config, &camera_config_template, sizeof(camera_config_t));
|
||||
memcpy(&camera_config, &default_camera_config, sizeof(camera_config_t));
|
||||
log_i("Frame size: %s", param_frame_size.value());
|
||||
auto frame_size = lookup_frame_size(param_frame_size.value());
|
||||
log_i("JPEG quality: %d", param_jpg_quality.value());
|
||||
log_i("Frame duration: %d ms", param_frame_duration.value());
|
||||
camera_config.frame_size = frame_size;
|
||||
camera_config.jpeg_quality = param_jpg_quality.value();
|
||||
camera_config.grab_mode = CAMERA_GRAB_LATEST;
|
||||
log_i("Enable PSRAM: %d", param_enable_psram.value());
|
||||
log_i("Frame buffers: %d", param_frame_buffers.value());
|
||||
camera_config.fb_count = param_frame_buffers.value();
|
||||
|
||||
if (param_enable_psram.value() && psramFound())
|
||||
{
|
||||
camera_config.fb_location = CAMERA_FB_IN_PSRAM;
|
||||
log_i("PSRAM enabled!");
|
||||
}
|
||||
else
|
||||
{
|
||||
camera_config.fb_location = CAMERA_FB_IN_DRAM;
|
||||
log_i("PSRAM disabled");
|
||||
}
|
||||
|
||||
return cam.init(camera_config);
|
||||
}
|
||||
|
||||
@@ -379,26 +288,17 @@ void on_connected()
|
||||
void on_config_saved()
|
||||
{
|
||||
log_v("on_config_saved");
|
||||
// Set flash led intensity
|
||||
analogWrite(LED_FLASH, param_led_intensity.value());
|
||||
// Update camera setting
|
||||
update_camera_settings();
|
||||
config_changed = true;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Disable brownout
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
|
||||
|
||||
// LED_BUILTIN (GPIO33) has inverted logic false => LED on
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(LED_BUILTIN, false);
|
||||
|
||||
pinMode(LED_FLASH, OUTPUT);
|
||||
// Turn flash led off
|
||||
analogWrite(LED_FLASH, 0);
|
||||
|
||||
#ifdef CORE_DEBUG_LEVEL
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
@@ -407,22 +307,19 @@ void setup()
|
||||
log_i("CPU Freq: %d Mhz, %d core(s)", getCpuFrequencyMhz(), ESP.getChipCores());
|
||||
log_i("Free heap: %d bytes", ESP.getFreeHeap());
|
||||
log_i("SDK version: %s", ESP.getSdkVersion());
|
||||
log_i("Board: %s", board_name);
|
||||
log_i("Starting " APP_TITLE "...");
|
||||
|
||||
if (psramFound())
|
||||
{
|
||||
psramInit();
|
||||
log_v("PSRAM found and initialized");
|
||||
}
|
||||
|
||||
param_group_board.addItem(¶m_board);
|
||||
iotWebConf.addParameterGroup(¶m_group_board);
|
||||
if (default_camera_config.fb_location == CAMERA_FB_IN_PSRAM)
|
||||
{
|
||||
if (!psramInit())
|
||||
log_e("Failed to initialize PSRAM");
|
||||
}
|
||||
|
||||
param_group_camera.addItem(¶m_frame_duration);
|
||||
param_group_camera.addItem(¶m_frame_size);
|
||||
param_group_camera.addItem(¶m_jpg_quality);
|
||||
param_group_camera.addItem(¶m_enable_psram);
|
||||
param_group_camera.addItem(¶m_frame_buffers);
|
||||
param_group_camera.addItem(¶m_brightness);
|
||||
param_group_camera.addItem(¶m_contrast);
|
||||
param_group_camera.addItem(¶m_saturation);
|
||||
@@ -447,9 +344,6 @@ void setup()
|
||||
param_group_camera.addItem(¶m_colorbar);
|
||||
iotWebConf.addParameterGroup(¶m_group_camera);
|
||||
|
||||
param_group_peripheral.addItem(¶m_led_intensity);
|
||||
iotWebConf.addParameterGroup(¶m_group_peripheral);
|
||||
|
||||
iotWebConf.getApTimeoutParameter()->visible = true;
|
||||
iotWebConf.setConfigSavedCallback(on_config_saved);
|
||||
iotWebConf.setWifiConnectionCallback(on_connected);
|
||||
@@ -460,19 +354,16 @@ void setup()
|
||||
if (camera_init_result == ESP_OK)
|
||||
update_camera_settings();
|
||||
else
|
||||
log_e("Failed to initialize camera: 0x%0x. Type: %s, frame size: %s, frame rate: %d ms, jpeg quality: %d", camera_init_result, param_board.value(), param_frame_size.value(), param_frame_duration.value(), param_jpg_quality.value());
|
||||
log_e("Failed to initialize camera: 0x%0x. Frame size: %s, frame rate: %d ms, jpeg quality: %d", camera_init_result, param_frame_size.value(), param_frame_duration.value(), param_jpg_quality.value());
|
||||
|
||||
// Set up required URL handlers on the web server
|
||||
web_server.on("/", HTTP_GET, handle_root);
|
||||
web_server.on("/config", []
|
||||
{ iotWebConf.handleConfig(); });
|
||||
web_server.on("/restart", HTTP_GET, handle_restart);
|
||||
// Camera snapshot
|
||||
web_server.on("/snapshot", HTTP_GET, handle_snapshot);
|
||||
// Camera stream
|
||||
web_server.on("/stream", HTTP_GET, handle_stream);
|
||||
// Camera flash light
|
||||
web_server.on("/flash", HTTP_GET, handle_flash);
|
||||
|
||||
web_server.onNotFound([]()
|
||||
{ iotWebConf.handleNotFound(); });
|
||||
@@ -496,9 +387,6 @@ void setup()
|
||||
case OTA_END_ERROR: log_e("OTA: End Failed"); break;
|
||||
default: log_e("OTA error: %u", error);
|
||||
} });
|
||||
|
||||
// Set flash led intensity
|
||||
analogWrite(LED_FLASH, param_led_intensity.value());
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
||||