commit c900c80afb86f3eacf60c8e9d2e9b503b25eb71b Author: Sam Rolfe Date: Fri Sep 25 20:39:33 2026 +1000 Initial commit (secrets isolated) diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..d7f308a --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +secrets.h +.pio/ +build/ +.vscode/ +.idea/ +*.bin +*.elf +*.hex diff --git a/include/README b/include/README new file mode 100755 index 0000000..45496b1 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100755 index 0000000..a10cade --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/lib/esp32cam-rtsp/.gitignore b/lib/esp32cam-rtsp/.gitignore new file mode 100755 index 0000000..63cac60 --- /dev/null +++ b/lib/esp32cam-rtsp/.gitignore @@ -0,0 +1,6 @@ +.*/* +.*.* +__pycache__/ +*.log +.DS_Store +workspace.code-workspace \ No newline at end of file diff --git a/lib/esp32cam-rtsp/README.md b/lib/esp32cam-rtsp/README.md new file mode 100755 index 0000000..edcd053 --- /dev/null +++ b/lib/esp32cam-rtsp/README.md @@ -0,0 +1,382 @@ +# 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) + +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**. + +Supported protocols + +- 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. + 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. + The URL is rtsp://<ip address>:554/mjpeg/1 + +- HTTP Motion JPEG + The HTTP JPEG streamer makes it possible to watch the camera stream directly in your browser. + The URL is http://<ip address>/stream + +- HTTP image + The HTTP Image returns an HTTP JPEG image of the camera. + The URL is http://<ip address>/snapshot + +This software supports the following ESP32-CAM (and alike) modules: + +- AI THINKER +- EspressIf ESP-EYE +- 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 +- Seeed Studio XIAO ESP32S3 SENSE +- TTGO T-CAMERA +- TTGO T-JOURNAL + +The software provides a **configuration web server**, that can be used to: + +- Provide information about the state of the device, wifi connection and camera, +- Set the WiFi parameters, +- Set the timeout for connecting to the access point, +- Set an access password, +- Select the image size, +- Select the frame rate, +- Select the JPEG quality +- Enable the use of the PSRAM +- Set the number of frame buffers +- Configure the camera options: + - Brightness + - Contrast + - Saturation + - Special effect (Normal, Negative, Gray-scale, Red/Green/Blue tint, Sepia) + - White balance + - Automatic White Balance gain + - Wite Balance mode + - Exposure control + - Auto Exposure (dsp) + - Auto Exposure level + - Manual exposure value + - Gain control + - Manual gain control + - Auto gain ceiling + - Black pixel correction + - White pixel correction + - Gamma correction + - Lens correction + - Horizontal mirror + - Vertical flip + - Downside enable + - Color bar + +The software provides contains also a mDNS server to be easily discoverable on the local network. +It advertises HTTP (port 80) and RTSP (port 554) + +## Required + +- ESP32-CAM module or similar, +- USB to Serial (TTL level) converter, piggyback board ESP32-CAM-MB or other way to connect to the device, +- [**PlatformIO**](https://platformio.org/) software (free download) + +## Boards + +There are a lot of boards available that are all called ESP32-CAM. +However, there are differences in CPU (type/speed/cores), how the camera is connected, presence of PSRAM or not... +To select the right board use the table below and use the configuration that is listed below for your board: + +| Board | 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 + +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. + +Install [Visual Studio Code](https://code.visualstudio.com) and install the PlatformIO plugin. + +## Putting the ESP32-CAM in download mode + +### ESP32-CAM-MB + +When using the ESP32-CAM-MB board, press and hold the GP0 button on the ESP32-CAM-MB board. +Then press short the reset button (on the inside) on the ESP32-CAM board and release the GP0 button. +This will put the ESP32-CAM board in download mode. + +### FTDI adapter + +When using an FTDI adapter, make sure the adapter is set to 3.3 volt before connecting. Use the wiring schema below. + +![ESP FTDI wiring](assets/ESP32CAM-to-FTDI.png) + +After programming remove the wire to tge GPIO0 pin to exit the download mode. + +## Compiling and deploying the software + +Open a command line or terminal window and clone this repository from GitHub. + +```sh +git clone https://github.com/rzeldent/esp32cam-rtsp.git +``` + +go into the folder + +```sh +cd esp32cam-rtsp +``` + +Next, the firmware has to be build and deployed to the ESP32. +There are two flavours to do this; using the command line or the graphical interface of Visual Studio Code. + +### Using the command line + +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 +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. +Make sure the ESP32-CAM is in download mode (see previous section) and type: + +```sh + 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. +To monitor the output, start a terminal using: + +```sh + pio device monitor +``` + +### Using Visual studio + +Open the project in a new window. Run the following tasks using the ```Terminal -> Run Task``` or CTRL+ALT+T command in the menu (or use the icons below on the toolbar). Make sure the ESP32-CAM is in download mode during the uploads. + +- PlatformIO: Build (esp32cam) +- PlatformIO: Upload (esp32cam) + +To monitor the behavior run the task, run: ```PlatformIO: Monitor (esp32cam)``` + +## Setting up the ESP32CAM-RTSP + +After the programming of the ESP32, there is no configuration present. This needs to be added. +To connect initially to the device open the WiFi connections and select the WiFi network / access point called **ESP32CAM-RTSP**. +Initially there is no password present. + +After connecting, the browser should automatically open the status page. +In case this does not happens automatically, connect to [http://192.168.4.1](http://192.168.4.1). +This page will display the current settings and status. On the bottom, there is a link to the config. Click on this link. + +This link brings up the configuration screen when connecting fot the first time. + +![Configuration screen](assets/Configuration.png) + +Configure at least: + +- The access point to connect to. No dropdown is present to show available networks! +- A password for accessing the Access point (AP) when starting. (required) +- Type of the ESP32-CAM board + +When finished press ```Apply``` to save the configuration. The screen will redirect to the status screen. +Here it is possible to reboot the device so the settings take effect. +It is also possible to restart manually by pressing the reset button. + +## Connecting to the configuration + +After the initial configuration and the device is connected to an access point, the device can be configured over http. + +When a connection is made to [http://esp32cam-rtsp](http://esp32cam-rtsp) the status screen is shown. + +![Status screen](assets/index.png) + +In case changes have been made to the configuration, this is shown and the possibility to restart is given. + +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. + +## Connecting to the RTSP stream + +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/). + +## 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). + +## 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). + +:bangbang: **Please be aware that there is no password present!**. +Everybody with network access to the device can see the streams or images! Beware of :trollface:! + +## API + +There is a minimum API present to perform some tasks using HTTP requests. For some requests authentication is required. +The authentication used is basic authentication. The user is always admin and the password the access point key.\ +If using a browser, remember that the authentication is stored in the browser session so needs to be entered only once. + +The URLs are below: + +### GET: /restart + +Calling this URL will restart the device. Authentication is required. + +### GET: /config + +Calling this URL will start the form for configuring the device in the browser. Authentication is required. + +### GET: /snapshot + +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. + +## Issues / Nice to know + +- The red LED on the back of the device indicates the device is not connected. +- Sometimes after configuration a reboot is required. + If the error screen is shown that it is unable to make a connection, first try to reboot the device, +- When booting, the device waits 30 seconds for a connection (configurable). + You can make a connection to the SSID and log in using the credentials below, +- When connected, go to the ip of the device and, when prompted for the credentials, enter 'admin' and the AP password. + This is a **required** field before saving the credentials, +- When the password is lost, a fix is to completely erase the ESP32 using the ```pio run -t erase``` command. + This will reset the device including configuration. + If using the esptool, you can do this using ```esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash```. + However, after erasing, re-flashing of the firmware is required. +- When finished configuring for the first time and the access point is entered, disconnect from the wireless network provided by the device. + This should reset the device and connect to the access point. + Resetting is also a good alternative... +- There are modules that have no or faulty PSRAM (despite advertised as such). + This can be the case if the camera fails to initialize. + It might help to disable the use of the PSRAM and reduce the buffers and the screen size. + +### Power + +Make sure the power is 5 volts and stable, although the ESP32 is a 3.3V module, this voltage is created on the board. +If not stable, it has been reported that restarts occur when starting up (probably when power is required for WiFi). +The software disables the brown out protection so there is some margin in the voltage. +Some people suggest to add a capacitor over the 5V input to stabilize the voltage. + +### PSRAM / Buffers / JPEG quality + +Some esp32cam modules have additional ram on the board. This allows to use this ram as frame buffer. +The availability of PSRAM can be seen in the HTML status overview. + +Not all the boards are equipped with PSRAM: + +| Board | PSRAM | +|--- |--- | +| WROVER_KIT | 8Mb | +| ESP_EYE | 8Mb | +| ESP32S3_EYE | 8Mb | +| M5STACK_PSRAM | 8Mb | +| M5STACK_V2_PSRAM | Version B only | +| 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. +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/). +In this case disable the use of PSRAM in the configuration and do not use camera modes that require PSRAM, + +For the setting JPEG quality, a lower number means higher quality. +Be aware that a very high quality (low number) can cause the ESP32 cam to crash or return no image. + +The default settings are: + +- No PSRAM + - SVGA (800x600) + - 1 frame buffer + - JPEG quality 12 + +- With PSRAM + - UXGA (1600x1200) + - 2 frame buffers + - JPEG quality 10 + +### Camera module + +Be careful when connecting the camera module. +Make sure it is connected the right way around (Camera pointing away from the board) and the ribbon cable inserted to the end before locking it. + +## Credits + +esp32cam-rtsp depends on PlatformIO, Bootstrap 5 and Micro-RTSP by Kevin Hester. + +## 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 + - Added options to set PSRAM / Frame buffers + - Added JPEG Motion streaming +- Feb 2023 + - Added additional settings for camera configuration +- Nov 2022 + - Added OTA + - Fix for grabbing frame + - Fixed bug: Increased WiFi password length +- Sep 2022 + - Added GUI with bootstrap + - More information in web page + - Added camera preview in HTML +- Jul 2022 + - Initial version diff --git a/lib/esp32cam-rtsp/assets/Configuration.png b/lib/esp32cam-rtsp/assets/Configuration.png new file mode 100755 index 0000000..ccef624 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/Configuration.png differ diff --git a/lib/esp32cam-rtsp/assets/ESP32CAM-to-FTDI.png b/lib/esp32cam-rtsp/assets/ESP32CAM-to-FTDI.png new file mode 100755 index 0000000..6cb016d Binary files /dev/null and b/lib/esp32cam-rtsp/assets/ESP32CAM-to-FTDI.png differ diff --git a/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam-ipex.jpg b/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam-ipex.jpg new file mode 100755 index 0000000..a819215 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam-ipex.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam-mb.jpg b/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam-mb.jpg new file mode 100755 index 0000000..027ad46 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam-mb.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam.jpg b/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam.jpg new file mode 100755 index 0000000..5cca775 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/ai-thinker-esp32-cam.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/ai_thinker_esp32-cam.jpg b/lib/esp32cam-rtsp/assets/boards/ai_thinker_esp32-cam.jpg new file mode 100755 index 0000000..87f9b3f Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/ai_thinker_esp32-cam.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/datasheets/ov2640_ds_1.8_.pdf b/lib/esp32cam-rtsp/assets/boards/datasheets/ov2640_ds_1.8_.pdf new file mode 100755 index 0000000..3281d2d Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/datasheets/ov2640_ds_1.8_.pdf differ diff --git a/lib/esp32cam-rtsp/assets/boards/esp-lyrap-cam-v1.0-3d.png b/lib/esp32cam-rtsp/assets/boards/esp-lyrap-cam-v1.0-3d.png new file mode 100755 index 0000000..d3f0a6b Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/esp-lyrap-cam-v1.0-3d.png differ diff --git a/lib/esp32cam-rtsp/assets/boards/esp32-wrover-cam.jpg b/lib/esp32cam-rtsp/assets/boards/esp32-wrover-cam.jpg new file mode 100755 index 0000000..f58b5bb Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/esp32-wrover-cam.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/espressif-esp-eye.jpg b/lib/esp32cam-rtsp/assets/boards/espressif-esp-eye.jpg new file mode 100755 index 0000000..8276dd8 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/espressif-esp-eye.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/espressif-esps3-eye.jpg b/lib/esp32cam-rtsp/assets/boards/espressif-esps3-eye.jpg new file mode 100755 index 0000000..79a072e Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/espressif-esps3-eye.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/lilygo-camera-module.jpg b/lib/esp32cam-rtsp/assets/boards/lilygo-camera-module.jpg new file mode 100755 index 0000000..63312e8 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/lilygo-camera-module.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/lilygo-simcam.jpg b/lib/esp32cam-rtsp/assets/boards/lilygo-simcam.jpg new file mode 100755 index 0000000..357f56b Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/lilygo-simcam.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/lilygo-ttgo-t-camera.jpg b/lib/esp32cam-rtsp/assets/boards/lilygo-ttgo-t-camera.jpg new file mode 100755 index 0000000..4415c24 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/lilygo-ttgo-t-camera.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/m5stack-esp32-camera.jpg b/lib/esp32cam-rtsp/assets/boards/m5stack-esp32-camera.jpg new file mode 100755 index 0000000..a240056 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/m5stack-esp32-camera.jpg differ diff --git a/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams3.webp b/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams3.webp new file mode 100755 index 0000000..1945bcf Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams3.webp differ diff --git a/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams32.webp b/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams32.webp new file mode 100755 index 0000000..d70994c Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams32.webp differ diff --git a/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams33webp.webp b/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams33webp.webp new file mode 100755 index 0000000..91a49b4 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/m5stack_Unitcams33webp.webp differ diff --git a/lib/esp32cam-rtsp/assets/boards/m5stack_esp32cam_02.webp b/lib/esp32cam-rtsp/assets/boards/m5stack_esp32cam_02.webp new file mode 100755 index 0000000..d3afa6b Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/m5stack_esp32cam_02.webp differ diff --git a/lib/esp32cam-rtsp/assets/boards/m5stack_unit_cam_02.webp b/lib/esp32cam-rtsp/assets/boards/m5stack_unit_cam_02.webp new file mode 100755 index 0000000..c1db855 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/m5stack_unit_cam_02.webp differ diff --git a/lib/esp32cam-rtsp/assets/boards/m5stack_unit_cam_03.webp b/lib/esp32cam-rtsp/assets/boards/m5stack_unit_cam_03.webp new file mode 100755 index 0000000..2de9f0b Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/m5stack_unit_cam_03.webp differ diff --git a/lib/esp32cam-rtsp/assets/boards/schematics/ESP-LyraP-CAM_V1.1_SCH_20200511A.pdf b/lib/esp32cam-rtsp/assets/boards/schematics/ESP-LyraP-CAM_V1.1_SCH_20200511A.pdf new file mode 100755 index 0000000..65c463e Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/schematics/ESP-LyraP-CAM_V1.1_SCH_20200511A.pdf differ diff --git a/lib/esp32cam-rtsp/assets/boards/schematics/UnitCamS3.png b/lib/esp32cam-rtsp/assets/boards/schematics/UnitCamS3.png new file mode 100755 index 0000000..6f6c874 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/schematics/UnitCamS3.png differ diff --git a/lib/esp32cam-rtsp/assets/boards/schematics/XIAO_ESP32S3_ExpBoard_v1.0_SCH.pdf b/lib/esp32cam-rtsp/assets/boards/schematics/XIAO_ESP32S3_ExpBoard_v1.0_SCH.pdf new file mode 100755 index 0000000..191e552 Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/schematics/XIAO_ESP32S3_ExpBoard_v1.0_SCH.pdf differ diff --git a/lib/esp32cam-rtsp/assets/boards/schematics/ai_thinker_esp32cam.pdf b/lib/esp32cam-rtsp/assets/boards/schematics/ai_thinker_esp32cam.pdf new file mode 100755 index 0000000..e24574b Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/schematics/ai_thinker_esp32cam.pdf differ diff --git a/lib/esp32cam-rtsp/assets/boards/schematics/m5stack_unit_cam_sch_01.webp b/lib/esp32cam-rtsp/assets/boards/schematics/m5stack_unit_cam_sch_01.webp new file mode 100755 index 0000000..80c49dc Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/schematics/m5stack_unit_cam_sch_01.webp differ diff --git a/lib/esp32cam-rtsp/assets/boards/seeed-studio-xiao-esp32s3-sense.jpg b/lib/esp32cam-rtsp/assets/boards/seeed-studio-xiao-esp32s3-sense.jpg new file mode 100755 index 0000000..c70122a Binary files /dev/null and b/lib/esp32cam-rtsp/assets/boards/seeed-studio-xiao-esp32s3-sense.jpg differ diff --git a/lib/esp32cam-rtsp/assets/index.png b/lib/esp32cam-rtsp/assets/index.png new file mode 100755 index 0000000..c21a7aa Binary files /dev/null and b/lib/esp32cam-rtsp/assets/index.png differ diff --git a/lib/esp32cam-rtsp/boards/esp32cam_ai_thinker.json b/lib/esp32cam-rtsp/boards/esp32cam_ai_thinker.json new file mode 100755 index 0000000..5c5fa8c --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_ai_thinker.json @@ -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" +} diff --git a/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s2_cam_board.json b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s2_cam_board.json new file mode 100755 index 0000000..4fb920f --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s2_cam_board.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s2_cam_header.json b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s2_cam_header.json new file mode 100755 index 0000000..212d0a9 --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s2_cam_header.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s3_cam_lcd.json b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s3_cam_lcd.json new file mode 100755 index 0000000..b07fd23 --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s3_cam_lcd.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s3_eye.json b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s3_eye.json new file mode 100755 index 0000000..a65ccbb --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp32s3_eye.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp_eye.json b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp_eye.json new file mode 100755 index 0000000..2b6a722 --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_espressif_esp_eye.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_freenove_s3_wroom_n8r8.json b/lib/esp32cam-rtsp/boards/esp32cam_freenove_s3_wroom_n8r8.json new file mode 100755 index 0000000..f924ca1 --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_freenove_s3_wroom_n8r8.json @@ -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" +} diff --git a/lib/esp32cam-rtsp/boards/esp32cam_freenove_wrover_kit.json b/lib/esp32cam-rtsp/boards/esp32cam_freenove_wrover_kit.json new file mode 100755 index 0000000..3c9b5dd --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_freenove_wrover_kit.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_m5stack_camera.json b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_camera.json new file mode 100755 index 0000000..7ca87cf --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_camera.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_m5stack_camera_psram.json b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_camera_psram.json new file mode 100755 index 0000000..d112035 --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_camera_psram.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_m5stack_esp32cam.json b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_esp32cam.json new file mode 100755 index 0000000..ee41ecf --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_esp32cam.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_m5stack_unitcam.json b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_unitcam.json new file mode 100755 index 0000000..92672be --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_unitcam.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_m5stack_unitcams3.json b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_unitcams3.json new file mode 100755 index 0000000..c29cc6c --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_unitcams3.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_m5stack_wide.json b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_wide.json new file mode 100755 index 0000000..d502897 --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_m5stack_wide.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_seeed_xiao_esp32s3_sense.json b/lib/esp32cam-rtsp/boards/esp32cam_seeed_xiao_esp32s3_sense.json new file mode 100755 index 0000000..ee742bc --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_seeed_xiao_esp32s3_sense.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_ttgo_t_camera.json b/lib/esp32cam-rtsp/boards/esp32cam_ttgo_t_camera.json new file mode 100755 index 0000000..3cd7062 --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_ttgo_t_camera.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/boards/esp32cam_ttgo_t_journal.json b/lib/esp32cam-rtsp/boards/esp32cam_ttgo_t_journal.json new file mode 100755 index 0000000..928ae27 --- /dev/null +++ b/lib/esp32cam-rtsp/boards/esp32cam_ttgo_t_journal.json @@ -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" +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/generate_html.ps1 b/lib/esp32cam-rtsp/generate_html.ps1 new file mode 100755 index 0000000..41885f2 --- /dev/null +++ b/lib/esp32cam-rtsp/generate_html.ps1 @@ -0,0 +1,4 @@ +. python3 -m pip install --upgrade pip setuptools wheel +. python3 -m pip install minify-html + +. python3 ./minify.py ./html/index.html ./html/index.min.html \ No newline at end of file diff --git a/lib/esp32cam-rtsp/generate_html.sh b/lib/esp32cam-rtsp/generate_html.sh new file mode 100755 index 0000000..c313849 --- /dev/null +++ b/lib/esp32cam-rtsp/generate_html.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +python3 -m pip install --upgrade pip setuptools wheel +python3 -m pip install minify-html + +python3 ./minify.py ./html/index.html ./html/index.min.html \ No newline at end of file diff --git a/lib/esp32cam-rtsp/html/index.html b/lib/esp32cam-rtsp/html/index.html new file mode 100755 index 0000000..9452780 --- /dev/null +++ b/lib/esp32cam-rtsp/html/index.html @@ -0,0 +1,252 @@ + + + + + + + + {{AppTitle}} v{{AppVersion}} + + + +

{{ThingName}}

+
+ +
+

+ Press on the button below to change the settings

+ +

+
+ + +

ESP32

+
+
Board type:
+
{{BoardType}}
+
SDK Version:
+
{{SDKVersion}}
+
CPU model:
+
{{ChipModel}} rev. {{ChipRevision}}
+
CPU speed:
+
{{CpuFreqMHz}} Mhz
+
CPU cores:
+
{{CpuCores}}
+
RAM size:
+
{{HeapSize}}
+
PSRAM size:
+
{{PsRamSize}}
+
Flash size:
+
{{FlashSize}}
+
+ +

Diagnostics

+
+
Uptime:
+
{{Uptime}}
+
RTSP sessions:
+
{{NumRTSPSessions}}
+
Free heap:
+
{{FreeHeap}}
+
Max free block:
+
{{MaxAllocHeap}}
+
+ +

Network

+
+
Host name:
+
{{HostName}}
+
Mac address:
+
{{MacAddress}}
+
Wifi mode:
+
{{WifiMode}}
+
Access point:
+
{{AccessPoint}}
+
Signal strength:
+
{{SignalStrength}} dbm
+
IPv4 address:
+
{{IPv4}}
+
IPv6 address:
+
{{IPv6}}
+
+ + {{#NetworkState.ApMode}} +
+

Not connected to an access point.
Consider configuring the access point.

+
+ {{/NetworkState.ApMode}} + + {{#NetworkState.OnLine}} +
+

Connected to the access point

+
+ {{/NetworkState.OnLine}} + +

Camera

+
+
Frame rate:
+
{{FrameDuration}} ms ({{FrameFrequency}} f/s)
+
Frame size:
+
{{FrameSize}}
+
JPEG quality:
+
{{JpegQuality}} [1-100]
+
Brightness:
+
{{Brightness}} [-2,2]
+
Contrast:
+
{{Contrast}} [-2,2]
+
Saturation:
+
{{Saturation}} [-2,2]
+
Special effect:
+
{{SpecialEffect}}
+
White balance:
+
{{#WhiteBal}}Auto{{/WhiteBal}}{{^WhiteBal}}Manual{{/WhiteBal}}
+
AWB gain:
+
{{#AwbGain}}Auto{{/AwbGain}}{{^AwbGain}}Manual{{/AwbGain}}
+
WB mode:
+
{{WbMode}}
+
Exposure control:
+
{{#ExposureCtrl}}Auto{{/ExposureCtrl}}{{^ExposureCtrl}}Manual{{/ExposureCtrl}}
+
Auto exposure control (dsp):
+
{{#Aec2}}Enabled{{/Aec2}}{{^Aec2}}Disabled{{/Aec2}}
+
Auto Exposure level:
+
{{AeLevel}}
+
Manual exposure value:
+
{{AecValue}}
+
Gain control:
+
{{#GainCtrl}}Auto{{/GainCtrl}}{{^GainCtrl}}Manual{{/GainCtrl}}
+
AGC gain:
+
{{AgcGain}}
+
Gain ceiling:
+
{{GainCeiling}}
+
Black pixel correct:
+
{{#Bpc}}Auto{{/Bpc}}{{^Bpc}}Manual{{/Bpc}}
+
White pixel correct:
+
{{#Wpc}}Auto{{/Wpc}}{{^Wpc}}Manual{{/Wpc}}
+
Gamma correct:
+
{{#RawGma}}Enabled{{/RawGma}}{{^RawGma}}Disabled{{/RawGma}}
+
Lens correction:
+
{{#Lenc}}Enabled{{/Lenc}}{{^Lenc}}Disabled{{/Lenc}}
+
Horizontal mirror:
+
{{#HMirror}}Mirrored{{/HMirror}}{{^HMirror}}Normal{{/HMirror}}
+
Vertical flip:
+
{{#VFlip}}Flipped{{/VFlip}}{{^VFlip}}Normal{{/VFlip}}
+
Downsize enable:
+
{{#Dcw}}Enabled{{/Dcw}}{{^Dcw}}Disabled{{/Dcw}}
+
Color bar:
+
{{#ColorBar}}Enabled{{/ColorBar}}{{^ColorBar}}Camera{{/ColorBar}}
+
+ + {{#CameraInitialized}} +
+

Camera was initialized successfully!

+
+ {{/CameraInitialized}} + {{^CameraInitialized}} +
+

Failed to initialize the camera!
+ Result: {{CameraInitResult}} ({{CameraInitResultText}})
+ Please check hardware or correct the camera settings and restart.

+ +

+
+ {{/CameraInitialized}} + + +

Special URLs / API

+
+
RTSP camera stream:
+
rtsp://{{IPv4}}:{{RtspPort}}/mjpeg/1
+
JPEG Motion stream:
+
http://{{IPv4}}/stream
+
Snapshot of the camera:
+
http://{{IPv4}}/snapshot
+
+ + + + \ No newline at end of file diff --git a/lib/esp32cam-rtsp/html/index.min.html b/lib/esp32cam-rtsp/html/index.min.html new file mode 100755 index 0000000..b2b7fc2 --- /dev/null +++ b/lib/esp32cam-rtsp/html/index.min.html @@ -0,0 +1 @@ +{{AppTitle}} v{{AppVersion}}

{{ThingName}}


Press on the button below to change the settings

ESP32

Board type:
{{BoardType}}
SDK Version:
{{SDKVersion}}
CPU model:
{{ChipModel}} rev. {{ChipRevision}}
CPU speed:
{{CpuFreqMHz}} Mhz
CPU cores:
{{CpuCores}}
RAM size:
{{HeapSize}}
PSRAM size:
{{PsRamSize}}
Flash size:
{{FlashSize}}

Diagnostics

Uptime:
{{Uptime}}
RTSP sessions:
{{NumRTSPSessions}}
Free heap:
{{FreeHeap}}
Max free block:
{{MaxAllocHeap}}

Network

Host name:
{{HostName}}
Mac address:
{{MacAddress}}
Wifi mode:
{{WifiMode}}
Access point:
{{AccessPoint}}
Signal strength:
{{SignalStrength}} dbm
IPv4 address:
{{IPv4}}
IPv6 address:
{{IPv6}}
{{#NetworkState.ApMode}}

Not connected to an access point.
Consider configuring the access point.

{{/NetworkState.ApMode}} {{#NetworkState.OnLine}}

Connected to the access point

{{/NetworkState.OnLine}}

Camera

Frame rate:
{{FrameDuration}} ms ({{FrameFrequency}} f/s)
Frame size:
{{FrameSize}}
JPEG quality:
{{JpegQuality}} [1-100]
Brightness:
{{Brightness}} [-2,2]
Contrast:
{{Contrast}} [-2,2]
Saturation:
{{Saturation}} [-2,2]
Special effect:
{{SpecialEffect}}
White balance:
{{#WhiteBal}}Auto{{/WhiteBal}}{{^WhiteBal}}Manual{{/WhiteBal}}
AWB gain:
{{#AwbGain}}Auto{{/AwbGain}}{{^AwbGain}}Manual{{/AwbGain}}
WB mode:
{{WbMode}}
Exposure control:
{{#ExposureCtrl}}Auto{{/ExposureCtrl}}{{^ExposureCtrl}}Manual{{/ExposureCtrl}}
Auto exposure control (dsp):
{{#Aec2}}Enabled{{/Aec2}}{{^Aec2}}Disabled{{/Aec2}}
Auto Exposure level:
{{AeLevel}}
Manual exposure value:
{{AecValue}}
Gain control:
{{#GainCtrl}}Auto{{/GainCtrl}}{{^GainCtrl}}Manual{{/GainCtrl}}
AGC gain:
{{AgcGain}}
Gain ceiling:
{{GainCeiling}}
Black pixel correct:
{{#Bpc}}Auto{{/Bpc}}{{^Bpc}}Manual{{/Bpc}}
White pixel correct:
{{#Wpc}}Auto{{/Wpc}}{{^Wpc}}Manual{{/Wpc}}
Gamma correct:
{{#RawGma}}Enabled{{/RawGma}}{{^RawGma}}Disabled{{/RawGma}}
Lens correction:
{{#Lenc}}Enabled{{/Lenc}}{{^Lenc}}Disabled{{/Lenc}}
Horizontal mirror:
{{#HMirror}}Mirrored{{/HMirror}}{{^HMirror}}Normal{{/HMirror}}
Vertical flip:
{{#VFlip}}Flipped{{/VFlip}}{{^VFlip}}Normal{{/VFlip}}
Downsize enable:
{{#Dcw}}Enabled{{/Dcw}}{{^Dcw}}Disabled{{/Dcw}}
Color bar:
{{#ColorBar}}Enabled{{/ColorBar}}{{^ColorBar}}Camera{{/ColorBar}}
{{#CameraInitialized}}

Camera was initialized successfully!

{{/CameraInitialized}} {{^CameraInitialized}}

Failed to initialize the camera!
Result: {{CameraInitResult}} ({{CameraInitResultText}})
Please check hardware or correct the camera settings and restart.

{{/CameraInitialized}}

Special URLs / API

RTSP camera stream:
rtsp://{{IPv4}}:{{RtspPort}}/mjpeg/1
JPEG Motion stream:
http://{{IPv4}}/stream
Snapshot of the camera:
http://{{IPv4}}/snapshot
\ No newline at end of file diff --git a/lib/esp32cam-rtsp/include/README b/lib/esp32cam-rtsp/include/README new file mode 100755 index 0000000..194dcd4 --- /dev/null +++ b/lib/esp32cam-rtsp/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/esp32cam-rtsp/include/format_duration.h b/lib/esp32cam-rtsp/include/format_duration.h new file mode 100755 index 0000000..a2dbb2d --- /dev/null +++ b/lib/esp32cam-rtsp/include/format_duration.h @@ -0,0 +1,11 @@ +#pragma once + +String format_duration(time_t seconds) +{ + auto days = seconds / (60 * 60 * 24); + auto tm = gmtime(&seconds); + String duration = days > 0 ? String(days) + " days, " : ""; + char time_buff[9]; + strftime(time_buff, 9, "%H:%M:%S", tm); + return duration + time_buff; +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/include/format_number.h b/lib/esp32cam-rtsp/include/format_number.h new file mode 100755 index 0000000..fc1f5d5 --- /dev/null +++ b/lib/esp32cam-rtsp/include/format_number.h @@ -0,0 +1,72 @@ +#pragma once + +#include + +String format_value(double value) +{ + if (value == 0.0) + return "0"; + + if (value < 0) + return "-" + format_value(-value); + + // No decimal places + if (value >= 1) + return String(value, 0); + if (value < 0.00001) + return String(value, 6); + if (value < 0.0001) + return String(value, 5); + if (value < 0.001) + return String(value, 4); + if (value < 0.01) + return String(value, 3); + if (value < 0.1) + return String(value, 2); + return String(value, 1); +} + +String format_si(double value, int decimal_places = 2) +{ + if (value == 0.0) + return "0"; + + if (value < 0) + return "-" + format_si(-value, decimal_places); + + auto value_abs = fabs(value); + if (value_abs < 1E-9) + return String(value * 1E12, decimal_places) + "p"; + if (value_abs < 1E-6) + return String(value * 1E9, decimal_places) + "n"; + if (value_abs < 1E-3) + return String(value * 1E6, decimal_places) + "u"; + if (value_abs < 1) + return String(value * 1E3, decimal_places) + "m"; + if (value_abs < 1E3) + return String(value, decimal_places); + if (value_abs < 1E6) + return String(value / 1E3, decimal_places) + "k"; + if (value_abs < 1E9) + return String(value / 1E6, decimal_places) + "M"; + if (value_abs < 1E12) + return String(value / 1E9, decimal_places) + "G"; + if (value_abs < 1E15) + return String(value / 1E12, decimal_places) + "T"; + + return "NaN"; +} + +String format_memory(size_t bytes, int decimal_places = 2) +{ + const char *suffix[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}; + auto val = (double)bytes; + auto suffix_index = 0; + while (val >= 1024.0) + { + val /= 1024; + suffix_index++; + } + + return String(val, decimal_places) + " " + suffix[suffix_index]; +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/include/lookup_camera_effect.h b/lib/esp32cam-rtsp/include/lookup_camera_effect.h new file mode 100755 index 0000000..f5db06e --- /dev/null +++ b/lib/esp32cam-rtsp/include/lookup_camera_effect.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +typedef struct +{ + const char name[11]; + const int value; +} camera_effect_entry_t; + +constexpr const camera_effect_entry_t camera_effects[] = { + {"Normal", 0}, + {"Negative", 1}, + {"Grayscale", 2}, + {"Red tint", 3}, + {"Green tint", 4}, + {"Blue tint", 5}, + {"Sepia", 6}}; + +const int lookup_camera_effect(const char *name) +{ + // Lookup table for the frame name to framesize_t + for (const auto &entry : camera_effects) + if (strncmp(entry.name, name, sizeof(entry.name)) == 0) + return entry.value; + + return 0; +} diff --git a/lib/esp32cam-rtsp/include/lookup_camera_frame_size.h b/lib/esp32cam-rtsp/include/lookup_camera_frame_size.h new file mode 100755 index 0000000..fd5a2b5 --- /dev/null +++ b/lib/esp32cam-rtsp/include/lookup_camera_frame_size.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +typedef struct frame_size_entry +{ + const char name[17]; + const framesize_t frame_size; +} frame_size_entry_t; + +constexpr const frame_size_entry_t frame_sizes[] = { + {"QQVGA (160x120)", FRAMESIZE_QQVGA}, + {"QCIF (176x144)", FRAMESIZE_QCIF}, + {"HQVGA (240x176)", FRAMESIZE_HQVGA}, + {"240x240", FRAMESIZE_240X240}, + {"QVGA (320x240)", FRAMESIZE_QVGA}, + {"CIF (400x296)", FRAMESIZE_CIF}, + {"HVGA (480x320)", FRAMESIZE_HVGA}, + {"VGA (640x480)", FRAMESIZE_VGA}, + {"SVGA (800x600)", FRAMESIZE_SVGA}, + {"XGA (1024x768)", FRAMESIZE_XGA}, + {"HD (1280x720)", FRAMESIZE_HD}, + {"SXGA (1280x1024)", FRAMESIZE_SXGA}, + {"UXGA (1600x1200)", FRAMESIZE_UXGA}}; + +const framesize_t lookup_frame_size(const char *pin) +{ + // Lookup table for the frame name to framesize_t + for (const auto &entry : frame_sizes) + if (strncmp(entry.name, pin, sizeof(entry.name)) == 0) + return entry.frame_size; + + return FRAMESIZE_INVALID; +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/include/lookup_camera_gainceiling.h b/lib/esp32cam-rtsp/include/lookup_camera_gainceiling.h new file mode 100755 index 0000000..4c7b3de --- /dev/null +++ b/lib/esp32cam-rtsp/include/lookup_camera_gainceiling.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +typedef struct +{ + const char name[5]; + const gainceiling_t value; +} camera_gainceiling_entry_t; + +constexpr const camera_gainceiling_entry_t camera_gain_ceilings[] = { + {"2X", GAINCEILING_2X}, + {"4X", GAINCEILING_4X}, + {"8X", GAINCEILING_8X}, + {"16X", GAINCEILING_16X}, + {"32X", GAINCEILING_32X}, + {"64X", GAINCEILING_64X}, + {"128X", GAINCEILING_128X}}; + +const gainceiling_t lookup_camera_gainceiling(const char *name) +{ + // Lookup table for the frame name to framesize_t + for (const auto &entry : camera_gain_ceilings) + if (strncmp(entry.name, name, sizeof(entry.name)) == 0) + return entry.value; + + return GAINCEILING_2X; +} diff --git a/lib/esp32cam-rtsp/include/lookup_camera_wb_mode.h b/lib/esp32cam-rtsp/include/lookup_camera_wb_mode.h new file mode 100755 index 0000000..affd29c --- /dev/null +++ b/lib/esp32cam-rtsp/include/lookup_camera_wb_mode.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +typedef struct +{ + const char name[7]; + const int value; +} camera_wb_mode_entry_t; + +constexpr const camera_wb_mode_entry_t camera_wb_modes[] = { + {"Auto", 0}, + {"Sunny", 1}, + {"Cloudy", 2}, + {"Office", 3}, + {"Home", 4}}; + +const int lookup_camera_wb_mode(const char *name) +{ + // Lookup table for the frame name to framesize_t + for (const auto &entry : camera_wb_modes) + if (strncmp(entry.name, name, sizeof(entry.name)) == 0) + return entry.value; + + return 0; +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/include/settings.h b/lib/esp32cam-rtsp/include/settings.h new file mode 100755 index 0000000..9422efa --- /dev/null +++ b/lib/esp32cam-rtsp/include/settings.h @@ -0,0 +1,41 @@ +#pragma once + +#define APP_TITLE "ESP32CAM-RTSP" +#define APP_VERSION "1.0" + +#define WIFI_SSID "ESP32CAM-RTSP" +#define WIFI_PASSWORD nullptr +#define CONFIG_VERSION "1.6" + +#define OTA_PASSWORD "ESP32CAM-RTSP" + +#define RTSP_PORT 554 + +#define DEFAULT_FRAME_DURATION 200 +#define DEFAULT_FRAME_SIZE "VGA (640x480)" +#define DEFAULT_JPEG_QUALITY (psramFound() ? 12 : 14) + +#define DEFAULT_BRIGHTNESS 0 +#define DEFAULT_CONTRAST 0 +#define DEFAULT_SATURATION 0 +#define DEFAULT_EFFECT "Normal" +#define DEFAULT_WHITE_BALANCE true +#define DEFAULT_WHITE_BALANCE_GAIN true +#define DEFAULT_WHITE_BALANCE_MODE "Auto" +#define DEFAULT_EXPOSURE_CONTROL true +#define DEFAULT_AEC2 true +#define DEFAULT_AE_LEVEL 0 +#define DEFAULT_AEC_VALUE 300 +#define DEFAULT_GAIN_CONTROL true +#define DEFAULT_AGC_GAIN 0 +#define DEFAULT_GAIN_CEILING "2X" +#define DEFAULT_BPC false +#define DEFAULT_WPC true +#define DEFAULT_RAW_GAMMA true +#define DEFAULT_LENC true +#define DEFAULT_HORIZONTAL_MIRROR false +#define DEFAULT_VERTICAL_MIRROR false +#define DEFAULT_DCW true +#define DEFAULT_COLORBAR false + +#define DEFAULT_LED_INTENSITY 0 \ No newline at end of file diff --git a/lib/esp32cam-rtsp/lib/README b/lib/esp32cam-rtsp/lib/README new file mode 100755 index 0000000..6debab1 --- /dev/null +++ b/lib/esp32cam-rtsp/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/lib/esp32cam-rtsp/lib/rtsp_server/library.json b/lib/esp32cam-rtsp/lib/rtsp_server/library.json new file mode 100755 index 0000000..15009f2 --- /dev/null +++ b/lib/esp32cam-rtsp/lib/rtsp_server/library.json @@ -0,0 +1,8 @@ +{ + "name": "RTSPServer", + "version": "1.0.0", + "description": "RTSP Server", + "dependencies": { + "contrem/arduino-timer": "^2.3.1" + } +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/lib/rtsp_server/rtsp_server.cpp b/lib/esp32cam-rtsp/lib/rtsp_server/rtsp_server.cpp new file mode 100755 index 0000000..826edc9 --- /dev/null +++ b/lib/esp32cam-rtsp/lib/rtsp_server/rtsp_server.cpp @@ -0,0 +1,51 @@ +#include "rtsp_server.h" +#include +#include + +// URI: e.g. rtsp://192.168.178.27:554/mjpeg/1 +rtsp_server::rtsp_server(OV2640 &cam, unsigned long interval, int port /*= 554*/) + : WiFiServer(port), cam_(cam) +{ + log_i("Starting RTSP server"); + WiFiServer::begin(); + timer_.every(interval, client_handler, this); +} +size_t rtsp_server::num_connected() +{ + return clients_.size(); +} + +void rtsp_server::doLoop() +{ + timer_.tick(); +} + +rtsp_server::rtsp_client::rtsp_client(const WiFiClient &client, OV2640 &cam) +{ + wifi_client = client; + streamer = std::shared_ptr(new OV2640Streamer(&wifi_client, cam)); + session = std::shared_ptr(new CRtspSession(&wifi_client, streamer.get())); +} + +bool rtsp_server::client_handler(void *arg) +{ + auto self = static_cast(arg); + // Check if a client wants to connect + auto new_client = self->accept(); + if (new_client) + self->clients_.push_back(std::unique_ptr(new rtsp_client(new_client, self->cam_))); + + auto now = millis(); + for (const auto &client : self->clients_) + { + // Handle requests + client->session->handleRequests(0); + // Send the frame. For now return the uptime as time marker, currMs + client->session->broadcastCurrentFrame(now); + } + + self->clients_.remove_if([](std::unique_ptr const &c) + { return c->session->m_stopped; }); + + return true; +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/lib/rtsp_server/rtsp_server.h b/lib/esp32cam-rtsp/lib/rtsp_server/rtsp_server.h new file mode 100755 index 0000000..63e207a --- /dev/null +++ b/lib/esp32cam-rtsp/lib/rtsp_server/rtsp_server.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +class rtsp_server : public WiFiServer +{ +public: + rtsp_server(OV2640 &cam, unsigned long interval, int port = 554); + + void doLoop(); + + size_t num_connected(); + +private: + struct rtsp_client + { + public: + rtsp_client(const WiFiClient &client, OV2640 &cam); + + WiFiClient wifi_client; + // Streamer for UDP/TCP based RTP transport + std::shared_ptr streamer; + // RTSP session and state + std::shared_ptr session; + }; + + OV2640 cam_; + std::list> clients_; + uintptr_t task_; + Timer<> timer_; + + static bool client_handler(void *); +}; \ No newline at end of file diff --git a/lib/esp32cam-rtsp/minify.py b/lib/esp32cam-rtsp/minify.py new file mode 100755 index 0000000..965e887 --- /dev/null +++ b/lib/esp32cam-rtsp/minify.py @@ -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.') \ No newline at end of file diff --git a/lib/esp32cam-rtsp/platformio.ini b/lib/esp32cam-rtsp/platformio.ini new file mode 100755 index 0000000..3f722ef --- /dev/null +++ b/lib/esp32cam-rtsp/platformio.ini @@ -0,0 +1,111 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +############################################################################### +[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 +framework = arduino + +#upload_protocol = espota +#upload_port = 192.168.178.223 +#upload_flags = --auth='ESP32CAM-RTSP' + +# Partition scheme for OTA +board_build.partitions = min_spiffs.csv + +monitor_speed = 115200 +monitor_rts = 0 +monitor_dtr = 0 +monitor_filters = log2file, time, default, esp32_exception_decoder + +build_flags = + -Ofast + -D 'BOARD_NAME="${this.board}"' + -D 'CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE' + -D 'IOTWEBCONF_PASSWORD_LEN=64' + +board_build.embed_txtfiles = + html/index.min.html + +lib_deps = + prampec/IotWebConf@^3.2.1 + geeksville/Micro-RTSP@^0.1.6 + rzeldent/micro-moustache@^1.0.1 + +[env: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_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 \ No newline at end of file diff --git a/lib/esp32cam-rtsp/src/main.cpp b/lib/esp32cam-rtsp/src/main.cpp new file mode 100755 index 0000000..8899780 --- /dev/null +++ b/lib/esp32cam-rtsp/src/main.cpp @@ -0,0 +1,411 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// HTML files +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_frame_duration = iotwebconf::Builder>("fd").label("Frame duration (ms)").defaultValue(DEFAULT_FRAME_DURATION).min(10).build(); +auto param_frame_size = iotwebconf::Builder>("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>("q").label("JPG quality").defaultValue(DEFAULT_JPEG_QUALITY).min(1).max(100).build(); +auto param_brightness = iotwebconf::Builder>("b").label("Brightness").defaultValue(DEFAULT_BRIGHTNESS).min(-2).max(2).build(); +auto param_contrast = iotwebconf::Builder>("c").label("Contrast").defaultValue(DEFAULT_CONTRAST).min(-2).max(2).build(); +auto param_saturation = iotwebconf::Builder>("s").label("Saturation").defaultValue(DEFAULT_SATURATION).min(-2).max(2).build(); +auto param_special_effect = iotwebconf::Builder>("e").label("Effect").optionValues((const char *)&camera_effects).optionNames((const char *)&camera_effects).optionCount(sizeof(camera_effects) / sizeof(camera_effects[0])).nameLength(sizeof(camera_effects[0])).defaultValue(DEFAULT_EFFECT).build(); +auto param_whitebal = iotwebconf::Builder("wb").label("White balance").defaultValue(DEFAULT_WHITE_BALANCE).build(); +auto param_awb_gain = iotwebconf::Builder("awbg").label("Automatic white balance gain").defaultValue(DEFAULT_WHITE_BALANCE_GAIN).build(); +auto param_wb_mode = iotwebconf::Builder>("wbm").label("White balance mode").optionValues((const char *)&camera_wb_modes).optionNames((const char *)&camera_wb_modes).optionCount(sizeof(camera_wb_modes) / sizeof(camera_wb_modes[0])).nameLength(sizeof(camera_wb_modes[0])).defaultValue(DEFAULT_WHITE_BALANCE_MODE).build(); +auto param_exposure_ctrl = iotwebconf::Builder("ec").label("Exposure control").defaultValue(DEFAULT_EXPOSURE_CONTROL).build(); +auto param_aec2 = iotwebconf::Builder("aec2").label("Auto exposure (dsp)").defaultValue(DEFAULT_AEC2).build(); +auto param_ae_level = iotwebconf::Builder>("ael").label("Auto Exposure level").defaultValue(DEFAULT_AE_LEVEL).min(-2).max(2).build(); +auto param_aec_value = iotwebconf::Builder>("aecv").label("Manual exposure value").defaultValue(DEFAULT_AEC_VALUE).min(9).max(1200).build(); +auto param_gain_ctrl = iotwebconf::Builder("gc").label("Gain control").defaultValue(DEFAULT_GAIN_CONTROL).build(); +auto param_agc_gain = iotwebconf::Builder>("agcg").label("AGC gain").defaultValue(DEFAULT_AGC_GAIN).min(0).max(30).build(); +auto param_gain_ceiling = iotwebconf::Builder>("gcl").label("Auto Gain ceiling").optionValues((const char *)&camera_gain_ceilings).optionNames((const char *)&camera_gain_ceilings).optionCount(sizeof(camera_gain_ceilings) / sizeof(camera_gain_ceilings[0])).nameLength(sizeof(camera_gain_ceilings[0])).defaultValue(DEFAULT_GAIN_CEILING).build(); +auto param_bpc = iotwebconf::Builder("bpc").label("Black pixel correct").defaultValue(DEFAULT_BPC).build(); +auto param_wpc = iotwebconf::Builder("wpc").label("White pixel correct").defaultValue(DEFAULT_WPC).build(); +auto param_raw_gma = iotwebconf::Builder("rg").label("Gamma correct").defaultValue(DEFAULT_RAW_GAMMA).build(); +auto param_lenc = iotwebconf::Builder("lenc").label("Lens correction").defaultValue(DEFAULT_LENC).build(); +auto param_hmirror = iotwebconf::Builder("hm").label("Horizontal mirror").defaultValue(DEFAULT_HORIZONTAL_MIRROR).build(); +auto param_vflip = iotwebconf::Builder("vm").label("Vertical mirror").defaultValue(DEFAULT_VERTICAL_MIRROR).build(); +auto param_dcw = iotwebconf::Builder("dcw").label("Downsize enable").defaultValue(DEFAULT_DCW).build(); +auto param_colorbar = iotwebconf::Builder("cb").label("Colorbar").defaultValue(DEFAULT_COLORBAR).build(); + +// Camera +OV2640 cam; +// DNS Server +DNSServer dnsServer; +// RTSP Server +std::unique_ptr camera_server; +// Web server +WebServer web_server(80); + +auto thingName = String(WIFI_SSID) + "-" + String(ESP.getEfuseMac(), 16); +IotWebConf iotWebConf(thingName.c_str(), &dnsServer, &web_server, WIFI_PASSWORD, CONFIG_VERSION); + +// Camera initialization result +esp_err_t camera_init_result; + +void handle_root() +{ + log_v("Handle root"); + // Let IotWebConf test and handle captive portal requests. + if (iotWebConf.handleCaptivePortal()) + return; + + // Format hostname + auto hostname = "esp32-" + WiFi.macAddress() + ".local"; + hostname.replace(":", ""); + hostname.toLowerCase(); + + // Wifi Modes + 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[] = { + // Version / CPU + {"AppTitle", APP_TITLE}, + {"AppVersion", APP_VERSION}, + {"BoardType", BOARD_NAME}, + {"ThingName", iotWebConf.getThingName()}, + {"SDKVersion", ESP.getSdkVersion()}, + {"ChipModel", ESP.getChipModel()}, + {"ChipRevision", String(ESP.getChipRevision())}, + {"CpuFreqMHz", String(ESP.getCpuFreqMHz())}, + {"CpuCores", String(ESP.getChipCores())}, + {"FlashSize", format_memory(ESP.getFlashChipSize(), 0)}, + {"HeapSize", format_memory(ESP.getHeapSize())}, + {"PsRamSize", format_memory(ESP.getPsramSize(), 0)}, + // Diagnostics + {"Uptime", String(format_duration(millis() / 1000))}, + {"FreeHeap", format_memory(ESP.getFreeHeap())}, + {"MaxAllocHeap", format_memory(ESP.getMaxAllocHeap())}, + {"NumRTSPSessions", camera_server != nullptr ? String(camera_server->num_connected()) : "RTSP server disabled"}, + // Network + {"HostName", hostname}, + {"MacAddress", WiFi.macAddress()}, + {"AccessPoint", WiFi.SSID()}, + {"SignalStrength", String(WiFi.RSSI())}, + {"WifiMode", wifi_modes[WiFi.getMode()]}, + {"IPv4", ipv4.toString()}, + {"IPv6", ipv6.toString()}, + {"NetworkState.ApMode", String(iotWebConf.getState() == iotwebconf::NetworkState::ApMode)}, + {"NetworkState.OnLine", String(iotWebConf.getState() == iotwebconf::NetworkState::OnLine)}, + // Camera + {"FrameSize", String(param_frame_size.value())}, + {"FrameDuration", String(param_frame_duration.value())}, + {"FrameFrequency", String(1000.0 / param_frame_duration.value(), 1)}, + {"JpegQuality", String(param_jpg_quality.value())}, + {"CameraInitialized", String(camera_init_result == ESP_OK)}, + {"CameraInitResult", String(camera_init_result)}, + {"CameraInitResultText", initResult}, + // Settings + {"Brightness", String(param_brightness.value())}, + {"Contrast", String(param_contrast.value())}, + {"Saturation", String(param_saturation.value())}, + {"SpecialEffect", String(param_special_effect.value())}, + {"WhiteBal", String(param_whitebal.value())}, + {"AwbGain", String(param_awb_gain.value())}, + {"WbMode", String(param_wb_mode.value())}, + {"ExposureCtrl", String(param_exposure_ctrl.value())}, + {"Aec2", String(param_aec2.value())}, + {"AeLevel", String(param_ae_level.value())}, + {"AecValue", String(param_aec_value.value())}, + {"GainCtrl", String(param_gain_ctrl.value())}, + {"AgcGain", String(param_agc_gain.value())}, + {"GainCeiling", String(param_gain_ceiling.value())}, + {"Bpc", String(param_bpc.value())}, + {"Wpc", String(param_wpc.value())}, + {"RawGma", String(param_raw_gma.value())}, + {"Lenc", String(param_lenc.value())}, + {"HMirror", String(param_hmirror.value())}, + {"VFlip", String(param_vflip.value())}, + {"Dcw", String(param_dcw.value())}, + {"ColorBar", String(param_colorbar.value())}, + // RTSP + {"RtspPort", String(RTSP_PORT)}}; + + web_server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + auto html = moustache_render(index_html_min_start, substitutions); + web_server.send(200, "text/html", html); +} + +void handle_snapshot() +{ + log_v("handle_snapshot"); + if (camera_init_result != ESP_OK) + { + web_server.send(404, "text/plain", "Camera is not initialized"); + return; + } + + // Remove old images stored in the frame buffer + auto frame_buffers = CAMERA_CONFIG_FB_COUNT; + while (frame_buffers--) + cam.run(); + + auto fb_len = cam.getSize(); + auto fb = (const char *)cam.getfb(); + if (fb == nullptr) + { + web_server.send(404, "text/plain", "Unable to obtain frame buffer from the camera"); + return; + } + + web_server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + web_server.setContentLength(fb_len); + web_server.send(200, "image/jpeg", ""); + web_server.sendContent(fb, fb_len); +} + +#define STREAM_CONTENT_BOUNDARY "123456789000000000000987654321" + +void handle_stream() +{ + log_v("handle_stream"); + if (camera_init_result != ESP_OK) + { + web_server.send(404, "text/plain", "Camera is not initialized"); + return; + } + + log_v("starting streaming"); + // Blocks further handling of HTTP server until stopped + char size_buf[12]; + 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"); + while (client.connected()) + { + client.write("\r\n--" STREAM_CONTENT_BOUNDARY "\r\n"); + cam.run(); + client.write("Content-Type: image/jpeg\r\nContent-Length: "); + sprintf(size_buf, "%d\r\n\r\n", cam.getSize()); + client.write(size_buf); + client.write(cam.getfb(), cam.getSize()); + } + + log_v("client disconnected"); + client.stop(); + log_v("stopped streaming"); +} + +esp_err_t initialize_camera() +{ + log_v("initialize_camera"); + + log_i("Frame size: %s", param_frame_size.value()); + auto frame_size = lookup_frame_size(param_frame_size.value()); + log_i("JPEG quality: %d", param_jpg_quality.value()); + auto jpeg_quality = param_jpg_quality.value(); + log_i("Frame duration: %d ms", param_frame_duration.value()); + const camera_config_t camera_config = { + .pin_pwdn = CAMERA_CONFIG_PIN_PWDN, // GPIO pin for camera power down line + .pin_reset = CAMERA_CONFIG_PIN_RESET, // GPIO pin for camera reset line + .pin_xclk = CAMERA_CONFIG_PIN_XCLK, // GPIO pin for camera XCLK line + .pin_sccb_sda = CAMERA_CONFIG_PIN_SCCB_SDA, // GPIO pin for camera SDA line + .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 + .pin_d6 = CAMERA_CONFIG_PIN_Y8, // GPIO pin for camera D6 line + .pin_d5 = CAMERA_CONFIG_PIN_Y7, // GPIO pin for camera D5 line + .pin_d4 = CAMERA_CONFIG_PIN_Y6, // GPIO pin for camera D4 line + .pin_d3 = CAMERA_CONFIG_PIN_Y5, // GPIO pin for camera D3 line + .pin_d2 = CAMERA_CONFIG_PIN_Y4, // GPIO pin for camera D2 line + .pin_d1 = CAMERA_CONFIG_PIN_Y3, // GPIO pin for camera D1 line + .pin_d0 = CAMERA_CONFIG_PIN_Y2, // GPIO pin for camera D0 line + .pin_vsync = CAMERA_CONFIG_PIN_VSYNC, // GPIO pin for camera VSYNC line + .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); +} + +void update_camera_settings() +{ + auto camera = esp_camera_sensor_get(); + if (camera == nullptr) + { + log_e("Unable to get camera sensor"); + return; + } + + camera->set_brightness(camera, param_brightness.value()); + camera->set_contrast(camera, param_contrast.value()); + camera->set_saturation(camera, param_saturation.value()); + camera->set_special_effect(camera, lookup_camera_effect(param_special_effect.value())); + camera->set_whitebal(camera, param_whitebal.value()); + camera->set_awb_gain(camera, param_awb_gain.value()); + camera->set_wb_mode(camera, lookup_camera_wb_mode(param_wb_mode.value())); + camera->set_exposure_ctrl(camera, param_exposure_ctrl.value()); + camera->set_aec2(camera, param_aec2.value()); + camera->set_ae_level(camera, param_ae_level.value()); + camera->set_aec_value(camera, param_aec_value.value()); + camera->set_gain_ctrl(camera, param_gain_ctrl.value()); + camera->set_agc_gain(camera, param_agc_gain.value()); + camera->set_gainceiling(camera, lookup_camera_gainceiling(param_gain_ceiling.value())); + camera->set_bpc(camera, param_bpc.value()); + camera->set_wpc(camera, param_wpc.value()); + camera->set_raw_gma(camera, param_raw_gma.value()); + camera->set_lenc(camera, param_lenc.value()); + camera->set_hmirror(camera, param_hmirror.value()); + camera->set_vflip(camera, param_vflip.value()); + camera->set_dcw(camera, param_dcw.value()); + camera->set_colorbar(camera, param_colorbar.value()); +} + +void start_rtsp_server() +{ + log_v("start_rtsp_server"); + camera_server = std::unique_ptr(new rtsp_server(cam, param_frame_duration.value(), RTSP_PORT)); + // Add RTSP service to mDNS + // HTTP is already set by iotWebConf + MDNS.addService("rtsp", "tcp", RTSP_PORT); +} + +void on_connected() +{ + log_v("on_connected"); + // Start the RTSP Server if initialized + if (camera_init_result == ESP_OK) + start_rtsp_server(); + else + log_e("Not starting RTSP server: camera not initialized"); +} + +void on_config_saved() +{ + log_v("on_config_saved"); + update_camera_settings(); +} + +void setup() +{ + // Disable brownout + WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); + +#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("SDK version: %s", ESP.getSdkVersion()); + log_i("Board: %s", BOARD_NAME); + log_i("Starting " APP_TITLE "..."); + + if (CAMERA_CONFIG_FB_LOCATION == CAMERA_FB_IN_PSRAM && !psramInit()) + log_e("Failed to initialize PSRAM"); + + param_group_camera.addItem(¶m_frame_duration); + param_group_camera.addItem(¶m_frame_size); + param_group_camera.addItem(¶m_jpg_quality); + param_group_camera.addItem(¶m_brightness); + param_group_camera.addItem(¶m_contrast); + param_group_camera.addItem(¶m_saturation); + param_group_camera.addItem(¶m_special_effect); + param_group_camera.addItem(¶m_whitebal); + param_group_camera.addItem(¶m_awb_gain); + param_group_camera.addItem(¶m_wb_mode); + param_group_camera.addItem(¶m_exposure_ctrl); + param_group_camera.addItem(¶m_aec2); + param_group_camera.addItem(¶m_ae_level); + param_group_camera.addItem(¶m_aec_value); + param_group_camera.addItem(¶m_gain_ctrl); + param_group_camera.addItem(¶m_agc_gain); + param_group_camera.addItem(¶m_gain_ceiling); + param_group_camera.addItem(¶m_bpc); + param_group_camera.addItem(¶m_wpc); + param_group_camera.addItem(¶m_raw_gma); + param_group_camera.addItem(¶m_lenc); + param_group_camera.addItem(¶m_hmirror); + param_group_camera.addItem(¶m_vflip); + param_group_camera.addItem(¶m_dcw); + param_group_camera.addItem(¶m_colorbar); + iotWebConf.addParameterGroup(¶m_group_camera); + + iotWebConf.getApTimeoutParameter()->visible = true; + iotWebConf.setConfigSavedCallback(on_config_saved); + iotWebConf.setWifiConnectionCallback(on_connected); +#ifdef USER_LED_GPIO + iotWebConf.setStatusPin(USER_LED_GPIO, USER_LED_ON_LEVEL); +#endif + iotWebConf.init(); + + // Try to initialize 3 times + for (auto i = 0; i < 3; i++) + { + camera_init_result = initialize_camera(); + 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 + web_server.on("/", HTTP_GET, handle_root); + web_server.on("/config", [] + { iotWebConf.handleConfig(); }); + // Camera snapshot + web_server.on("/snapshot", HTTP_GET, handle_snapshot); + // Camera stream + web_server.on("/stream", HTTP_GET, handle_stream); + + web_server.onNotFound([]() + { iotWebConf.handleNotFound(); }); +} + +void loop() +{ + iotWebConf.doLoop(); + + if (camera_server) + camera_server->doLoop(); +} \ No newline at end of file diff --git a/lib/esp32cam-rtsp/test/README b/lib/esp32cam-rtsp/test/README new file mode 100755 index 0000000..9b1e87b --- /dev/null +++ b/lib/esp32cam-rtsp/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/platformio.ini b/platformio.ini new file mode 100755 index 0000000..a7e0369 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,16 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32cam] +platform = espressif32 +board = esp32cam +framework = arduino +monitor_speed = 115200 +lib_extra_dirs = lib diff --git a/secrets.h.example b/secrets.h.example new file mode 100644 index 0000000..5ff32d1 --- /dev/null +++ b/secrets.h.example @@ -0,0 +1,9 @@ +#ifndef SECRETS_H +#define SECRETS_H + +#define SECRET_WIFI_SSID "YOUR_WIFI_SSID" +#define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" +#define SECRET_MQTT_USER "YOUR_MQTT_USERNAME" +#define SECRET_MQTT_PASS "YOUR_MQTT_PASSWORD" + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100755 index 0000000..a61151a --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,172 @@ +#include "secrets.h" +#include +#include "esp_camera.h" +#include // Include esp32cam-rtsp library + +// WiFi Credentials +const char* ssid = SECRET_WIFI_SSID; +const char* password = SECRET_WIFI_PASS; + +// MQTT Broker +const char* mqtt_server = "192.168.20.30"; +const char* mqtt_user = SECRET_MQTT_USER; +const char* password = SECRET_WIFI_PASS; + +// MQTT Topic +const char* mqtt_topic = "homeassistant/camera_1/control"; + +// Camera Pins (AI Thinker ESP32-CAM) +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 0 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 21 +#define Y4_GPIO_NUM 19 +#define Y3_GPIO_NUM 18 +#define Y2_GPIO_NUM 5 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +WiFiClient espClient; +PubSubClient mqttClient(espClient); +RTSPServer rtspServer; // RTSP server instance + +void setup_wifi() { + delay(10); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); +} + +void setupCamera() { + camera_config_t config; + config.ledc_channel = LEDC_CHANNEL_0; + config.ledc_timer = LEDC_TIMER_0; + config.pin_d0 = Y2_GPIO_NUM; + config.pin_d1 = Y3_GPIO_NUM; + config.pin_d2 = Y4_GPIO_NUM; + config.pin_d3 = Y5_GPIO_NUM; + config.pin_d4 = Y6_GPIO_NUM; + config.pin_d5 = Y7_GPIO_NUM; + config.pin_d6 = Y8_GPIO_NUM; + config.pin_d7 = Y9_GPIO_NUM; + config.pin_xclk = XCLK_GPIO_NUM; + config.pin_pclk = PCLK_GPIO_NUM; + config.pin_vsync = VSYNC_GPIO_NUM; + config.pin_href = HREF_GPIO_NUM; + config.pin_sccb_sda = SIOD_GPIO_NUM; + config.pin_sccb_scl = SIOC_GPIO_NUM; + config.pin_pwdn = PWDN_GPIO_NUM; + config.pin_reset = RESET_GPIO_NUM; + config.xclk_freq_hz = 20000000; + config.pixel_format = PIXFORMAT_JPEG; + + if (psramFound()) { + config.frame_size = FRAMESIZE_UXGA; + config.jpeg_quality = 10; + config.fb_count = 2; + } else { + config.frame_size = FRAMESIZE_SVGA; + config.jpeg_quality = 12; + config.fb_count = 1; + } + + esp_err_t err = esp_camera_init(&config); + if (err != ESP_OK) { + Serial.printf("Camera init failed with error 0x%x", err); + return; + } + Serial.println("Camera initialized"); +} + +void startRTSPStream() { + // Initialize RTSP server + rtspServer.begin(); + Serial.println("RTSP server started"); +} + +void stopRTSPStream() { + // Stop the RTSP server + rtspServer.end(); + Serial.println("RTSP server stopped"); +} + +void callback(char* topic, byte* payload, unsigned int length) { + Serial.print("Message arrived on topic: "); + Serial.print(topic); + Serial.print(". Message: "); + String messageTemp; + + for (int i = 0; i < length; i++) { + Serial.print((char)payload[i]); + messageTemp += (char)payload[i]; + } + Serial.println(); + + // Handle incoming MQTT messages to control the camera + if (String(topic) == mqtt_topic) { + if (messageTemp == "turn_on_camera") { + setupCamera(); + startRTSPStream(); + Serial.println("Camera turned on"); + } else if (messageTemp == "turn_off_camera") { + esp_camera_deinit(); + stopRTSPStream(); + Serial.println("Camera turned off"); + } + } +} + +void reconnect() { + while (!mqttClient.connected()) { + Serial.print("Attempting MQTT connection..."); + if (mqttClient.connect("ESP32CAMClient", mqtt_user, mqtt_password)) { + Serial.println("connected"); + mqttClient.subscribe(mqtt_topic); + } else { + Serial.print("failed, rc="); + Serial.print(mqttClient.state()); + Serial.println(" try again in 5 seconds"); + delay(5000); + } + } +} + +void setup() { + Serial.begin(115200); + setup_wifi(); + mqttClient.setServer(mqtt_server, 1883); + mqttClient.setCallback(callback); + reconnect(); + + // Automatically start the camera and RTSP server + setupCamera(); + startRTSPStream(); + Serial.println("Camera and RTSP server started"); +} + +void loop() { + if (!mqttClient.connected()) { + reconnect(); + } + mqttClient.loop(); + rtspServer.handleClient(); // Handle RTSP clients +} diff --git a/test/README b/test/README new file mode 100755 index 0000000..b0416ad --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html