29 Commits
1.0.5 ... main

Author SHA1 Message Date
ce3a12f422 Add devcontainer configuration for ESP32-CAM RTSP development and update .gitignore 2025-07-27 17:52:17 -05:00
Rene Zeldenthuis
00635d03b7 git submodule stuff 2025-03-15 14:39:57 +01:00
Rene
1bb103a2a8 Merge pull request #163 from ndoo/main
Add support for M5Stack AtomS3R-CAM
2025-03-15 13:53:34 +01:00
Andrew Yong
d55a97a3a7 Add support for M5Stack AtomS3R-CAM
Signed-off-by: Andrew Yong <me@ndoo.sg>
2025-03-07 11:56:07 +08:00
Rene Zeldenthuis
a4c6d60279 Moved dependabot 2024-12-29 11:45:53 +01:00
Rene
45d08d08ce Add files via upload 2024-12-29 11:42:17 +01:00
ColdLlama
0eb4ddfe69 Update README.md (#151)
corrected a tiny typo from "to" to "two"
2024-11-17 15:15:06 +01:00
Kaze
7a5abd3235 Update README.md (#148)
According to AI-Thinker officials, the ESP32-2 is a module and not a CPU, so it was changed to the ESP32.
2024-11-12 16:35:02 +01:00
Rene Zeldenthuis
312d916647 merge issues and fixes 2024-03-10 12:46:48 +01:00
Rene Zeldenthuis
71079f4796 Fix merge 2024-03-10 11:24:40 +01:00
Rene
d99d1c510f Merged from develop (Updated documentation) (#115)
* Added seeed_xiao_esp32s3

* Fixed typo

* Updating build system

* Fixed typos

* Renamed envirnment name to seeed_xiao_esp32s3

* Update README.md

* Updated platformio definitions

* Added cache

* Updated README.md

* - Default value for initResult if initialzation fails

* constexpr camera_config_t m5stack_camera_settings

* Added M5Stack UnitCamS3

* Work in progress

* WIP

* Work in progress

* Removed OTA

* Added unitcams3

* UnitcamS3

* Corrected HTML for ipv4
fixed Sewrial issue esp32s2

* USER_LED_ON_LEVEL=LOW

* Added documentation pins for Mems/grove/led

* Typo

* Removed non required depencency

* Removed non required depencency

* Readded

* Added sccb_i2c_port
Retry 3 times camera init

* Added Freenove wroom-1 n8r8 board (#112)

Co-authored-by: Nick Eales <nick.eales@outlook.com>

* Fixing missing comma in xiao board json (#114)

* Updated Markdown

---------

Co-authored-by: absentwallaby <64674944+absentwallaby@users.noreply.github.com>
Co-authored-by: Nick Eales <nick.eales@outlook.com>
Co-authored-by: Nick Volgas <n.volgas@gmail.com>
2024-03-10 11:11:03 +01:00
Rene
a60fbc7917 Develop (#108)
* Added seeed_xiao_esp32s3

* Fixed typo

* Updating build system

* Fixed typos

* Renamed envirnment name to seeed_xiao_esp32s3

* Update README.md

* Updated platformio definitions

* Added cache

* Updated README.md

* - Default value for initResult if initialzation fails

* constexpr camera_config_t m5stack_camera_settings

* Added M5Stack UnitCamS3

* Work in progress

* WIP

* Work in progress

* Removed OTA

* Added unitcams3

* UnitcamS3

* Corrected HTML for ipv4
fixed Sewrial issue esp32s2

* USER_LED_ON_LEVEL=LOW

* Added documentation pins for Mems/grove/led

* Typo

* Removed non required depencency

* Removed non required depencency

* Readded
2024-02-13 14:13:45 +01:00
Rene
5e4fee3624 Update README.md 2023-12-18 23:50:10 +01:00
Rene
7a0259d878 Update README.md 2023-12-18 23:49:50 +01:00
Rene
f68e347c5b Update README.md 2023-10-17 16:12:14 +02:00
Rene
0d0223e8df Update README.md 2023-10-17 16:11:30 +02:00
Rene
45e9a92e3c Update README.md 2023-10-17 16:10:41 +02:00
rzeldent
3e6df1a56b Merge pull request #94 from rzeldent/bugfix/flashurl
Fix space in flashlight URL
2023-09-21 21:05:18 +02:00
Rene Zeldenthuis
a40f6a8ad8 Fix space in flashlight URL 2023-09-21 21:03:12 +02:00
rzeldent
aee7cbddd8 Merge pull request #78 from rzeldent/feature/temperature
- Added temperature
2023-06-16 18:23:35 +02:00
Rene Zeldenthuis
8c263be1a6 - Added temperature
- Added uptime
2023-06-16 18:20:35 +02:00
rzeldent
0dc7abc338 Merge pull request #76 from rzeldent:bugfix/default_settings
Changes to default configuration:
2023-06-08 23:20:28 +02:00
Rene Zeldenthuis
e88c7a6f62 Changes to default configuration:
- Frame duration 200ms
- Frame size VGA (640x480)
- Quality 12/14
2023-06-08 23:14:30 +02:00
Rene Zeldenthuis
a711eec80c Added cores to logging 2023-05-29 13:29:16 +02:00
rzeldent
5f80cabbed Merge pull request #62 from rzeldent/feature/remove_bootstrap
- Added CSS in html
2023-05-05 23:37:22 +08:00
Rene Zeldenthuis
621dbe466e - Added CSS in html
- Embed using platformIO
- new minify (also css)
2023-04-16 17:17:28 +02:00
rzeldent
72482080cf Merge pull request #55 from rzeldent/bugfix/ipv4ipv6
Bugfix/ipv4ipv6
2023-03-26 22:29:46 +02:00
Rene Zeldenthuis
97acc08edf Added logging 2023-03-26 22:26:12 +02:00
Rene Zeldenthuis
86dcf88d4e Added led flashing for connectivity 2023-03-26 21:54:24 +02:00
66 changed files with 1836 additions and 861 deletions

View File

@@ -0,0 +1,22 @@
{
"name": "ESP32-CAM RTSP Development",
"image": "platformio/platformio-core",
"customizations": {
"vscode": {
"extensions": [
"platformio.platformio-ide",
"ms-vscode.cpptools",
"ms-vscode.cmake-tools"
]
}
},
"mounts": ["source=/dev,target=/dev,type=bind"],
"runArgs": ["--privileged", "--device-cgroup-rule=c 166:* rmw"],
"postCreateCommand": "pio pkg update -g -p espressif32",
"remoteUser": "root",
"forwardPorts": [80, 554],
"portsAttributes": {
"80": { "label": "Web Interface" },
"554": { "label": "RTSP Stream" }
}
}

View File

@@ -5,18 +5,25 @@ jobs:
name: Build name: Build
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up python
uses: actions/setup-python@v3
with: with:
python-version: '3.x' submodules: 'true'
architecture: 'x64' - uses: actions/cache@v4
with:
path: |
~/.cache/pip
~/.platformio/.cache
key: ${{ runner.os }}-pio
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: Install PlatformIO - name: Install PlatformIO
run: python -m pip install platformio run: python -m pip install platformio
- name: Build firmware - name: Build firmware
run: platformio run run: platformio run
- name: Archive - name: Archive
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: firmware.bin name: firmwares.zip
path: .pio/build/*/firmware.bin path: .pio/build/*/firmware.bin

4
.gitignore vendored
View File

@@ -1,5 +1,7 @@
.*/* .pio/*
.vscode/*
.*.* .*.*
__pycache__/
*.log *.log
.DS_Store .DS_Store
workspace.code-workspace workspace.code-workspace

144
README.md
View File

@@ -1,36 +1,51 @@
# ESP32CAM-RTSP :video_camera: # ESP32CAM-RTSP
[![Platform IO CI](https://github.com/rzeldent/esp32cam-rtsp/actions/workflows/main.yml/badge.svg)](https://github.com/rzeldent/esp32cam-rtsp/actions/workflows/main.yml) [![Platform IO CI](https://github.com/rzeldent/esp32cam-rtsp/actions/workflows/main.yml/badge.svg)](https://github.com/rzeldent/esp32cam-rtsp/actions/workflows/main.yml)
Simple [RTSP](https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol), [HTTP JPEG Streamer](https://en.wikipedia.org/wiki/Motion_JPEG) and image server with configuration through the web interface. Simple [RTSP](https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol), [HTTP JPEG Streamer](https://en.wikipedia.org/wiki/Motion_JPEG) and image server with configuration through the web interface.
> [!IMPORTANT]
> New branch available! Here [branch: develop](https://github.com/rzeldent/esp32cam-rtsp/tree/develop)
> This branch supports all the current devices and the Seeed Studio Xiao esp32s3!
> Please use this and let me know if this works for you!
Flashing this software on a ESP32CAM module will make it a **RTSP streaming camera** server, a **HTTP Motion JPEG streamer** and a **HTTP image server**. Flashing this software on a ESP32CAM module will make it a **RTSP streaming camera** server, a **HTTP Motion JPEG streamer** and a **HTTP image server**.
Supported protocols Supported protocols
- :white_check_mark: RTSP - RTSP
The RTSP protocol is an industry standard and allows many CCTV systems and applications (like for example [VLC](https://www.videolan.org/vlc/)) to connect directly to the ESP32CAM camera stream. The RTSP protocol is an industry standard and allows many CCTV systems and applications (like for example [VLC](https://www.videolan.org/vlc/)) to connect directly to the ESP32CAM camera stream.
It is also possible to stream directly to a server using [ffmpeg](https://ffmpeg.org). It is also possible to stream directly to a server using [ffmpeg](https://ffmpeg.org).
This makes the module a camera server allowing recording and the stream can be stored on a disk and replayed later. This makes the module a camera server allowing recording and the stream can be stored on a disk and replayed later.
The URL is rtsp://&lt;ip address&gt;:554/mjpeg/1 The URL is rtsp://&lt;ip address&gt;:554/mjpeg/1
- :white_check_mark: HTTP Motion JPEG - HTTP Motion JPEG
The HTTP JPEG streamer makes it possible to watch the camera stream directly in your browser. The HTTP JPEG streamer makes it possible to watch the camera stream directly in your browser.
The URL is http://&lt;ip address&gt;/stream The URL is http://&lt;ip address&gt;/stream
- :white_check_mark: HTTP image - HTTP image
The HTTP Image returns an HTTP JPEG image of the camera. The HTTP Image returns an HTTP JPEG image of the camera.
The URL is http://&lt;ip address&gt;/snapshot The URL is http://&lt;ip address&gt;/snapshot
This software supports the following ESP32-CAM (and alike) modules: This software supports the following ESP32-CAM (and alike) modules:
- ESP32CAM
- AI THINKER - AI THINKER
- TTGO T-CAM - EspressIf ESP-EYE
- WROVER-KIT - EspressIf ESP32S2-CAM
- EspressIf ESP32S3-CAM-LCD
- EspressIf ESP32S3-EYE
- Freenove WROVER KIT
- M5STACK ESP32CAM
- M5STACK_PSRAM
- M5STACK_UNITCAM
- M5STACK_UNITCAMS3
- M5STACK_V2_PSRAM
- M5STACK_PSRAM
- M5STACK_WIDE
- M5STACK - M5STACK
- Seeed Studio XIAO ESP32S3 SENSE
![ESP32CAM module](assets/ESP32-CAM.jpg) - TTGO T-CAMERA
- TTGO T-JOURNAL
The software provides a **configuration web server**, that can be used to: The software provides a **configuration web server**, that can be used to:
@@ -38,7 +53,6 @@ The software provides a **configuration web server**, that can be used to:
- Set the WiFi parameters, - Set the WiFi parameters,
- Set the timeout for connecting to the access point, - Set the timeout for connecting to the access point,
- Set an access password, - Set an access password,
- Select the board type,
- Select the image size, - Select the image size,
- Select the frame rate, - Select the frame rate,
- Select the JPEG quality - Select the JPEG quality
@@ -48,7 +62,7 @@ The software provides a **configuration web server**, that can be used to:
- Brightness - Brightness
- Contrast - Contrast
- Saturation - Saturation
- Special effect (Normal, Negative, Grayscale, Red/Green/Blue tint, Sepia) - Special effect (Normal, Negative, Gray-scale, Red/Green/Blue tint, Sepia)
- White balance - White balance
- Automatic White Balance gain - Automatic White Balance gain
- Wite Balance mode - Wite Balance mode
@@ -77,25 +91,34 @@ 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, - 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) - [**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 | Image | CPU | SRAM | Flash | PSRAM | Camera | | Site |
|--- |--- |--- |--- |--- | --- |--- |--- |--- |
| Espressif ESP32-Wrover CAM | ![img](assets/boards/esp32-wrover-cam.jpg) | ESP32 | 520KB | 4Mb | 4MB | OV2640 | | |
| AI-Thinker ESP32-CAM | ![img](assets/boards/ai-thinker-esp32-cam-ipex.jpg) ![img](assets/boards/ai-thinker-esp32-cam.jpg) | ESP32 | 520KB | 4Mb | 4MB | OV2640 | | [https://docs.ai-thinker.com/esp32-cam](https://docs.ai-thinker.com/esp32-cam) |
| Espressif ESP-EYE | ![img](assets/boards/espressif-esp-eye.jpg) | ESP32 | 520KB | 4Mb | 4MB | OV2640 | | |
| Espressif ESP-S3-EYE | ![img](assets/boards/espressif-esps3-eye.jpg) | ESP32-S3 | 520KB | 4Mb | 4MB | OV2640 | | [https://www.espressif.com/en/products/devkits/esp-eye/overview](https://www.espressif.com/en/products/devkits/esp-eye/overview) |
| LilyGo camera module | ![img](assets/boards/lilygo-camera-module.jpg) | ESP32 Wrover | 520KB | 4Mb | 4MB | OV2640 / OV5640 | | |
| LilyGo Simcam | ![img](assets/boards/lilygo-simcam.jpg) | | | | | OV2640 | | |
| LilyGo TTGO-T Camera | ![img](assets/boards/lilygo-ttgo-t-camera.jpg) | | | | | OV2640 | | |
| M5Stack ESP32CAM | ![img](assets/boards/m5stack_esp32cam_02.webp) | ESP32 | 520Kb | 4Mb | - | OV2640 | Microphone | [https://docs.m5stack.com/en/unit/esp32cam](https://docs.m5stack.com/en/unit/esp32cam) |
| M5Stack UnitCam | ![img](assets/boards/m5stack_unit_cam_02.webp) ![img](assets/boards/m5stack_unit_cam_03.webp) | ESP32-WROOM-32E | 520KB | 4Mb | - | OV2640 | | [https://docs.m5stack.com/en/unit/unit_cam](https://docs.m5stack.com/en/unit/unit_cam) |
| M5Stack Camera | ![img](assets/boards/m5stack-esp32-camera.jpg) | ESP32 | 520Kb | 4Mb | - | OV2640 | | [https://docs.m5stack.com/en/unit/m5camera](https://docs.m5stack.com/en/unit/m5camera) |
| M5Stack Camera PSRAM | ![img](assets/boards/m5stack-esp32-camera.jpg) | ESP32 | 520Kb | 4Mb | 4Mb | OV2640 | | [https://docs.m5stack.com/en/unit/m5camera](https://docs.m5stack.com/en/unit/m5camera) |
| M5Stack UnitCamS3 | ![img](assets/boards//m5stack_Unitcams3.webp) ![img](assets/boards/m5stack_Unitcams32.webp) | ESP32-S3-WROOM-1-N16R8 | 520Kb | 16Mb | 8Mb | OV2640 | | [https://docs.m5stack.com/en/unit/Unit-CamS3](https://docs.m5stack.com/en/unit/Unit-CamS3) |
| Seeed studio Xiao ESP32S3 Sense | ![img](assets/boards/seeed-studio-xiao-esp32s3-sense.jpg) | ESP32-S3R8 | 520KB | 8Mb | 8MB | OV2640 | Microphone | [https://www.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html](https://www.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html) |
## Installing and running PlatformIO ## 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). 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. 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 [Visual Studio Code](https://code.visualstudio.com) and install the PlatformIO plugin.
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.
## Putting the ESP32-CAM in download mode ## Putting the ESP32-CAM in download mode
@@ -128,17 +151,28 @@ cd esp32cam-rtsp
``` ```
Next, the firmware has to be build and deployed to the ESP32. Next, the firmware has to be build and deployed to the ESP32.
There are to flavours to do this; using the command line or the graphical interface of Visual Studio Code. There are two flavours to do this; using the command line or the graphical interface of Visual Studio Code.
I recommend to use VIsual Studio Code as it is free to use and offers more insight.
### Using the command line ### Using the command line
First the source code has to be compiled. Type: Make sure you have the latest version of the Espressif toolchain.
```sh
pio pkg update -g -p espressif32
```
First the source code has to be compiled to build all targets
```sh ```sh
pio run pio run
``` ```
if only a specific target is required, for example the ```esp32cam_ttgo_t_journal``` type:
```sh
pio run -e esp32cam_ttgo_t_journal
```
When finished, firmware has to be uploaded. When finished, firmware has to be uploaded.
Make sure the ESP32-CAM is in download mode (see previous section) and type: Make sure the ESP32-CAM is in download mode (see previous section) and type:
@@ -146,6 +180,12 @@ Make sure the ESP32-CAM is in download mode (see previous section) and type:
pio run -t upload pio run -t upload
``` ```
or, again, for a specific target, for example ```esp32cam_ai_thinker```
```sh
pio run -t upload -e esp32cam_ai_thinker
```
When done remove the jumper when using a FTDI adapter or press the reset button on the ESP32-CAM. When done remove the jumper when using a FTDI adapter or press the reset button on the ESP32-CAM.
To monitor the output, start a terminal using: To monitor the output, start a terminal using:
@@ -199,21 +239,21 @@ In case changes have been made to the configuration, this is shown and the possi
Clicking on the ```change configuration``` button will open the configuration. It is possible that a password dialog is shown before entering. Clicking on the ```change configuration``` button will open the configuration. It is possible that a password dialog is shown before entering.
If this happens, for the user enter 'admin' and for the password the value that has been configured as the Access Point password. If this happens, for the user enter 'admin' and for the password the value that has been configured as the Access Point password.
## Connecting to the RTSP stream :video_camera: ## Connecting to the RTSP stream
RTSP stream is available at: [rtsp://esp32cam-rtsp.local:554/mjpeg/1](rtsp://esp32cam-rtsp.local:554/mjpeg/1). RTSP stream is available at: [rtsp://esp32cam-rtsp.local:554/mjpeg/1](rtsp://esp32cam-rtsp.local:554/mjpeg/1).
This link can be opened with for example [VLC](https://www.videolan.org/vlc/). This link can be opened with for example [VLC](https://www.videolan.org/vlc/).
## Connecting to the JPEG motion server :video_camera: ## Connecting to the JPEG motion server
The JPEG motion server server is available using a normal web browser at: [http://esp32cam-rtsp.local:/stream](http://esp32cam-rtsp.local/stream). The JPEG motion server server is available using a normal web browser at: [http://esp32cam-rtsp.local:/stream](http://esp32cam-rtsp.local/stream).
## Connecting to the image server :camera: ## Connecting to the image server
The image server server is available using a normal web browser at: [http://esp32cam-rtsp.local:/snapshot](http://esp32cam-rtsp.local/snapshot). The image server server is available using a normal web browser at: [http://esp32cam-rtsp.local:/snapshot](http://esp32cam-rtsp.local/snapshot).
:bangbang: **Please be aware that there is no password present!**. :bangbang: **Please be aware that there is no password present!**.
Everybody with access to the device can see the streams or images! Beware of :trollface:! Everybody with network access to the device can see the streams or images! Beware of :trollface:!
## API ## API
@@ -234,16 +274,8 @@ Calling this URL will start the form for configuring the device in the browser.
### GET: /snapshot ### GET: /snapshot
Calling this URL will return a JPEG snapshot of the camera in the browser. Calling this URL will return a JPEG snapshot of the camera in the browser.
This request can also be used (for example using cURL) to save the snapshot to a file. This request can also be used (for example using cURL) to save the snapshot to a file.
### GET: /flash?v={intensity}
Calling this URL will set the intensity of the flash LED. Authentication is required.
The parameter v for the intensity must be between 0 (off) and 255 (max).
If no v parameter is present, it will be set to the value of the flash LED intensity from configuration.
## Issues / Nice to know ## Issues / Nice to know
- The red LED on the back of the device indicates the device is not connected. - The red LED on the back of the device indicates the device is not connected.
@@ -278,14 +310,22 @@ The availability of PSRAM can be seen in the HTML status overview.
Not all the boards are equipped with PSRAM: Not all the boards are equipped with PSRAM:
| Board | PSRAM | | Board | PSRAM |
|--- |--- | |--- |--- |
| ESP32CAM | Yes | | WROVER_KIT | 8Mb |
| ESP32CAM (USB-C) | No | | ESP_EYE | 8Mb |
| AI THINKER | Yes | | ESP32S3_EYE | 8Mb |
| TTGO T-CAM | No | | M5STACK_PSRAM | 8Mb |
| M5 STACK| | No | | M5STACK_V2_PSRAM | Version B only |
| WROVER KIT | Yes | | M5STACK_WIDE | 8Mb |
| M5STACK_ESP32CAM | No |
| M5STACK_UNITCAM | No |
| M5STACK_UNITCAMS3 | 8Mb |
| AI_THINKER | 8Mb |
| TTGO_T_JOURNAL | No |
| ESP32_CAM_BOARD | ? |
| ESP32S2_CAM_BOARD | ? |
| ESP32S3_CAM_LCD | ? |
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. 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.
There are (a lot of?) boards around with faulty PSRAM. If the camera fails to initialize, this might be a reason. See on [Reddit](https://www.reddit.com/r/esp32/comments/z2hyns/i_have_a_faulty_psram_on_my_esp32cam_what_should/). There are (a lot of?) boards around with faulty PSRAM. If the camera fails to initialize, this might be a reason. See on [Reddit](https://www.reddit.com/r/esp32/comments/z2hyns/i_have_a_faulty_psram_on_my_esp32cam_what_should/).
@@ -317,6 +357,14 @@ esp32cam-rtsp depends on PlatformIO, Bootstrap 5 and Micro-RTSP by Kevin Hester.
## Change history ## Change history
- January 2024
- Moved settings to board definitions
- Added new boards
- Removed OTA to increase performance
- Oktober 2023
- Added support for Seeed Xiao esp32s3
- New build system
- Updated documentation
- March 2023 - March 2023
- Added options to set PSRAM / Frame buffers - Added options to set PSRAM / Frame buffers
- Added JPEG Motion streaming - Added JPEG Motion streaming

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

View File

@@ -0,0 +1,66 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_AI_THINKER'",
"'-D BOARD_HAS_PSRAM'",
"'-mfix-esp32-psram-cache-issue'",
"'-D USER_LED_GPIO=33'",
"'-D USER_LED_ON_LEVEL=LOW'",
"'-D CAMERA_CONFIG_PIN_PWDN=32'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=0'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=26'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=27'",
"'-D CAMERA_CONFIG_PIN_Y9=35'",
"'-D CAMERA_CONFIG_PIN_Y8=34'",
"'-D CAMERA_CONFIG_PIN_Y7=39'",
"'-D CAMERA_CONFIG_PIN_Y6=36'",
"'-D CAMERA_CONFIG_PIN_Y5=21'",
"'-D CAMERA_CONFIG_PIN_Y4=19'",
"'-D CAMERA_CONFIG_PIN_Y3=18'",
"'-D CAMERA_CONFIG_PIN_Y2=5'",
"'-D CAMERA_CONFIG_PIN_VSYNC=25'",
"'-D CAMERA_CONFIG_PIN_HREF=23'",
"'-D CAMERA_CONFIG_PIN_PCLK=22'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32CAM AI Thinker",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.ai-thinker.com/esp32-cam",
"vendor": "Anxinke"
}

View File

@@ -0,0 +1,63 @@
{
"build": {
"arduino": {
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_ESPRESSIF_ESP32S2_CAM_BOARD'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=0'",
"'-D ARDUINO_USB_CDC_ON_BOOT=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D CAMERA_CONFIG_PIN_PWDN=1'",
"'-D CAMERA_CONFIG_PIN_RESET=2'",
"'-D CAMERA_CONFIG_PIN_XCLK=42'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=41'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=18'",
"'-D CAMERA_CONFIG_PIN_Y9=16'",
"'-D CAMERA_CONFIG_PIN_Y8=39'",
"'-D CAMERA_CONFIG_PIN_Y7=40'",
"'-D CAMERA_CONFIG_PIN_Y6=15'",
"'-D CAMERA_CONFIG_PIN_Y5=12'",
"'-D CAMERA_CONFIG_PIN_Y4=5'",
"'-D CAMERA_CONFIG_PIN_Y3=13'",
"'-D CAMERA_CONFIG_PIN_Y2=14'",
"'-D CAMERA_CONFIG_PIN_VSYNC=38'",
"'-D CAMERA_CONFIG_PIN_HREF=4'",
"'-D CAMERA_CONFIG_PIN_PCLK=3'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"mcu": "esp32s2",
"variant": "esp32s2"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s2.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif ESP32-S2-Saola-1",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.html",
"vendor": "Espressif"
}

View File

@@ -0,0 +1,63 @@
{
"build": {
"arduino": {
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_ESPRESSIF_ESP32S2_CAM_BOARD'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=0'",
"'-D ARDUINO_USB_CDC_ON_BOOT=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D CAMERA_CONFIG_PIN_PWDN=1'",
"'-D CAMERA_CONFIG_PIN_RESET=2'",
"'-D CAMERA_CONFIG_PIN_XCLK=42'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=41'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=18'",
"'-D CAMERA_CONFIG_PIN_Y9=16'",
"'-D CAMERA_CONFIG_PIN_Y8=39'",
"'-D CAMERA_CONFIG_PIN_Y7=40'",
"'-D CAMERA_CONFIG_PIN_Y6=15'",
"'-D CAMERA_CONFIG_PIN_Y5=13'",
"'-D CAMERA_CONFIG_PIN_Y4=5'",
"'-D CAMERA_CONFIG_PIN_Y3=12'",
"'-D CAMERA_CONFIG_PIN_Y2=14'",
"'-D CAMERA_CONFIG_PIN_VSYNC=38'",
"'-D CAMERA_CONFIG_PIN_HREF=4'",
"'-D CAMERA_CONFIG_PIN_PCLK=3'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"mcu": "esp32s2",
"variant": "esp32s2"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s2.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif ESP32-S2-Saola-1",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.html",
"vendor": "Espressif"
}

View File

@@ -0,0 +1,72 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv",
"memory_type": "opi_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_ESP32S3_CAM_LCD'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=40'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=17'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=18'",
"'-D CAMERA_CONFIG_PIN_Y9=39'",
"'-D CAMERA_CONFIG_PIN_Y8=41'",
"'-D CAMERA_CONFIG_PIN_Y7=42'",
"'-D CAMERA_CONFIG_PIN_Y6=12'",
"'-D CAMERA_CONFIG_PIN_Y5=3'",
"'-D CAMERA_CONFIG_PIN_Y4=14'",
"'-D CAMERA_CONFIG_PIN_Y3=47'",
"'-D CAMERA_CONFIG_PIN_Y2=13'",
"'-D CAMERA_CONFIG_PIN_VSYNC=21'",
"'-D CAMERA_CONFIG_PIN_HREF=38'",
"'-D CAMERA_CONFIG_PIN_PCLK=11'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dout",
"hwids": [
[
"0X303A",
"0x1001"
]
],
"mcu": "esp32s3",
"variant": "esp32s3camlcd"
},
"connectivity": [
"bluetooth",
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32S3-CAM LCD",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.espressif.com/en/news/Maple_Eye_ESP32-S3",
"vendor": "Espressif"
}

View File

@@ -0,0 +1,76 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_ESPRESSIF_ESP32S3_EYE'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=15'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=4'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=5'",
"'-D CAMERA_CONFIG_PIN_Y9=16'",
"'-D CAMERA_CONFIG_PIN_Y8=17'",
"'-D CAMERA_CONFIG_PIN_Y7=18'",
"'-D CAMERA_CONFIG_PIN_Y6=12'",
"'-D CAMERA_CONFIG_PIN_Y5=10'",
"'-D CAMERA_CONFIG_PIN_Y4=8'",
"'-D CAMERA_CONFIG_PIN_Y3=9'",
"'-D CAMERA_CONFIG_PIN_Y2=11'",
"'-D CAMERA_CONFIG_PIN_VSYNC=6'",
"'-D CAMERA_CONFIG_PIN_HREF=7'",
"'-D CAMERA_CONFIG_PIN_PCLK=13'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x2886",
"0x0056"
],
[
"0x2886",
"0x8056"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"bluetooth",
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32S3_EYE",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.espressif.com/en/products/devkits/esp-eye/overview",
"vendor": "Espressif"
}

View File

@@ -0,0 +1,66 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_ESPRESSIF_ESP_EYE'",
"'-D BOARD_HAS_PSRAM'",
"'-mfix-esp32-psram-cache-issue'",
"'-D USER_LED_GPIO=14'",
"'-D USER_LED_ON_LEVEL=HIGH'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=11'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=17'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=41'",
"'-D CAMERA_CONFIG_PIN_Y9=13'",
"'-D CAMERA_CONFIG_PIN_Y8=4'",
"'-D CAMERA_CONFIG_PIN_Y7=10'",
"'-D CAMERA_CONFIG_PIN_Y6=5'",
"'-D CAMERA_CONFIG_PIN_Y5=7'",
"'-D CAMERA_CONFIG_PIN_Y4=16'",
"'-D CAMERA_CONFIG_PIN_Y3=15'",
"'-D CAMERA_CONFIG_PIN_Y2=6'",
"'-D CAMERA_CONFIG_PIN_VSYNC=42'",
"'-D CAMERA_CONFIG_PIN_HREF=18'",
"'-D CAMERA_CONFIG_PIN_PCLK=12'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=1'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM AI Thinker",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.espressif.com/en/products/devkits/esp-eye/overview",
"vendor": "Espressif"
}

View File

@@ -0,0 +1,70 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32S3_DEV'",
"'-D ARDUINO_USB_MODE=1'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=1'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=15'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=4'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=5'",
"'-D CAMERA_CONFIG_PIN_Y9=16'",
"'-D CAMERA_CONFIG_PIN_Y8=17'",
"'-D CAMERA_CONFIG_PIN_Y7=18'",
"'-D CAMERA_CONFIG_PIN_Y6=12'",
"'-D CAMERA_CONFIG_PIN_Y5=10'",
"'-D CAMERA_CONFIG_PIN_Y4=8'",
"'-D CAMERA_CONFIG_PIN_Y3=9'",
"'-D CAMERA_CONFIG_PIN_Y2=11'",
"'-D CAMERA_CONFIG_PIN_VSYNC=6'",
"'-D CAMERA_CONFIG_PIN_HREF=7'",
"'-D CAMERA_CONFIG_PIN_PCLK=13'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"hwids": [
[
"0x303A",
"0x1001"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32 FREENOVE S3 WROOM",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://github.com/Freenove/Freenove_ESP32_S3_WROOM_Board",
"vendor": "Freenove"
}

View File

@@ -0,0 +1,66 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_WROVER_KIT'",
"'-D BOARD_HAS_PSRAM'",
"'-mfix-esp32-psram-cache-issue'",
"'-D USER_LED_GPIO=2'",
"'-D USER_LED_ON_LEVEL=HIGH'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=21'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=26'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=27'",
"'-D CAMERA_CONFIG_PIN_Y9=35'",
"'-D CAMERA_CONFIG_PIN_Y8=34'",
"'-D CAMERA_CONFIG_PIN_Y7=39'",
"'-D CAMERA_CONFIG_PIN_Y6=36'",
"'-D CAMERA_CONFIG_PIN_Y5=19'",
"'-D CAMERA_CONFIG_PIN_Y4=18'",
"'-D CAMERA_CONFIG_PIN_Y3=5'",
"'-D CAMERA_CONFIG_PIN_Y2=4'",
"'-D CAMERA_CONFIG_PIN_VSYNC=25'",
"'-D CAMERA_CONFIG_PIN_HREF=23'",
"'-D CAMERA_CONFIG_PIN_PCLK=22'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM WROVER kit",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004960637276.html",
"vendor": "Freenove"
}

View File

@@ -0,0 +1,82 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_M5STACK_ATOMS3R'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D USER_LED_GPIO=GPIO_NUM_NC'",
"'-D USER_LED_ON_LEVEL=GPIO_NUM_NC'",
"'-D CAMERA_POWER_GPIO=18'",
"'-D CAMERA_POWER_ON_LEVEL=LOW'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=21'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=12'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=9'",
"'-D CAMERA_CONFIG_PIN_Y9=13'",
"'-D CAMERA_CONFIG_PIN_Y8=11'",
"'-D CAMERA_CONFIG_PIN_Y7=17'",
"'-D CAMERA_CONFIG_PIN_Y6=4'",
"'-D CAMERA_CONFIG_PIN_Y5=48'",
"'-D CAMERA_CONFIG_PIN_Y4=46'",
"'-D CAMERA_CONFIG_PIN_Y3=42'",
"'-D CAMERA_CONFIG_PIN_Y2=3'",
"'-D CAMERA_CONFIG_PIN_VSYNC=10'",
"'-D CAMERA_CONFIG_PIN_HREF=14'",
"'-D CAMERA_CONFIG_PIN_PCLK=40'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'",
"'-D GROVE_SDA=2'",
"'-D GROVE_SCL=1'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x2886",
"0x0056"
],
[
"0x2886",
"0x8056"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"bluetooth",
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "M5STACK ATOMS3R",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.m5stack.com/en/unit/esp32cam",
"vendor": "M5STACK"
}

View File

@@ -0,0 +1,64 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_M5STACK'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=15'",
"'-D CAMERA_CONFIG_PIN_XCLK=27'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'",
"'-D CAMERA_CONFIG_PIN_Y9=19'",
"'-D CAMERA_CONFIG_PIN_Y8=36'",
"'-D CAMERA_CONFIG_PIN_Y7=18'",
"'-D CAMERA_CONFIG_PIN_Y6=39'",
"'-D CAMERA_CONFIG_PIN_Y5=5'",
"'-D CAMERA_CONFIG_PIN_Y4=34'",
"'-D CAMERA_CONFIG_PIN_Y3=35'",
"'-D CAMERA_CONFIG_PIN_Y2=32'",
"'-D CAMERA_CONFIG_PIN_VSYNC=25'",
"'-D CAMERA_CONFIG_PIN_HREF=26'",
"'-D CAMERA_CONFIG_PIN_PCLK=21'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=1'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'",
"'-D GROVE_SDA=13'",
"'-D GROVE_SCL=4'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM M5 STACK",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.m5stack.com/en/unit/m5camera",
"vendor": "M5STACK"
}

View File

@@ -0,0 +1,66 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_M5STACK_CAMERA_PSRAM'",
"'-D BOARD_HAS_PSRAM'",
"'-mfix-esp32-psram-cache-issue'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=15'",
"'-D CAMERA_CONFIG_PIN_XCLK=27'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'",
"'-D CAMERA_CONFIG_PIN_Y9=19'",
"'-D CAMERA_CONFIG_PIN_Y8=36'",
"'-D CAMERA_CONFIG_PIN_Y7=18'",
"'-D CAMERA_CONFIG_PIN_Y6=39'",
"'-D CAMERA_CONFIG_PIN_Y5=5'",
"'-D CAMERA_CONFIG_PIN_Y4=34'",
"'-D CAMERA_CONFIG_PIN_Y3=35'",
"'-D CAMERA_CONFIG_PIN_Y2=32'",
"'-D CAMERA_CONFIG_PIN_VSYNC=22'",
"'-D CAMERA_CONFIG_PIN_HREF=26'",
"'-D CAMERA_CONFIG_PIN_PCLK=21'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'",
"'-D GROVE_SDA=13'",
"'-D GROVE_SCL=4'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM M5 STACK",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.m5stack.com/en/unit/m5camera",
"vendor": "M5STACK"
}

View File

@@ -0,0 +1,69 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_M5STACK_ESP32CAM'",
"'-D BOARD_HAS_PSRAM'",
"'-mfix-esp32-psram-cache-issue'",
"'-D USER_LED_GPIO=16'",
"'-D USER_LED_ON_LEVEL=LOW'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=15'",
"'-D CAMERA_CONFIG_PIN_XCLK=27'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'",
"'-D CAMERA_CONFIG_PIN_Y9=19'",
"'-D CAMERA_CONFIG_PIN_Y8=36'",
"'-D CAMERA_CONFIG_PIN_Y7=18'",
"'-D CAMERA_CONFIG_PIN_Y6=39'",
"'-D CAMERA_CONFIG_PIN_Y5=5'",
"'-D CAMERA_CONFIG_PIN_Y4=34'",
"'-D CAMERA_CONFIG_PIN_Y3=35'",
"'-D CAMERA_CONFIG_PIN_Y2=17'",
"'-D CAMERA_CONFIG_PIN_VSYNC=22'",
"'-D CAMERA_CONFIG_PIN_HREF=26'",
"'-D CAMERA_CONFIG_PIN_PCLK=21'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'",
"'-D MICROPHONE_GPIO=32'",
"'-D GROVE_SDA=13'",
"'-D GROVE_SCL=4'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM M5STACK ESP32CAM",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.m5stack.com/en/unit/esp32cam",
"vendor": "M5STACK"
}

View File

@@ -0,0 +1,64 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_M5STACK_UNITCAM'",
"'-D USER_LED_GPIO=4'",
"'-D USER_LED_ON_LEVEL=LOW'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=15'",
"'-D CAMERA_CONFIG_PIN_XCLK=27'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'",
"'-D CAMERA_CONFIG_PIN_Y9=19'",
"'-D CAMERA_CONFIG_PIN_Y8=36'",
"'-D CAMERA_CONFIG_PIN_Y7=18'",
"'-D CAMERA_CONFIG_PIN_Y6=39'",
"'-D CAMERA_CONFIG_PIN_Y5=5'",
"'-D CAMERA_CONFIG_PIN_Y4=34'",
"'-D CAMERA_CONFIG_PIN_Y3=35'",
"'-D CAMERA_CONFIG_PIN_Y2=32'",
"'-D CAMERA_CONFIG_PIN_VSYNC=22'",
"'-D CAMERA_CONFIG_PIN_HREF=26'",
"'-D CAMERA_CONFIG_PIN_PCLK=21'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=1'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM M5STACK UNITCAM",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.m5stack.com/en/unit/unit_cam",
"vendor": "M5STACK"
}

View File

@@ -0,0 +1,84 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_M5STACK_UNITCAMS3'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D USER_LED_GPIO=14'",
"'-D USER_LED_ON_LEVEL=HIGH'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=21'",
"'-D CAMERA_CONFIG_PIN_XCLK=11'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=17'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=41'",
"'-D CAMERA_CONFIG_PIN_Y9=35'",
"'-D CAMERA_CONFIG_PIN_Y8=34'",
"'-D CAMERA_CONFIG_PIN_Y7=39'",
"'-D CAMERA_CONFIG_PIN_Y6=36'",
"'-D CAMERA_CONFIG_PIN_Y5=19'",
"'-D CAMERA_CONFIG_PIN_Y4=18'",
"'-D CAMERA_CONFIG_PIN_Y3=5'",
"'-D CAMERA_CONFIG_PIN_Y2=4'",
"'-D CAMERA_CONFIG_PIN_VSYNC=25'",
"'-D CAMERA_CONFIG_PIN_HREF=23'",
"'-D CAMERA_CONFIG_PIN_PCLK=22'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'",
"'-D I2C_MEMS_SDA=48'",
"'-D I2C_MEMS_SCL=47'",
"'-D TF_CS=9'",
"'-D TF_MOSI=38'",
"'-D TF_CLK=39'",
"'-D TF_MISO=40'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x2886",
"0x0056"
],
[
"0x2886",
"0x8056"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"bluetooth",
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM M5STACK UNITCAMS3",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.m5stack.com/en/unit/Unit-CamS3",
"vendor": "M5STACK"
}

View File

@@ -0,0 +1,64 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_M5STACK_WIDE'",
"'-D BOARD_HAS_PSRAM'",
"'-mfix-esp32-psram-cache-issue'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=15'",
"'-D CAMERA_CONFIG_PIN_XCLK=27'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=22'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'",
"'-D CAMERA_CONFIG_PIN_Y9=19'",
"'-D CAMERA_CONFIG_PIN_Y8=36'",
"'-D CAMERA_CONFIG_PIN_Y7=18'",
"'-D CAMERA_CONFIG_PIN_Y6=39'",
"'-D CAMERA_CONFIG_PIN_Y5=5'",
"'-D CAMERA_CONFIG_PIN_Y4=34'",
"'-D CAMERA_CONFIG_PIN_Y3=35'",
"'-D CAMERA_CONFIG_PIN_Y2=32'",
"'-D CAMERA_CONFIG_PIN_VSYNC=25'",
"'-D CAMERA_CONFIG_PIN_HREF=26'",
"'-D CAMERA_CONFIG_PIN_PCLK=21'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM M5 STACK WIDE",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://shop.m5stack.com/collections/m5-cameras",
"vendor": "M5STACK"
}

View File

@@ -0,0 +1,84 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_SEEED_XIAO_ESP32S3_SENSE'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D USER_LED_GPIO=21'",
"'-D USER_LED_ON_LEVEL=LOW'",
"'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=10'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=40'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=39'",
"'-D CAMERA_CONFIG_PIN_Y9=48'",
"'-D CAMERA_CONFIG_PIN_Y8=11'",
"'-D CAMERA_CONFIG_PIN_Y7=12'",
"'-D CAMERA_CONFIG_PIN_Y6=14'",
"'-D CAMERA_CONFIG_PIN_Y5=16'",
"'-D CAMERA_CONFIG_PIN_Y4=18'",
"'-D CAMERA_CONFIG_PIN_Y3=17'",
"'-D CAMERA_CONFIG_PIN_Y2=15'",
"'-D CAMERA_CONFIG_PIN_VSYNC=38'",
"'-D CAMERA_CONFIG_PIN_HREF=47'",
"'-D CAMERA_CONFIG_PIN_PCLK=13'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=2'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'",
"'-D I2C_MEMS_SDA=41'",
"'-D I2C_MEMS_SCL=42'",
"'-D TF_CS=21'",
"'-D TF_MOSI=10'",
"'-D TF_CLK=8'",
"'-D TF_MISO=9'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x2886",
"0x0056"
],
[
"0x2886",
"0x8056"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"bluetooth",
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Seeed Studio XIAO ESP32S3 Sense",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.seeedstudio.com/XIAO-ESP32S3-p-5627.html",
"vendor": "Seeed Studio"
}

View File

@@ -0,0 +1,66 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_TTGO_T_CAMERA'",
"'-D CAMERA_CONFIG_PIN_PWDN=26'",
"'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'",
"'-D CAMERA_CONFIG_PIN_XCLK=32'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=13'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=12'",
"'-D CAMERA_CONFIG_PIN_Y9=39'",
"'-D CAMERA_CONFIG_PIN_Y8=36'",
"'-D CAMERA_CONFIG_PIN_Y7=23'",
"'-D CAMERA_CONFIG_PIN_Y6=18'",
"'-D CAMERA_CONFIG_PIN_Y5=15'",
"'-D CAMERA_CONFIG_PIN_Y4=4'",
"'-D CAMERA_CONFIG_PIN_Y3=14'",
"'-D CAMERA_CONFIG_PIN_Y2=5'",
"'-D CAMERA_CONFIG_PIN_VSYNC=27'",
"'-D CAMERA_CONFIG_PIN_HREF=25'",
"'-D CAMERA_CONFIG_PIN_PCLK=19'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=1'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'",
"'-D LCD_SSD1306_PIN_SDA=21'",
"'-D LCD_SSD1306_PIN_SCL=22'",
"'-D BUTTON_RIGHT_PIN=34'",
"'-D PIR_PIN=33'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM TTGO-T-CAMERA",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.lilygo.cc/products/",
"vendor": "LILYGO"
}

View File

@@ -0,0 +1,62 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld",
"partitions": "huge_app.csv"
},
"core": "esp32",
"extra_flags": [
"'-D ESP32CAM_TTGO_T_JOURNAL'",
"'-D CAMERA_CONFIG_PIN_PWDN=0'",
"'-D CAMERA_CONFIG_PIN_RESET=15'",
"'-D CAMERA_CONFIG_PIN_XCLK=27'",
"'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'",
"'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'",
"'-D CAMERA_CONFIG_PIN_Y9=19'",
"'-D CAMERA_CONFIG_PIN_Y8=36'",
"'-D CAMERA_CONFIG_PIN_Y7=18'",
"'-D CAMERA_CONFIG_PIN_Y6=39'",
"'-D CAMERA_CONFIG_PIN_Y5=5'",
"'-D CAMERA_CONFIG_PIN_Y4=34'",
"'-D CAMERA_CONFIG_PIN_Y3=35'",
"'-D CAMERA_CONFIG_PIN_Y2=17'",
"'-D CAMERA_CONFIG_PIN_VSYNC=22'",
"'-D CAMERA_CONFIG_PIN_HREF=26'",
"'-D CAMERA_CONFIG_PIN_PCLK=21'",
"'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'",
"'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'",
"'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'",
"'-D CAMERA_CONFIG_FB_COUNT=1'",
"'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'",
"'-D SCCB_I2C_PORT=I2C_NUM_0'"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "ESP32-CAM TTGO-T-JOURNAL",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.lilygo.cc/products/",
"vendor": "LILYGO"
}

View File

@@ -1,5 +1,4 @@
. python3 -m pip install --upgrade pip setuptools wheel . python3 -m pip install --upgrade pip setuptools wheel
. python3 -m pip install htmlmin . python3 -m pip install minify-html
. python3 ./html_to_cpp.py ./html ./include/html_data.h . python3 ./minify.py ./html/index.html ./html/index.min.html
. python3 ./html_to_cpp_gzip.py ./html_gzip ./include/html_data_gzip.h

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
python3 -m pip install --upgrade pip setuptools wheel
python3 -m pip install htmlmin
python3 ./html_to_cpp.py ./html ./include/html_data.h python3 -m pip install --upgrade pip setuptools wheel
python3 ./html_to_cpp_gzip.py ./html_gzip ./include/html_data_gzip.h python3 -m pip install minify-html
python3 ./minify.py ./html/index.html ./html/index.min.html

View File

@@ -4,310 +4,247 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="bootstrap.min.css"> <style>
html,
body {
font-family: Arial, Verdana, Helvetica, sans-serif;
min-height: 100%;
}
.flex-table {
display: grid;
grid-template-columns: repeat(auto-fill, 25%);
}
.flex-table>.row {
grid-column-start: 2;
grid-column-end: 3;
}
.text-center {
text-align: center;
}
.alert {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
}
.alert-info {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
}
.alert-success {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
}
.alert-warning {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
}
.alert-danger {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
.btn {
display: inline-block;
margin-bottom: 0;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
border: 1px solid transparent;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
border-radius: 4px;
}
.btn-lg {
padding: 10px 16px;
font-size: 18px;
line-height: 1.3333333;
border-radius: 6px;
}
.btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
</style>
<title>{{AppTitle}} v{{AppVersion}}</title> <title>{{AppTitle}} v{{AppVersion}}</title>
</head> </head>
<body> <body>
<div class="container"> <h1 class="text-center">{{ThingName}}</h1>
<h1 class="text-center">{{ThingName}}</h1> <hr>
<hr>
{{#ConfigChanged}} <div class="alert alert-info">
<div class="alert alert-danger" role="alert"> <h3 class="text-center">
<p>The configuration has been changed.</p> Press on the button below to change the settings<br><br>
<p>It is recommended to restart the device.</p> <button type="button" class="btn btn-lg btn-primary" onclick="location.href='config'">Change
settings</button>
</h3>
</div>
<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>
<div>{{ChipModel}} rev. {{ChipRevision}}</div>
<div class="row">CPU speed:</div>
<div>{{CpuFreqMHz}} Mhz</div>
<div class="row">CPU cores:</div>
<div>{{CpuCores}}</div>
<div class="row">RAM size:</div>
<div>{{HeapSize}}</div>
<div class="row">PSRAM size:</div>
<div>{{PsRamSize}}</div>
<div class="row">Flash size:</div>
<div>{{FlashSize}}</div>
</div>
<h2 class="text-center">Diagnostics</h2>
<div class="flex-table">
<div class="row">Uptime:</div>
<div>{{Uptime}}</div>
<div class="row">RTSP sessions:</div>
<div>{{NumRTSPSessions}}</div>
<div class="row">Free heap:</div>
<div>{{FreeHeap}}</div>
<div class="row">Max free block:</div>
<div>{{MaxAllocHeap}}</div>
</div>
<h2 class="text-center">Network</h2>
<div class="flex-table">
<div class="row">Host name:</div>
<div>{{HostName}}</div>
<div class="row">Mac address:</div>
<div>{{MacAddress}}</div>
<div class="row">Wifi mode:</div>
<div>{{WifiMode}}</div>
<div class="row">Access point:</div>
<div>{{AccessPoint}}</div>
<div class="row">Signal strength:</div>
<div>{{SignalStrength}} dbm</div>
<div class="row">IPv4 address:</div>
<div>{{IPv4}}</div>
<div class="row">IPv6 address:</div>
<div>{{IPv6}}</div>
</div>
{{#NetworkState.ApMode}}
<div class="alert alert-warning">
<h3 class="text-center">Not connected to an access point.<br>Consider configuring the access point.</h3>
</div>
{{/NetworkState.ApMode}}
{{#NetworkState.OnLine}}
<div class="alert alert-success">
<h3 class="text-center">Connected to the access point</h3>
</div>
{{/NetworkState.OnLine}}
<h2 class="text-center">Camera</h2>
<div class="flex-table">
<div class="row">Frame rate:</div>
<div>{{FrameDuration}} ms ({{FrameFrequency}} f/s)</div>
<div class="row">Frame size:</div>
<div>{{FrameSize}}</div>
<div class="row">JPEG quality:</div>
<div>{{JpegQuality}} [1-100]</div>
<div class="row">Brightness:</div>
<div>{{Brightness}} [-2,2]</div>
<div class="row">Contrast:</div>
<div>{{Contrast}} [-2,2]</div>
<div class="row">Saturation:</div>
<div>{{Saturation}} [-2,2]</div>
<div class="row">Special effect:</div>
<div>{{SpecialEffect}}</div>
<div class="row">White balance:</div>
<div>{{#WhiteBal}}Auto{{/WhiteBal}}{{^WhiteBal}}Manual{{/WhiteBal}}</div>
<div class="row">AWB gain:</div>
<div>{{#AwbGain}}Auto{{/AwbGain}}{{^AwbGain}}Manual{{/AwbGain}}</div>
<div class="row">WB mode:</div>
<div>{{WbMode}}</div>
<div class="row">Exposure control:</div>
<div>{{#ExposureCtrl}}Auto{{/ExposureCtrl}}{{^ExposureCtrl}}Manual{{/ExposureCtrl}}</div>
<div class="row">Auto exposure control (dsp):</div>
<div>{{#Aec2}}Enabled{{/Aec2}}{{^Aec2}}Disabled{{/Aec2}}</div>
<div class="row">Auto Exposure level:</div>
<div>{{AeLevel}}</div>
<div class="row">Manual exposure value:</div>
<div>{{AecValue}}</div>
<div class="row">Gain control:</div>
<div>{{#GainCtrl}}Auto{{/GainCtrl}}{{^GainCtrl}}Manual{{/GainCtrl}}</div>
<div class="row">AGC gain:</div>
<div>{{AgcGain}}</div>
<div class="row">Gain ceiling:</div>
<div>{{GainCeiling}}</div>
<div class="row">Black pixel correct:</div>
<div>{{#Bpc}}Auto{{/Bpc}}{{^Bpc}}Manual{{/Bpc}}</div>
<div class="row">White pixel correct:</div>
<div>{{#Wpc}}Auto{{/Wpc}}{{^Wpc}}Manual{{/Wpc}}</div>
<div class="row">Gamma correct:</div>
<div>{{#RawGma}}Enabled{{/RawGma}}{{^RawGma}}Disabled{{/RawGma}}</div>
<div class="row">Lens correction:</div>
<div>{{#Lenc}}Enabled{{/Lenc}}{{^Lenc}}Disabled{{/Lenc}}</div>
<div class="row">Horizontal mirror:</div>
<div>{{#HMirror}}Mirrored{{/HMirror}}{{^HMirror}}Normal{{/HMirror}}</div>
<div class="row">Vertical flip:</div>
<div>{{#VFlip}}Flipped{{/VFlip}}{{^VFlip}}Normal{{/VFlip}}</div>
<div class="row">Downsize enable:</div>
<div>{{#Dcw}}Enabled{{/Dcw}}{{^Dcw}}Disabled{{/Dcw}}</div>
<div class="row">Color bar:</div>
<div>{{#ColorBar}}Enabled{{/ColorBar}}{{^ColorBar}}Camera{{/ColorBar}}</div>
</div>
{{#CameraInitialized}}
<div class="alert alert-success">
<h3 class="text-center">Camera was initialized successfully!</h3>
</div>
{{/CameraInitialized}}
{{^CameraInitialized}}
<div class="alert alert-danger">
<h3 class="text-center">Failed to initialize the camera!<br>
Result: {{CameraInitResult}} ({{CameraInitResultText}})<br>
Please check hardware or correct the camera settings and restart.<br><br>
<button type="button" class="btn btn-danger" onclick="location.href='restart'">Restart</button> <button type="button" class="btn btn-danger" onclick="location.href='restart'">Restart</button>
</div> </h3>
{{/ConfigChanged}} </div>
{{/CameraInitialized}}
<div class="row">
<div class="col-sm-6">
<div class="card bg-light mb-3">
<h5 class="card-header">ESP32</h5>
<div class="card-body">
<div class="row">
<div class="col-4">SDK Version:</div>
<div class="col-8">{{SDKVersion}}</div>
</div>
<div class="row">
<div class="col-4">CPU model:</div>
<div class="col-8">{{ChipModel}} rev. {{ChipRevision}}</div>
</div>
<div class="row">
<div class="col-4">CPU speed:</div>
<div class="col-8">{{CpuFreqMHz}} Mhz</div>
</div>
<div class="row">
<div class="col-4">CPU cores:</div>
<div class="col-8">{{CpuCores}}</div>
</div>
<div class="row">
<div class="col-4">RAM size:</div>
<div class="col-8">{{HeapSize}}</div>
</div>
<div class="row">
<div class="col-4">PSRAM size:</div>
<div class="col-8">{{PsRamSize}}</div>
</div>
<div class="row">
<div class="col-4">Flash size:</div>
<div class="col-8">{{FlashSize}}</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card bg-light mb-3">
<h5 class="card-header">Diagnostics</h5>
<div class="card-body">
<div class="row">
<div class="col-4">Uptime:</div>
<div class="col-8">{{Uptime}}</div>
</div>
<div class="row">
<div class="col-4">RTSP sessions:</div>
<div class="col-8">{{NumRTSPSessions}}</div>
</div>
<div class="row">
<div class="col-4">Free heap:</div>
<div class="col-8">{{FreeHeap}}</div>
</div>
<div class="row">
<div class="col-4">Max free block:</div>
<div class="col-8">{{MaxAllocHeap}}</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card bg-light mb-3">
<h5 class="card-header">Peripheral</h5>
<div class="card-body">
<div class="row">
<div class="col-4">Board type:</div>
<div class="col-8">{{BoardType}}</div>
</div>
<div class="row">
<div class="col-4">LED intensity:</div>
<div class="col-8">{{LedIntensity}} [0-100]</div>
</div>
</div>
</div>
<div class="card bg-light mb-3">
<h5 class="card-header">Network</h5>
<div class="card-body">
<div class="row">
<div class="col-4">Host name:</div>
<div class="col-8">{{HostName}}</div>
</div>
<div class="row">
<div class="col-4">Mac address:</div>
<div class="col-8">{{MacAddress}}</div>
</div>
<div class="row">
<div class="col-4">Wifi mode:</div>
<div class="col-8">{{WifiMode}}</div>
</div>
<div class="row">
<div class="col-4">Access point:</div>
<div class="col-8">{{AccessPoint}}</div>
</div>
<div class="row">
<div class="col-4">Signal strength:</div>
<div class="col-8">{{SignalStrength}} dbm</div>
</div>
<div class="row">
<div class="col-4">IPv4 address:</div>
<div class="col-8">{{IpV4}}</div>
</div>
<div class="row">
<div class="col-4">IPv6 address:</div>
<div class="col-8">{{IpV6}}</div>
</div>
{{#NetworkState.ApMode}}
<div class="mt-4 alert alert-warning" role="alert">
<h4 class="text-center">Not connected to an access point.<br>Consider configuring the access point.</h4>
</div>
{{/NetworkState.ApMode}}
{{#NetworkState.OnLine}}
<div class="mt-4 alert alert-success" role="alert">
<h4 class="text-center">Connected to the access point</h4>
</div>
{{/NetworkState.OnLine}}
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card bg-light mb-3">
<h5 class="card-header">Camera</h5>
<div class="card-body">
<div class="row">
<div class="col-4">Frame rate:</div>
<div class="col-8">{{FrameDuration}} ms ({{FrameFrequency}} f/s)</div>
</div>
<div class="row">
<div class="col-4">Frame size:</div>
<div class="col-8">{{FrameSize}}</div>
</div>
<div class="row">
<div class="col-4">JPEG quality:</div>
<div class="col-8">{{JpegQuality}} [1-100]</div>
</div>
<div class="row">
<div class="col-4">Enable PSRAM:</div>
<div class="col-8">{{#EnablePSRAM}}Enabled{{/EnablePSRAM}}{{^EnablePSRAM}}Disabled{{/EnablePSRAM}}</div>
</div>
<div class="row">
<div class="col-4">Number of frame buffers:</div>
<div class="col-8">{{FrameBuffers}}</div>
</div>
<div class="row">
<div class="col-4">Brightness:</div>
<div class="col-8">{{Brightness}} [-2,2]</div>
</div>
<div class="row">
<div class="col-4">Contrast:</div>
<div class="col-8">{{Contrast}} [-2,2]</div>
</div>
<div class="row">
<div class="col-4">Saturation:</div>
<div class="col-8">{{Saturation}} [-2,2]</div>
</div>
<div class="row">
<div class="col-4">Special effect:</div>
<div class="col-8">{{SpecialEffect}}</div>
</div>
<div class="row">
<div class="col-4">White balance:</div>
<div class="col-8">{{#WhiteBal}}Auto{{/WhiteBal}}{{^WhiteBal}}Manual{{/WhiteBal}}</div>
</div>
<div class="row">
<div class="col-4">AWB gain:</div>
<div class="col-8">{{#AwbGain}}Auto{{/AwbGain}}{{^AwbGain}}Manual{{/AwbGain}}</div>
</div>
<div class="row">
<div class="col-4">WB mode:</div>
<div class="col-8">{{WbMode}}</div>
</div>
<div class="row">
<div class="col-4">Exposure control:</div>
<div class="col-8">
{{#ExposureCtrl}}Auto{{/ExposureCtrl}}{{^ExposureCtrl}}Manual{{/ExposureCtrl}}</div>
</div>
<div class="row">
<div class="col-4">Auto exposure control (dsp):</div>
<div class="col-8">{{#Aec2}}Enabled{{/Aec2}}{{^Aec2}}Disabled{{/Aec2}}</div>
</div>
<div class="row">
<div class="col-4">Auto Exposure level:</div>
<div class="col-8">{{AeLevel}}</div>
</div>
<div class="row">
<div class="col-4">Manual exposure value:</div>
<div class="col-8">{{AecValue}}</div>
</div>
<div class="row">
<div class="col-4">Gain control:</div>
<div class="col-8">{{#GainCtrl}}Auto{{/GainCtrl}}{{^GainCtrl}}Manual{{/GainCtrl}}</div>
</div>
<div class="row">
<div class="col-4">AGC gain:</div>
<div class="col-8">{{AgcGain}}</div>
</div>
<div class="row">
<div class="col-4">Gain ceiling:</div>
<div class="col-8">{{GainCeiling}}</div>
</div>
<div class="row">
<div class="col-4">Black pixel correct:</div>
<div class="col-8">{{#Bpc}}Auto{{/Bpc}}{{^Bpc}}Manual{{/Bpc}}</div>
</div>
<div class="row">
<div class="col-4">White pixel correct:</div>
<div class="col-8">{{#Wpc}}Auto{{/Wpc}}{{^Wpc}}Manual{{/Wpc}}</div>
</div>
<div class="row">
<div class="col-4">Gamma correct:</div>
<div class="col-8">{{#RawGma}}Enabled{{/RawGma}}{{^RawGma}}Disabled{{/RawGma}}</div>
</div>
<div class="row">
<div class="col-4">Lens correction:</div>
<div class="col-8">{{#Lenc}}Enabled{{/Lenc}}{{^Lenc}}Disabled{{/Lenc}}</div>
</div>
<div class="row">
<div class="col-4">Horizontal mirror:</div>
<div class="col-8">{{#HMirror}}Mirrored{{/HMirror}}{{^HMirror}}Normal{{/HMirror}}</div>
</div>
<div class="row">
<div class="col-4">Vertical flip:</div>
<div class="col-8">{{#VFlip}}Flipped{{/VFlip}}{{^VFlip}}Normal{{/VFlip}}</div>
</div>
<div class="row">
<div class="col-4">Downsize enable:</div>
<div class="col-8">{{#Dcw}}Enabled{{/Dcw}}{{^Dcw}}Disabled{{/Dcw}}</div>
</div>
<div class="row">
<div class="col-4">Color bar:</div>
<div class="col-8">{{#ColorBar}}Enabled{{/ColorBar}}{{^ColorBar}}Camera{{/ColorBar}}</div>
</div>
{{#CameraInitialized}}
<div class="mt-4 alert alert-success" role="alert">
<h4 class="text-center">Camera was initialized successfully!</h4>
</div>
{{/CameraInitialized}}
{{^CameraInitialized}}
<div class="mt-4 alert alert-danger" role="alert">
<h4 class="text-center">Failed to initialize the camera!</h4>
<p>Result: {{CameraInitResult}} ({{CameraInitResultText}})</p>
<p>Please check hardware or correct the camera settings and restart.</p>
<button type="button" class="btn btn-danger" onclick="location.href='restart'">Restart</button>
</div>
{{/CameraInitialized}}
</div>
</div>
</div>
</div>
<div class="row">
<div class="card bg-light mb-3">
<h5 class="card-header">Special URLs / API</h5>
<div class="card-body">
<div class="row">
<span>
RTSP camera stream: <a href="rtsp://{{IpV4}}:{{RtspPort}}/mjpeg/1">rtsp://{{IpV4}}:{{RtspPort}}/mjpeg/1</a>
</span>
</div>
<div class="row">
<span>
JPEG Motion stream: <a href="http://{{IpV4}}/stream" target="_blank">http://{{IpV4}}/stream</a>
</span>
</div>
<div class="row">
<span>
Snapshot of the camera: <a href="http://{{IpV4}}/snapshot " target="_blank">http://{{IpV4}}/snapshot</a>
</span>
</div>
<div class="row">
<span>
Intensity of the flash led (0-255): <a href="http://{{IpV4}}/flash?v=0">http://{{IpV4}}/flash?v=0</a>. Authentication is required.
</span>
</div>
<div class="row">
<span>
Restart the camera: <a href="http://{{IpV4}}/restart">http://{{IpV4}}/restart</a>. Authentication is required.
</span>
</div>
</div>
</div>
</div>
<div class="d-grid gap-2 col-6 mx-auto">
<button type="button" class="btn btn-lg btn-warning" onclick="location.href='config'">Settings</button>
</div>
<h2 class="text-center">Special URLs / API</h2>
<div class="flex-table">
<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" rel="noopener">http://{{IPv4}}/stream</a></div>
<div class="row">Snapshot of the camera:</div>
<div><a href="http://{{IPv4}}/snapshot " target="_blank" rel="noopener">http://{{IPv4}}/snapshot</a> </div>
</div> </div>
</body> </body>

1
html/index.min.html Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,32 +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">
<link rel="stylesheet" href="bootstrap.min.css">
<meta http-equiv="refresh" content="1;url=/index.html">
<title>{{AppTitle}} v{{AppVersion}}</title>
</head>
<body>
<div class="container">
<h1 class="text-center">{{ThingName}}</h1>
<hr>
<div class="jumbotron bg-light">
<h1 class="display-4 text-center">Restart</h1>
<p class="lead text-center">The device is restarting.</p>
<hr class="my-4 ">
<p class="text-center">In some cases, the device requires a hard reset (power cycle).</p>
<p class="text-center">If this page takes longer than a minute, consider performing a power cycle.</p>
<div class="d-flex justify-content-center">
<div class="spinner-border text-danger" role="status">
<span class="visually-hidden">Restarting...</span>
</div>
</div>
</div>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -1,42 +0,0 @@
#!/usr/bin/python3
import os
import sys
import htmlmin
if (len(sys.argv) <= 2):
print('Usage: html_to_cpp.py <input_dir> <file.h>')
sys.exit(1)
input_dir = sys.argv[1]
file_h = sys.argv[2]
file_names = os.listdir(input_dir)
file_names = filter(lambda x: x[0] != '.' and os.path.isfile(os.path.join(input_dir, x)), file_names)
file_names = sorted(file_names)
output_file = open(file_h, 'w')
output_file.write('//*******************************************************************************\n'
'// HTML import\n'
'// Machine generated file\n'
'// ******************************************************************************\n'
'\n\n')
for file_name in file_names:
print(f'Processing: {file_name}... ')
file_path = os.path.join(input_dir, file_name)
file_data_name = f'file_data_{file_name}'.replace('.', '_')
file = open(file_path, 'r')
html = file.read()
file.close()
html_mimified = htmlmin.minify(html, remove_empty_space=True)
# escape "
html_mimified_escaped = html_mimified.replace('"', '\\"')
output_file.write(f'constexpr char {file_data_name }[] = "{html_mimified_escaped}";\n')
output_file.close()
print('Done.')

View File

@@ -1,46 +0,0 @@
#!/usr/bin/python3
import os
import sys
import htmlmin
import gzip
if (len(sys.argv) <= 2):
print('Usage: bin_to_cpp_gzip.py <input_dir> <file.h>')
sys.exit(1)
input_dir = sys.argv[1]
file_h = sys.argv[2]
file_names = os.listdir(input_dir)
file_names = filter(lambda x: x[0] != '.' and
os.path.isfile(os.path.join(input_dir, x)), file_names)
file_names = sorted(file_names)
output_file = open(file_h, 'w')
output_file.write(
'//*******************************************************************************\n'
'// HTML import gzipped\n'
'// Machine generated file\n'
'// ******************************************************************************\n'
'\n\n')
for file_name in file_names:
print(f'Processing: {file_name}... ')
file_path = os.path.join(input_dir, file_name)
file_data_name = f'file_data_{file_name}'.replace('.', '_')
file = open(file_path, 'r')
html = file.read()
file.close()
html_mimified = htmlmin.minify(html, remove_empty_space=True)
html_mimified_gzip = gzip.compress(bytes(html_mimified, 'utf-8'))
html_mimified_gzip_values = ','.join(f'0x{i:02x}' for i in html_mimified_gzip)
output_file.write(f'constexpr unsigned char {file_data_name}[] = {{\n{html_mimified_gzip_values}\n}};\n\n')
output_file.close()
print('Done.')

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,152 +0,0 @@
#pragma once
#include <string.h>
#include <esp_camera.h>
typedef struct
{
const char name[11];
const camera_config_t config;
} camera_config_entry_t;
constexpr camera_config_t esp32cam_settings = {
.pin_pwdn = -1,
.pin_reset = 15,
.pin_xclk = 27,
.pin_sscb_sda = 25,
.pin_sscb_scl = 23,
.pin_d7 = 19,
.pin_d6 = 36,
.pin_d5 = 18,
.pin_d4 = 39,
.pin_d3 = 5,
.pin_d2 = 34,
.pin_d1 = 35,
.pin_d0 = 17,
.pin_vsync = 22,
.pin_href = 26,
.pin_pclk = 21,
.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 = 2};
constexpr camera_config_t esp32cam_aithinker_settings = {
.pin_pwdn = 32,
.pin_reset = -1,
.pin_xclk = 0,
.pin_sscb_sda = 26,
.pin_sscb_scl = 27,
.pin_d7 = 35,
.pin_d6 = 34,
.pin_d5 = 39,
.pin_d4 = 36,
.pin_d3 = 21,
.pin_d2 = 19,
.pin_d1 = 18,
.pin_d0 = 5,
.pin_vsync = 25,
.pin_href = 23,
.pin_pclk = 22,
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_1,
.ledc_channel = LEDC_CHANNEL_1,
.pixel_format = PIXFORMAT_JPEG,
.frame_size = FRAMESIZE_SVGA,
.jpeg_quality = 12,
.fb_count = 2};
constexpr camera_config_t esp32cam_ttgo_t_settings = {
.pin_pwdn = 26,
.pin_reset = -1,
.pin_xclk = 32,
.pin_sscb_sda = 13,
.pin_sscb_scl = 12,
.pin_d7 = 39,
.pin_d6 = 36,
.pin_d5 = 23,
.pin_d4 = 18,
.pin_d3 = 15,
.pin_d2 = 4,
.pin_d1 = 14,
.pin_d0 = 5,
.pin_vsync = 27,
.pin_href = 25,
.pin_pclk = 19,
.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 = 2};
constexpr camera_config_t esp32cam_m5stack_settings = {
.pin_pwdn = -1,
.pin_reset = 15,
.pin_xclk = 27,
.pin_sscb_sda = 25,
.pin_sscb_scl = 23,
.pin_d7 = 19,
.pin_d6 = 36,
.pin_d5 = 18,
.pin_d4 = 39,
.pin_d3 = 5,
.pin_d2 = 34,
.pin_d1 = 35,
.pin_d0 = 32,
.pin_vsync = 22,
.pin_href = 26,
.pin_pclk = 21,
.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 = 2};
constexpr camera_config_t esp32cam_wrover_kit_settings = {
.pin_pwdn = -1,
.pin_reset = -1,
.pin_xclk = 21,
.pin_sscb_sda = 26,
.pin_sscb_scl = 27,
.pin_d7 = 35,
.pin_d6 = 34,
.pin_d5 = 39,
.pin_d4 = 36,
.pin_d3 = 19,
.pin_d2 = 18,
.pin_d1 = 5,
.pin_d0 = 4,
.pin_vsync = 25,
.pin_href = 23,
.pin_pclk = 22,
.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 = 2};
constexpr const camera_config_entry_t camera_configs[] = {
{"ESP32CAM", esp32cam_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{};
}

View File

@@ -5,23 +5,20 @@
#define WIFI_SSID "ESP32CAM-RTSP" #define WIFI_SSID "ESP32CAM-RTSP"
#define WIFI_PASSWORD nullptr #define WIFI_PASSWORD nullptr
#define CONFIG_VERSION "1.5" #define CONFIG_VERSION "1.6"
#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_FRAME_DURATION 200
#define DEFAULT_ENABLE_PSRAM psramFound() #define DEFAULT_FRAME_SIZE "VGA (640x480)"
#define DEFAULT_BUFFERS (psramFound() ? 2 : 1) #define DEFAULT_JPEG_QUALITY (psramFound() ? 12 : 14)
#define DEFAULT_FRAME_DURATION 100
#define DEFAULT_FRAME_SIZE (psramFound() ? "UXGA (1600x1200)" : "SVGA (800x600)")
#define DEFAULT_JPEG_QUALITY (psramFound() ? 10 : 12)
#define DEFAULT_BRIGHTNESS 0 #define DEFAULT_BRIGHTNESS 0
#define DEFAULT_CONTRAST 0 #define DEFAULT_CONTRAST 0
#define DEFAULT_SATURATION 0 #define DEFAULT_SATURATION 0
#define DEFAULT_EFFECT "Normal" #define DEFAULT_EFFECT "Normal"
#define DEFAULT_WHITE_BALANCE true #define DEFAULT_WHITE_BALANCE true
#define DEFAULT_WHITE_BALANCE_GAIN true #define DEFAULT_WHITE_BALANCE_GAIN true
#define DEFAULT_WHITE_BALANCE_MODE "Auto" #define DEFAULT_WHITE_BALANCE_MODE "Auto"
@@ -41,4 +38,4 @@
#define DEFAULT_DCW true #define DEFAULT_DCW true
#define DEFAULT_COLORBAR false #define DEFAULT_COLORBAR false
#define DEFAULT_LED_INTENSITY 0 #define DEFAULT_LED_INTENSITY 0

View File

@@ -1,8 +1,8 @@
{ {
"name": "RTSPServer", "name": "RTSPServer",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "RTSP Server",
"dependencies": { "dependencies": {
"contrem/arduino-timer": "^2.3.1" "contrem/arduino-timer": "^2.3.1"
} }
} }

View File

@@ -29,7 +29,7 @@ private:
std::shared_ptr<CRtspSession> session; std::shared_ptr<CRtspSession> session;
}; };
OV2640 cam_; OV2640 cam_;
std::list<std::unique_ptr<rtsp_client>> clients_; std::list<std::unique_ptr<rtsp_client>> clients_;
uintptr_t task_; uintptr_t task_;
Timer<> timer_; Timer<> timer_;

20
minify.py Normal file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/python3
import sys
import minify_html
if (len(sys.argv) <= 2):
print('Usage: minify.py input.html output.html')
sys.exit(1)
input_file = open(sys.argv[1], 'r')
output_file = open(sys.argv[2], 'w')
html = input_file.read()
input_file.close()
html_minified = minify_html.minify(html, minify_css=True)
output_file.write(html_minified)
output_file.close()
print('Done.')

View File

@@ -8,15 +8,33 @@
; Please visit documentation for the other options and examples ; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[env:esp32cam] ###############################################################################
[platformio]
#default_envs = esp32cam_ai_thinker
#default_envs = esp32cam_espressif_esp_eye
#default_envs = esp32cam_espressif_esp32s2_cam_board
#default_envs = esp32cam_espressif_esp32s2_cam_header
#default_envs = esp32cam_espressif_esp32s3_cam_lcd
#default_envs = esp32cam_espressif_esp32s3_eye
#default_envs = esp32cam_freenove_wrover_kit
#default_envs = esp32cam_m5stack_camera_psram
#default_envs = esp32cam_m5stack_camera
#default_envs = esp32cam_m5stack_esp32cam
#default_envs = esp32cam_m5stack_unitcam
#default_envs = esp32cam_m5stack_unitcams3
#default_envs = esp32cam_m5stack_wide
#default_envs = esp32cam_seeed_xiao_esp32s3_sense
#default_envs = esp32cam_ttgo_t_camera
#default_envs = esp32cam_ttgo_t_journal
[env]
platform = espressif32 platform = espressif32
board = esp32cam
framework = arduino framework = arduino
#upload_protocol = espota #upload_protocol = espota
#upload_port = 192.168.50.222 #upload_port = 192.168.178.223
#upload_flags = #upload_flags = --auth='ESP32CAM-RTSP'
# --auth='ESP32CAM-RTSP'
# Partition scheme for OTA # Partition scheme for OTA
board_build.partitions = min_spiffs.csv board_build.partitions = min_spiffs.csv
@@ -27,15 +45,70 @@ monitor_dtr = 0
monitor_filters = log2file, time, default, esp32_exception_decoder monitor_filters = log2file, time, default, esp32_exception_decoder
build_flags = build_flags =
-O2 -Ofast
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE -D 'BOARD_NAME="${this.board}"'
-D LED_FLASH=4 -D 'CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE'
-D LED_BUILTIN=33 -D 'IOTWEBCONF_PASSWORD_LEN=64'
-D BOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue board_build.embed_txtfiles =
-D IOTWEBCONF_PASSWORD_LEN=64 html/index.min.html
lib_deps = lib_deps =
prampec/IotWebConf @ ^3.2.1 prampec/IotWebConf@^3.2.1
geeksville/Micro-RTSP @ ^0.1.6 geeksville/Micro-RTSP@^0.1.6
rzeldent/micro-moustache@^1.0.1 rzeldent/micro-moustache@^1.0.1
[env:esp32cam_ai_thinker]
board = esp32cam_ai_thinker
[env:esp32cam_espressif_esp_eye]
board = esp32cam_espressif_esp_eye
[env:esp32cam_espressif_esp32s2_cam_board]
# Use board connection
# The 18 pin header on the board has Y5 and Y3 swapped
board = esp32cam_espressif_esp32s2_cam_board
[env:esp32cam_espressif_esp32s2_cam_header]
# Use header connection
# The 18 pin header on the board has Y5 and Y3 swapped
board = esp32cam_espressif_esp32s2_cam_header
[env:esp32cam_espressif_esp32s3_cam_lcd]
board = esp32cam_espressif_esp32s3_cam_lcd
[env:esp32cam_espressif_esp32s3_eye]
board = esp32cam_espressif_esp32s3_eye
[env:esp32cam_freenove_wrover_kit]
board = esp32cam_freenove_wrover_kit
[env:esp32cam_m5stack_atoms3r]
board = esp32cam_m5stack_atoms3r
[env:esp32cam_m5stack_camera_psram]
board = esp32cam_m5stack_camera_psram
[env:esp32cam_m5stack_camera]
board = esp32cam_m5stack_camera
[env:esp32cam_m5stack_esp32cam]
board = esp32cam_m5stack_esp32cam
[env:esp32cam_m5stack_unitcam]
board = esp32cam_m5stack_unitcam
[env:esp32cam_m5stack_unitcams3]
board = esp32cam_m5stack_unitcams3
[env:esp32cam_m5stack_wide]
board = esp32cam_m5stack_wide
[env:esp32cam_seeed_xiao_esp32s3_sense]
board = esp32cam_seeed_xiao_esp32s3_sense
[env:esp32cam_ttgo_t_camera]
board = esp32cam_ttgo_t_camera
[env:esp32cam_ttgo_t_journal]
board = esp32cam_ttgo_t_journal

View File

@@ -1,12 +1,12 @@
#include <Arduino.h> #include <Arduino.h>
#include <ArduinoOTA.h> #include <esp_wifi.h>
#include <soc/rtc_cntl_reg.h> #include <soc/rtc_cntl_reg.h>
#include <driver/i2c.h>
#include <IotWebConf.h> #include <IotWebConf.h>
#include <IotWebConfTParameter.h> #include <IotWebConfTParameter.h>
#include <OV2640.h> #include <OV2640.h>
#include <ESPmDNS.h> #include <ESPmDNS.h>
#include <rtsp_server.h> #include <rtsp_server.h>
#include <lookup_camera_config.h>
#include <lookup_camera_effect.h> #include <lookup_camera_effect.h>
#include <lookup_camera_frame_size.h> #include <lookup_camera_frame_size.h>
#include <lookup_camera_gainceiling.h> #include <lookup_camera_gainceiling.h>
@@ -14,19 +14,15 @@
#include <format_duration.h> #include <format_duration.h>
#include <format_number.h> #include <format_number.h>
#include <moustache.h> #include <moustache.h>
#include <html_data.h>
#include <html_data_gzip.h>
#include <settings.h> #include <settings.h>
auto param_group_board = iotwebconf::ParameterGroup("board", "Board settings"); // HTML files
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(); extern const char index_html_min_start[] asm("_binary_html_index_min_html_start");
auto param_group_camera = iotwebconf::ParameterGroup("camera", "Camera settings"); 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_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_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_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_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_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_saturation = iotwebconf::Builder<iotwebconf::IntTParameter<int>>("s").label("Saturation").defaultValue(DEFAULT_SATURATION).min(-2).max(2).build();
@@ -50,9 +46,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_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_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;
// DNS Server // DNS Server
@@ -61,23 +54,13 @@ DNSServer dnsServer;
std::unique_ptr<rtsp_server> camera_server; std::unique_ptr<rtsp_server> camera_server;
// Web server // Web server
WebServer web_server(80); WebServer web_server(80);
IotWebConf iotWebConf(WIFI_SSID, &dnsServer, &web_server, WIFI_PASSWORD, CONFIG_VERSION);
// Keep track of config changes. This will allow a reset of the device auto thingName = String(WIFI_SSID) + "-" + String(ESP.getEfuseMac(), 16);
bool config_changed = false; IotWebConf iotWebConf(thingName.c_str(), &dnsServer, &web_server, WIFI_PASSWORD, CONFIG_VERSION);
// Camera initialization result // Camera initialization result
esp_err_t camera_init_result; esp_err_t camera_init_result;
void stream_text_file_gzip(const unsigned char *content, size_t length, const char *mime_type)
{
// Cache for 86400 seconds (one day)
web_server.sendHeader("Cache-Control", "max-age=86400");
web_server.sendHeader("Content-encoding", "gzip");
web_server.setContentLength(length);
web_server.send(200, mime_type, "");
web_server.sendContent(reinterpret_cast<const char *>(content), length);
}
void handle_root() void handle_root()
{ {
log_v("Handle root"); log_v("Handle root");
@@ -92,13 +75,18 @@ void handle_root()
// Wifi Modes // Wifi Modes
const char *wifi_modes[] = {"NULL", "STA", "AP", "STA+AP"}; const char *wifi_modes[] = {"NULL", "STA", "AP", "STA+AP"};
auto ipv4 = WiFi.getMode() == WIFI_MODE_AP ? WiFi.softAPIP() : WiFi.localIP();
auto ipv6 = WiFi.getMode() == WIFI_MODE_AP ? WiFi.softAPIPv6() : WiFi.localIPv6();
auto initResult = esp_err_to_name(camera_init_result);
if (initResult == nullptr)
initResult = "Unknown reason";
moustache_variable_t substitutions[] = { moustache_variable_t substitutions[] = {
// Config Changed?
{"ConfigChanged", String(config_changed)},
// Version / CPU // Version / CPU
{"AppTitle", APP_TITLE}, {"AppTitle", APP_TITLE},
{"AppVersion", APP_VERSION}, {"AppVersion", APP_VERSION},
{"BoardType", BOARD_NAME},
{"ThingName", iotWebConf.getThingName()}, {"ThingName", iotWebConf.getThingName()},
{"SDKVersion", ESP.getSdkVersion()}, {"SDKVersion", ESP.getSdkVersion()},
{"ChipModel", ESP.getChipModel()}, {"ChipModel", ESP.getChipModel()},
@@ -118,22 +106,19 @@ void handle_root()
{"MacAddress", WiFi.macAddress()}, {"MacAddress", WiFi.macAddress()},
{"AccessPoint", WiFi.SSID()}, {"AccessPoint", WiFi.SSID()},
{"SignalStrength", String(WiFi.RSSI())}, {"SignalStrength", String(WiFi.RSSI())},
{"IpV4", WiFi.localIP().toString()},
{"IpV6", WiFi.localIPv6().toString()},
{"WifiMode", wifi_modes[WiFi.getMode()]}, {"WifiMode", wifi_modes[WiFi.getMode()]},
{"IPv4", ipv4.toString()},
{"IPv6", ipv6.toString()},
{"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
{"BoardType", String(param_board.value())},
{"FrameSize", String(param_frame_size.value())}, {"FrameSize", String(param_frame_size.value())},
{"FrameDuration", String(param_frame_duration.value())}, {"FrameDuration", String(param_frame_duration.value())},
{"FrameFrequency", String(1000.0 / param_frame_duration.value(), 1)}, {"FrameFrequency", String(1000.0 / param_frame_duration.value(), 1)},
{"JpegQuality", String(param_jpg_quality.value())}, {"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)}, {"CameraInitialized", String(camera_init_result == ESP_OK)},
{"CameraInitResult", String(camera_init_result)}, {"CameraInitResult", String(camera_init_result)},
{"CameraInitResultText", esp_err_to_name(camera_init_result)}, {"CameraInitResultText", initResult},
// Settings // Settings
{"Brightness", String(param_brightness.value())}, {"Brightness", String(param_brightness.value())},
{"Contrast", String(param_contrast.value())}, {"Contrast", String(param_contrast.value())},
@@ -157,38 +142,14 @@ void handle_root()
{"VFlip", String(param_vflip.value())}, {"VFlip", String(param_vflip.value())},
{"Dcw", String(param_dcw.value())}, {"Dcw", String(param_dcw.value())},
{"ColorBar", String(param_colorbar.value())}, {"ColorBar", String(param_colorbar.value())},
// LED
{"LedIntensity", String(param_led_intensity.value())},
// RTSP // RTSP
{"RtspPort", String(RTSP_PORT)}}; {"RtspPort", String(RTSP_PORT)}};
web_server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); web_server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
auto html = moustache_render(file_data_index_html, substitutions); auto html = moustache_render(index_html_min_start, substitutions);
web_server.send(200, "text/html", html); 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(file_data_restart_html, substitutions);
web_server.send(200, "text/html", html);
log_v("Restarting... Press refresh to connect again");
sleep(100);
ESP.restart();
}
void handle_snapshot() void handle_snapshot()
{ {
log_v("handle_snapshot"); log_v("handle_snapshot");
@@ -199,7 +160,7 @@ void handle_snapshot()
} }
// Remove old images stored in the frame buffer // Remove old images stored in the frame buffer
auto frame_buffers = psramFound() ? 2 : 1; auto frame_buffers = CAMERA_CONFIG_FB_COUNT;
while (frame_buffers--) while (frame_buffers--)
cam.run(); cam.run();
@@ -229,6 +190,7 @@ void handle_stream()
} }
log_v("starting streaming"); log_v("starting streaming");
// Blocks further handling of HTTP server until stopped
char size_buf[12]; char size_buf[12];
auto client = web_server.client(); auto client = web_server.client();
client.write("HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: multipart/x-mixed-replace; boundary=" STREAM_CONTENT_BOUNDARY "\r\n"); client.write("HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: multipart/x-mixed-replace; boundary=" STREAM_CONTENT_BOUNDARY "\r\n");
@@ -247,62 +209,46 @@ void handle_stream()
log_v("stopped streaming"); 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() esp_err_t initialize_camera()
{ {
log_v("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));
log_i("Frame size: %s", param_frame_size.value()); log_i("Frame size: %s", param_frame_size.value());
auto frame_size = lookup_frame_size(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("JPEG quality: %d", param_jpg_quality.value());
auto jpeg_quality = param_jpg_quality.value();
log_i("Frame duration: %d ms", param_frame_duration.value()); log_i("Frame duration: %d ms", param_frame_duration.value());
camera_config.frame_size = frame_size; const camera_config_t camera_config = {
camera_config.jpeg_quality = param_jpg_quality.value(); .pin_pwdn = CAMERA_CONFIG_PIN_PWDN, // GPIO pin for camera power down line
camera_config.grab_mode = CAMERA_GRAB_LATEST; .pin_reset = CAMERA_CONFIG_PIN_RESET, // GPIO pin for camera reset line
log_i("Enable PSRAM: %d", param_enable_psram.value()); .pin_xclk = CAMERA_CONFIG_PIN_XCLK, // GPIO pin for camera XCLK line
log_i("Frame buffers: %d", param_frame_buffers.value()); .pin_sccb_sda = CAMERA_CONFIG_PIN_SCCB_SDA, // GPIO pin for camera SDA line
camera_config.fb_count = param_frame_buffers.value(); .pin_sccb_scl = CAMERA_CONFIG_PIN_SCCB_SCL, // GPIO pin for camera SCL line
.pin_d7 = CAMERA_CONFIG_PIN_Y9, // GPIO pin for camera D7 line
if (param_enable_psram.value() && psramFound()) .pin_d6 = CAMERA_CONFIG_PIN_Y8, // GPIO pin for camera D6 line
{ .pin_d5 = CAMERA_CONFIG_PIN_Y7, // GPIO pin for camera D5 line
camera_config.fb_location = CAMERA_FB_IN_PSRAM; .pin_d4 = CAMERA_CONFIG_PIN_Y6, // GPIO pin for camera D4 line
log_i("PSRAM enabled!"); .pin_d3 = CAMERA_CONFIG_PIN_Y5, // GPIO pin for camera D3 line
} .pin_d2 = CAMERA_CONFIG_PIN_Y4, // GPIO pin for camera D2 line
else .pin_d1 = CAMERA_CONFIG_PIN_Y3, // GPIO pin for camera D1 line
{ .pin_d0 = CAMERA_CONFIG_PIN_Y2, // GPIO pin for camera D0 line
camera_config.fb_location = CAMERA_FB_IN_DRAM; .pin_vsync = CAMERA_CONFIG_PIN_VSYNC, // GPIO pin for camera VSYNC line
log_i("PSRAM disabled"); .pin_href = CAMERA_CONFIG_PIN_HREF, // GPIO pin for camera HREF line
} .pin_pclk = CAMERA_CONFIG_PIN_PCLK, // GPIO pin for camera PCLK line
.xclk_freq_hz = CAMERA_CONFIG_CLK_FREQ_HZ, // Frequency of XCLK signal, in Hz. EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode
.ledc_timer = CAMERA_CONFIG_LEDC_TIMER, // LEDC timer to be used for generating XCLK
.ledc_channel = CAMERA_CONFIG_LEDC_CHANNEL, // LEDC channel to be used for generating XCLK
.pixel_format = PIXFORMAT_JPEG, // Format of the pixel data: PIXFORMAT_ + YUV422|GRAYSCALE|RGB565|JPEG
.frame_size = frame_size, // Size of the output image: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
.jpeg_quality = jpeg_quality, // Quality of JPEG output. 0-63 lower means higher quality
.fb_count = CAMERA_CONFIG_FB_COUNT, // Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed)
.fb_location = CAMERA_CONFIG_FB_LOCATION, // The location where the frame buffer will be allocated
.grab_mode = CAMERA_GRAB_LATEST, // When buffers should be filled
#if CONFIG_CAMERA_CONVERTER_ENABLED
conv_mode = CONV_DISABLE, // RGB<->YUV Conversion mode
#endif
.sccb_i2c_port = SCCB_I2C_PORT // If pin_sccb_sda is -1, use the already configured I2C bus by number
};
return cam.init(camera_config); return cam.init(camera_config);
} }
@@ -344,19 +290,14 @@ void start_rtsp_server()
{ {
log_v("start_rtsp_server"); log_v("start_rtsp_server");
camera_server = std::unique_ptr<rtsp_server>(new rtsp_server(cam, param_frame_duration.value(), RTSP_PORT)); camera_server = std::unique_ptr<rtsp_server>(new rtsp_server(cam, param_frame_duration.value(), RTSP_PORT));
// Add service to mDNS - rtsp // Add RTSP service to mDNS
MDNS.addService("rtsp", "tcp", 554); // HTTP is already set by iotWebConf
MDNS.addService("rtsp", "tcp", RTSP_PORT);
} }
void on_connected() void on_connected()
{ {
log_v("on_connected"); log_v("on_connected");
// Turn LED off (has inverted logic GPIO33) => red LED off => connected
digitalWrite(LED_BUILTIN, true);
// Set flash led intensity
analogWrite(LED_FLASH, param_led_intensity.value());
// Start (OTA) Over The Air programming when connected
ArduinoOTA.begin();
// Start the RTSP Server if initialized // Start the RTSP Server if initialized
if (camera_init_result == ESP_OK) if (camera_init_result == ESP_OK)
start_rtsp_server(); start_rtsp_server();
@@ -367,11 +308,7 @@ void on_connected()
void on_config_saved() void on_config_saved()
{ {
log_v("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(); update_camera_settings();
config_changed = true;
} }
void setup() void setup()
@@ -379,35 +316,37 @@ void setup()
// Disable brownout // Disable brownout
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
pinMode(LED_BUILTIN, OUTPUT); #ifdef CAMERA_POWER_GPIO
// Turn LED on (has inverted logic GPIO33) => red LED on => not connected pinMode(CAMERA_POWER_GPIO, OUTPUT);
digitalWrite(LED_BUILTIN, false); digitalWrite(CAMERA_POWER_GPIO, CAMERA_POWER_ON_LEVEL);
pinMode(LED_FLASH, OUTPUT);
// Turn flash led off
analogWrite(LED_FLASH, 0);
#ifdef CORE_DEBUG_LEVEL
Serial.begin(115200);
Serial.setDebugOutput(true);
#endif #endif
log_i("CPU Freq: %d Mhz", getCpuFrequencyMhz()); #ifdef USER_LED_GPIO
pinMode(USER_LED_GPIO, OUTPUT);
digitalWrite(USER_LED_GPIO, !USER_LED_ON_LEVEL);
#endif
Serial.begin(115200);
Serial.setDebugOutput(true);
#ifdef ARDUINO_USB_CDC_ON_BOOT
// Delay for USB to connect/settle
delay(5000);
#endif
log_i("Core debug level: %d", CORE_DEBUG_LEVEL);
log_i("CPU Freq: %d Mhz, %d core(s)", getCpuFrequencyMhz(), ESP.getChipCores());
log_i("Free heap: %d bytes", ESP.getFreeHeap()); log_i("Free heap: %d bytes", ESP.getFreeHeap());
log_i("SDK version: %s", ESP.getSdkVersion()); log_i("SDK version: %s", ESP.getSdkVersion());
log_i("Board: %s", BOARD_NAME);
log_i("Starting " APP_TITLE "..."); log_i("Starting " APP_TITLE "...");
if (psramFound()) if (CAMERA_CONFIG_FB_LOCATION == CAMERA_FB_IN_PSRAM && !psramInit())
psramInit(); log_e("Failed to initialize PSRAM");
param_group_board.addItem(&param_board);
iotWebConf.addParameterGroup(&param_group_board);
param_group_camera.addItem(&param_frame_duration); param_group_camera.addItem(&param_frame_duration);
param_group_camera.addItem(&param_frame_size); param_group_camera.addItem(&param_frame_size);
param_group_camera.addItem(&param_jpg_quality); param_group_camera.addItem(&param_jpg_quality);
param_group_camera.addItem(&param_enable_psram);
param_group_camera.addItem(&param_frame_buffers);
param_group_camera.addItem(&param_brightness); param_group_camera.addItem(&param_brightness);
param_group_camera.addItem(&param_contrast); param_group_camera.addItem(&param_contrast);
param_group_camera.addItem(&param_saturation); param_group_camera.addItem(&param_saturation);
@@ -432,65 +371,45 @@ void setup()
param_group_camera.addItem(&param_colorbar); param_group_camera.addItem(&param_colorbar);
iotWebConf.addParameterGroup(&param_group_camera); 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);
#ifdef USER_LED_GPIO
iotWebConf.setStatusPin(USER_LED_GPIO, USER_LED_ON_LEVEL);
#endif
iotWebConf.init(); iotWebConf.init();
camera_init_result = initialize_camera(); // Try to initialize 3 times
if (camera_init_result != ESP_OK) for (auto i = 0; i < 3; i++)
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()); {
else camera_init_result = initialize_camera();
update_camera_settings(); if (camera_init_result == ESP_OK)
{
update_camera_settings();
break;
}
esp_camera_deinit();
log_e("Failed to initialize camera. Error: 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());
delay(500);
}
// Set up required URL handlers on the web server // Set up required URL handlers on the web server
web_server.on("/", HTTP_GET, handle_root); web_server.on("/", HTTP_GET, handle_root);
web_server.on("/config", [] web_server.on("/config", []
{ iotWebConf.handleConfig(); }); { iotWebConf.handleConfig(); });
web_server.on("/restart", HTTP_GET, handle_restart);
// Camera snapshot // Camera snapshot
web_server.on("/snapshot", HTTP_GET, handle_snapshot); web_server.on("/snapshot", HTTP_GET, handle_snapshot);
// Camera stream // Camera stream
web_server.on("/stream", HTTP_GET, handle_stream); web_server.on("/stream", HTTP_GET, handle_stream);
// Camera flash light
web_server.on("/flash", HTTP_GET, handle_flash);
// bootstrap
web_server.on("/bootstrap.min.css", HTTP_GET, []()
{ stream_text_file_gzip(file_data_bootstrap_min_css, sizeof(file_data_bootstrap_min_css), "text/css"); });
web_server.onNotFound([]() web_server.onNotFound([]()
{ iotWebConf.handleNotFound(); }); { iotWebConf.handleNotFound(); });
ArduinoOTA
.onStart([]()
{ log_w("Starting OTA update: %s", ArduinoOTA.getCommand() == U_FLASH ? "sketch" : "filesystem"); })
.onEnd([]()
{ log_w("OTA update done!"); })
.onProgress([](unsigned int progress, unsigned int total)
{ log_i("OTA Progress: %u%%\r", (progress / (total / 100))); })
.onError([](ota_error_t error)
{
switch (error)
{
case OTA_AUTH_ERROR: log_e("OTA: Auth Failed"); break;
case OTA_BEGIN_ERROR: log_e("OTA: Begin Failed"); break;
case OTA_CONNECT_ERROR: log_e("OTA: Connect Failed"); break;
case OTA_RECEIVE_ERROR: log_e("OTA: Receive Failed"); break;
case OTA_END_ERROR: log_e("OTA: End Failed"); break;
default: log_e("OTA error: %u", error);
} });
ArduinoOTA.setPassword(OTA_PASSWORD);
} }
void loop() void loop()
{ {
iotWebConf.doLoop(); iotWebConf.doLoop();
ArduinoOTA.handle();
if (camera_server) if (camera_server)
camera_server->doLoop(); camera_server->doLoop();