├── .github └── workflows │ └── main.yml ├── .gitignore ├── README.md ├── assets ├── Configuration.png ├── ESP32CAM-to-FTDI.png ├── boards │ ├── ai-thinker-esp32-cam-ipex.jpg │ ├── ai-thinker-esp32-cam-mb.jpg │ ├── ai-thinker-esp32-cam.jpg │ ├── ai_thinker_esp32-cam.jpg │ ├── datasheets │ │ └── ov2640_ds_1.8_.pdf │ ├── esp-lyrap-cam-v1.0-3d.png │ ├── esp32-wrover-cam.jpg │ ├── espressif-esp-eye.jpg │ ├── espressif-esps3-eye.jpg │ ├── lilygo-camera-module.jpg │ ├── lilygo-simcam.jpg │ ├── lilygo-ttgo-t-camera.jpg │ ├── m5stack-esp32-camera.jpg │ ├── m5stack_Unitcams3.webp │ ├── m5stack_Unitcams32.webp │ ├── m5stack_Unitcams33webp.webp │ ├── m5stack_esp32cam_02.webp │ ├── m5stack_unit_cam_02.webp │ ├── m5stack_unit_cam_03.webp │ ├── schematics │ │ ├── ESP-LyraP-CAM_V1.1_SCH_20200511A.pdf │ │ ├── UnitCamS3.png │ │ ├── XIAO_ESP32S3_ExpBoard_v1.0_SCH.pdf │ │ ├── ai_thinker_esp32cam.pdf │ │ └── m5stack_unit_cam_sch_01.webp │ └── seeed-studio-xiao-esp32s3-sense.jpg └── index.png ├── boards ├── esp32cam_ai_thinker.json ├── esp32cam_espressif_esp32s2_cam_board.json ├── esp32cam_espressif_esp32s2_cam_header.json ├── esp32cam_espressif_esp32s3_cam_lcd.json ├── esp32cam_espressif_esp32s3_eye.json ├── esp32cam_espressif_esp_eye.json ├── esp32cam_freenove_s3_wroom_n8r8.json ├── esp32cam_freenove_wrover_kit.json ├── esp32cam_m5stack_atoms3r.json ├── esp32cam_m5stack_camera.json ├── esp32cam_m5stack_camera_psram.json ├── esp32cam_m5stack_esp32cam.json ├── esp32cam_m5stack_unitcam.json ├── esp32cam_m5stack_unitcams3.json ├── esp32cam_m5stack_wide.json ├── esp32cam_seeed_xiao_esp32s3_sense.json ├── esp32cam_ttgo_t_camera.json └── esp32cam_ttgo_t_journal.json ├── generate_html.ps1 ├── generate_html.sh ├── html ├── index.html └── index.min.html ├── include ├── README ├── format_duration.h ├── format_number.h ├── lookup_camera_effect.h ├── lookup_camera_frame_size.h ├── lookup_camera_gainceiling.h ├── lookup_camera_wb_mode.h └── settings.h ├── lib ├── README └── rtsp_server │ ├── library.json │ ├── rtsp_server.cpp │ └── rtsp_server.h ├── minify.py ├── platformio.ini ├── src └── main.cpp └── test └── README /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Platform IO CI 2 | on: [push] 3 | jobs: 4 | build: 5 | name: Build 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v4 9 | with: 10 | submodules: 'true' 11 | - uses: actions/cache@v4 12 | with: 13 | path: | 14 | ~/.cache/pip 15 | ~/.platformio/.cache 16 | key: ${{ runner.os }}-pio 17 | - name: Set up Python 18 | uses: actions/setup-python@v5 19 | with: 20 | python-version: '3.9' 21 | - name: Install PlatformIO 22 | run: python -m pip install platformio 23 | - name: Build firmware 24 | run: platformio run 25 | - name: Archive 26 | uses: actions/upload-artifact@v4 27 | with: 28 | name: firmwares.zip 29 | path: .pio/build/*/firmware.bin 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*/* 2 | .*.* 3 | __pycache__/ 4 | *.log 5 | .DS_Store 6 | workspace.code-workspace -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32CAM-RTSP 2 | 3 | [![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) 4 | 5 | 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. 6 | 7 | > [!IMPORTANT] 8 | > New branch available! Here [branch: develop](https://github.com/rzeldent/esp32cam-rtsp/tree/develop) 9 | > This branch supports all the current devices and the Seeed Studio Xiao esp32s3! 10 | > Please use this and let me know if this works for you! 11 | 12 | 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**. 13 | 14 | Supported protocols 15 | 16 | - RTSP 17 | 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. 18 | It is also possible to stream directly to a server using [ffmpeg](https://ffmpeg.org). 19 | This makes the module a camera server allowing recording and the stream can be stored on a disk and replayed later. 20 | The URL is rtsp://<ip address>:554/mjpeg/1 21 | 22 | - HTTP Motion JPEG 23 | The HTTP JPEG streamer makes it possible to watch the camera stream directly in your browser. 24 | The URL is http://<ip address>/stream 25 | 26 | - HTTP image 27 | The HTTP Image returns an HTTP JPEG image of the camera. 28 | The URL is http://<ip address>/snapshot 29 | 30 | This software supports the following ESP32-CAM (and alike) modules: 31 | 32 | - AI THINKER 33 | - EspressIf ESP-EYE 34 | - EspressIf ESP32S2-CAM 35 | - EspressIf ESP32S3-CAM-LCD 36 | - EspressIf ESP32S3-EYE 37 | - Freenove WROVER KIT 38 | - M5STACK ESP32CAM 39 | - M5STACK_PSRAM 40 | - M5STACK_UNITCAM 41 | - M5STACK_UNITCAMS3 42 | - M5STACK_V2_PSRAM 43 | - M5STACK_PSRAM 44 | - M5STACK_WIDE 45 | - M5STACK 46 | - Seeed Studio XIAO ESP32S3 SENSE 47 | - TTGO T-CAMERA 48 | - TTGO T-JOURNAL 49 | 50 | The software provides a **configuration web server**, that can be used to: 51 | 52 | - Provide information about the state of the device, wifi connection and camera, 53 | - Set the WiFi parameters, 54 | - Set the timeout for connecting to the access point, 55 | - Set an access password, 56 | - Select the image size, 57 | - Select the frame rate, 58 | - Select the JPEG quality 59 | - Enable the use of the PSRAM 60 | - Set the number of frame buffers 61 | - Configure the camera options: 62 | - Brightness 63 | - Contrast 64 | - Saturation 65 | - Special effect (Normal, Negative, Gray-scale, Red/Green/Blue tint, Sepia) 66 | - White balance 67 | - Automatic White Balance gain 68 | - Wite Balance mode 69 | - Exposure control 70 | - Auto Exposure (dsp) 71 | - Auto Exposure level 72 | - Manual exposure value 73 | - Gain control 74 | - Manual gain control 75 | - Auto gain ceiling 76 | - Black pixel correction 77 | - White pixel correction 78 | - Gamma correction 79 | - Lens correction 80 | - Horizontal mirror 81 | - Vertical flip 82 | - Downside enable 83 | - Color bar 84 | 85 | The software provides contains also a mDNS server to be easily discoverable on the local network. 86 | It advertises HTTP (port 80) and RTSP (port 554) 87 | 88 | ## Required 89 | 90 | - ESP32-CAM module or similar, 91 | - USB to Serial (TTL level) converter, piggyback board ESP32-CAM-MB or other way to connect to the device, 92 | - [**PlatformIO**](https://platformio.org/) software (free download) 93 | 94 | ## Boards 95 | 96 | There are a lot of boards available that are all called ESP32-CAM. 97 | However, there are differences in CPU (type/speed/cores), how the camera is connected, presence of PSRAM or not... 98 | To select the right board use the table below and use the configuration that is listed below for your board: 99 | 100 | | Board | Image | CPU | SRAM | Flash | PSRAM | Camera | | Site | 101 | |--- |--- |--- |--- |--- | --- |--- |--- |--- | 102 | | Espressif ESP32-Wrover CAM | ![img](assets/boards/esp32-wrover-cam.jpg) | ESP32 | 520KB | 4Mb | 4MB | OV2640 | | | 103 | | 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) | 104 | | Espressif ESP-EYE | ![img](assets/boards/espressif-esp-eye.jpg) | ESP32 | 520KB | 4Mb | 4MB | OV2640 | | | 105 | | 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) | 106 | | LilyGo camera module | ![img](assets/boards/lilygo-camera-module.jpg) | ESP32 Wrover | 520KB | 4Mb | 4MB | OV2640 / OV5640 | | | 107 | | LilyGo Simcam | ![img](assets/boards/lilygo-simcam.jpg) | | | | | OV2640 | | | 108 | | LilyGo TTGO-T Camera | ![img](assets/boards/lilygo-ttgo-t-camera.jpg) | | | | | OV2640 | | | 109 | | 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) | 110 | | 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) | 111 | | 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) | 112 | | 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) | 113 | | 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) | 114 | | 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) | 115 | 116 | ## Installing and running PlatformIO 117 | 118 | 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). 119 | 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. 120 | 121 | Install [Visual Studio Code](https://code.visualstudio.com) and install the PlatformIO plugin. 122 | 123 | ## Putting the ESP32-CAM in download mode 124 | 125 | ### ESP32-CAM-MB 126 | 127 | When using the ESP32-CAM-MB board, press and hold the GP0 button on the ESP32-CAM-MB board. 128 | Then press short the reset button (on the inside) on the ESP32-CAM board and release the GP0 button. 129 | This will put the ESP32-CAM board in download mode. 130 | 131 | ### FTDI adapter 132 | 133 | When using an FTDI adapter, make sure the adapter is set to 3.3 volt before connecting. Use the wiring schema below. 134 | 135 | ![ESP FTDI wiring](assets/ESP32CAM-to-FTDI.png) 136 | 137 | After programming remove the wire to tge GPIO0 pin to exit the download mode. 138 | 139 | ## Compiling and deploying the software 140 | 141 | Open a command line or terminal window and clone this repository from GitHub. 142 | 143 | ```sh 144 | git clone https://github.com/rzeldent/esp32cam-rtsp.git 145 | ``` 146 | 147 | go into the folder 148 | 149 | ```sh 150 | cd esp32cam-rtsp 151 | ``` 152 | 153 | Next, the firmware has to be build and deployed to the ESP32. 154 | There are two flavours to do this; using the command line or the graphical interface of Visual Studio Code. 155 | 156 | ### Using the command line 157 | 158 | Make sure you have the latest version of the Espressif toolchain. 159 | 160 | ```sh 161 | pio pkg update -g -p espressif32 162 | ``` 163 | 164 | First the source code has to be compiled to build all targets 165 | 166 | ```sh 167 | pio run 168 | ``` 169 | 170 | if only a specific target is required, for example the ```esp32cam_ttgo_t_journal``` type: 171 | 172 | ```sh 173 | pio run -e esp32cam_ttgo_t_journal 174 | ``` 175 | 176 | When finished, firmware has to be uploaded. 177 | Make sure the ESP32-CAM is in download mode (see previous section) and type: 178 | 179 | ```sh 180 | pio run -t upload 181 | ``` 182 | 183 | or, again, for a specific target, for example ```esp32cam_ai_thinker``` 184 | 185 | ```sh 186 | pio run -t upload -e esp32cam_ai_thinker 187 | ``` 188 | 189 | When done remove the jumper when using a FTDI adapter or press the reset button on the ESP32-CAM. 190 | To monitor the output, start a terminal using: 191 | 192 | ```sh 193 | pio device monitor 194 | ``` 195 | 196 | ### Using Visual studio 197 | 198 | 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. 199 | 200 | - PlatformIO: Build (esp32cam) 201 | - PlatformIO: Upload (esp32cam) 202 | 203 | To monitor the behavior run the task, run: ```PlatformIO: Monitor (esp32cam)``` 204 | 205 | ## Setting up the ESP32CAM-RTSP 206 | 207 | After the programming of the ESP32, there is no configuration present. This needs to be added. 208 | To connect initially to the device open the WiFi connections and select the WiFi network / access point called **ESP32CAM-RTSP**. 209 | Initially there is no password present. 210 | 211 | After connecting, the browser should automatically open the status page. 212 | In case this does not happens automatically, connect to [http://192.168.4.1](http://192.168.4.1). 213 | This page will display the current settings and status. On the bottom, there is a link to the config. Click on this link. 214 | 215 | This link brings up the configuration screen when connecting fot the first time. 216 | 217 | ![Configuration screen](assets/Configuration.png) 218 | 219 | Configure at least: 220 | 221 | - The access point to connect to. No dropdown is present to show available networks! 222 | - A password for accessing the Access point (AP) when starting. (required) 223 | - Type of the ESP32-CAM board 224 | 225 | When finished press ```Apply``` to save the configuration. The screen will redirect to the status screen. 226 | Here it is possible to reboot the device so the settings take effect. 227 | It is also possible to restart manually by pressing the reset button. 228 | 229 | ## Connecting to the configuration 230 | 231 | After the initial configuration and the device is connected to an access point, the device can be configured over http. 232 | 233 | When a connection is made to [http://esp32cam-rtsp](http://esp32cam-rtsp) the status screen is shown. 234 | 235 | ![Status screen](assets/index.png) 236 | 237 | In case changes have been made to the configuration, this is shown and the possibility to restart is given. 238 | 239 | Clicking on the ```change configuration``` button will open the configuration. It is possible that a password dialog is shown before entering. 240 | If this happens, for the user enter 'admin' and for the password the value that has been configured as the Access Point password. 241 | 242 | ## Connecting to the RTSP stream 243 | 244 | RTSP stream is available at: [rtsp://esp32cam-rtsp.local:554/mjpeg/1](rtsp://esp32cam-rtsp.local:554/mjpeg/1). 245 | This link can be opened with for example [VLC](https://www.videolan.org/vlc/). 246 | 247 | ## Connecting to the JPEG motion server 248 | 249 | The JPEG motion server server is available using a normal web browser at: [http://esp32cam-rtsp.local:/stream](http://esp32cam-rtsp.local/stream). 250 | 251 | ## Connecting to the image server 252 | 253 | The image server server is available using a normal web browser at: [http://esp32cam-rtsp.local:/snapshot](http://esp32cam-rtsp.local/snapshot). 254 | 255 | :bangbang: **Please be aware that there is no password present!**. 256 | Everybody with network access to the device can see the streams or images! Beware of :trollface:! 257 | 258 | ## API 259 | 260 | There is a minimum API present to perform some tasks using HTTP requests. For some requests authentication is required. 261 | The authentication used is basic authentication. The user is always admin and the password the access point key.\ 262 | If using a browser, remember that the authentication is stored in the browser session so needs to be entered only once. 263 | 264 | The URLs are below: 265 | 266 | ### GET: /restart 267 | 268 | Calling this URL will restart the device. Authentication is required. 269 | 270 | ### GET: /config 271 | 272 | Calling this URL will start the form for configuring the device in the browser. Authentication is required. 273 | 274 | ### GET: /snapshot 275 | 276 | Calling this URL will return a JPEG snapshot of the camera in the browser. 277 | This request can also be used (for example using cURL) to save the snapshot to a file. 278 | 279 | ## Issues / Nice to know 280 | 281 | - The red LED on the back of the device indicates the device is not connected. 282 | - Sometimes after configuration a reboot is required. 283 | If the error screen is shown that it is unable to make a connection, first try to reboot the device, 284 | - When booting, the device waits 30 seconds for a connection (configurable). 285 | You can make a connection to the SSID and log in using the credentials below, 286 | - When connected, go to the ip of the device and, when prompted for the credentials, enter 'admin' and the AP password. 287 | This is a **required** field before saving the credentials, 288 | - When the password is lost, a fix is to completely erase the ESP32 using the ```pio run -t erase``` command. 289 | This will reset the device including configuration. 290 | If using the esptool, you can do this using ```esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash```. 291 | However, after erasing, re-flashing of the firmware is required. 292 | - When finished configuring for the first time and the access point is entered, disconnect from the wireless network provided by the device. 293 | This should reset the device and connect to the access point. 294 | Resetting is also a good alternative... 295 | - There are modules that have no or faulty PSRAM (despite advertised as such). 296 | This can be the case if the camera fails to initialize. 297 | It might help to disable the use of the PSRAM and reduce the buffers and the screen size. 298 | 299 | ### Power 300 | 301 | Make sure the power is 5 volts and stable, although the ESP32 is a 3.3V module, this voltage is created on the board. 302 | If not stable, it has been reported that restarts occur when starting up (probably when power is required for WiFi). 303 | The software disables the brown out protection so there is some margin in the voltage. 304 | Some people suggest to add a capacitor over the 5V input to stabilize the voltage. 305 | 306 | ### PSRAM / Buffers / JPEG quality 307 | 308 | Some esp32cam modules have additional ram on the board. This allows to use this ram as frame buffer. 309 | The availability of PSRAM can be seen in the HTML status overview. 310 | 311 | Not all the boards are equipped with PSRAM: 312 | 313 | | Board | PSRAM | 314 | |--- |--- | 315 | | WROVER_KIT | 8Mb | 316 | | ESP_EYE | 8Mb | 317 | | ESP32S3_EYE | 8Mb | 318 | | M5STACK_PSRAM | 8Mb | 319 | | M5STACK_V2_PSRAM | Version B only | 320 | | M5STACK_WIDE | 8Mb | 321 | | M5STACK_ESP32CAM | No | 322 | | M5STACK_UNITCAM | No | 323 | | M5STACK_UNITCAMS3 | 8Mb | 324 | | AI_THINKER | 8Mb | 325 | | TTGO_T_JOURNAL | No | 326 | | ESP32_CAM_BOARD | ? | 327 | | ESP32S2_CAM_BOARD | ? | 328 | | ESP32S3_CAM_LCD | ? | 329 | 330 | 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. 331 | 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/). 332 | In this case disable the use of PSRAM in the configuration and do not use camera modes that require PSRAM, 333 | 334 | For the setting JPEG quality, a lower number means higher quality. 335 | Be aware that a very high quality (low number) can cause the ESP32 cam to crash or return no image. 336 | 337 | The default settings are: 338 | 339 | - No PSRAM 340 | - SVGA (800x600) 341 | - 1 frame buffer 342 | - JPEG quality 12 343 | 344 | - With PSRAM 345 | - UXGA (1600x1200) 346 | - 2 frame buffers 347 | - JPEG quality 10 348 | 349 | ### Camera module 350 | 351 | Be careful when connecting the camera module. 352 | 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. 353 | 354 | ## Credits 355 | 356 | esp32cam-rtsp depends on PlatformIO, Bootstrap 5 and Micro-RTSP by Kevin Hester. 357 | 358 | ## Change history 359 | 360 | - January 2024 361 | - Moved settings to board definitions 362 | - Added new boards 363 | - Removed OTA to increase performance 364 | - Oktober 2023 365 | - Added support for Seeed Xiao esp32s3 366 | - New build system 367 | - Updated documentation 368 | - March 2023 369 | - Added options to set PSRAM / Frame buffers 370 | - Added JPEG Motion streaming 371 | - Feb 2023 372 | - Added additional settings for camera configuration 373 | - Nov 2022 374 | - Added OTA 375 | - Fix for grabbing frame 376 | - Fixed bug: Increased WiFi password length 377 | - Sep 2022 378 | - Added GUI with bootstrap 379 | - More information in web page 380 | - Added camera preview in HTML 381 | - Jul 2022 382 | - Initial version 383 | -------------------------------------------------------------------------------- /assets/Configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/Configuration.png -------------------------------------------------------------------------------- /assets/ESP32CAM-to-FTDI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/ESP32CAM-to-FTDI.png -------------------------------------------------------------------------------- /assets/boards/ai-thinker-esp32-cam-ipex.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/ai-thinker-esp32-cam-ipex.jpg -------------------------------------------------------------------------------- /assets/boards/ai-thinker-esp32-cam-mb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/ai-thinker-esp32-cam-mb.jpg -------------------------------------------------------------------------------- /assets/boards/ai-thinker-esp32-cam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/ai-thinker-esp32-cam.jpg -------------------------------------------------------------------------------- /assets/boards/ai_thinker_esp32-cam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/ai_thinker_esp32-cam.jpg -------------------------------------------------------------------------------- /assets/boards/datasheets/ov2640_ds_1.8_.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/datasheets/ov2640_ds_1.8_.pdf -------------------------------------------------------------------------------- /assets/boards/esp-lyrap-cam-v1.0-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/esp-lyrap-cam-v1.0-3d.png -------------------------------------------------------------------------------- /assets/boards/esp32-wrover-cam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/esp32-wrover-cam.jpg -------------------------------------------------------------------------------- /assets/boards/espressif-esp-eye.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/espressif-esp-eye.jpg -------------------------------------------------------------------------------- /assets/boards/espressif-esps3-eye.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/espressif-esps3-eye.jpg -------------------------------------------------------------------------------- /assets/boards/lilygo-camera-module.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/lilygo-camera-module.jpg -------------------------------------------------------------------------------- /assets/boards/lilygo-simcam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/lilygo-simcam.jpg -------------------------------------------------------------------------------- /assets/boards/lilygo-ttgo-t-camera.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/lilygo-ttgo-t-camera.jpg -------------------------------------------------------------------------------- /assets/boards/m5stack-esp32-camera.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/m5stack-esp32-camera.jpg -------------------------------------------------------------------------------- /assets/boards/m5stack_Unitcams3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/m5stack_Unitcams3.webp -------------------------------------------------------------------------------- /assets/boards/m5stack_Unitcams32.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/m5stack_Unitcams32.webp -------------------------------------------------------------------------------- /assets/boards/m5stack_Unitcams33webp.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/m5stack_Unitcams33webp.webp -------------------------------------------------------------------------------- /assets/boards/m5stack_esp32cam_02.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/m5stack_esp32cam_02.webp -------------------------------------------------------------------------------- /assets/boards/m5stack_unit_cam_02.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/m5stack_unit_cam_02.webp -------------------------------------------------------------------------------- /assets/boards/m5stack_unit_cam_03.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/m5stack_unit_cam_03.webp -------------------------------------------------------------------------------- /assets/boards/schematics/ESP-LyraP-CAM_V1.1_SCH_20200511A.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/schematics/ESP-LyraP-CAM_V1.1_SCH_20200511A.pdf -------------------------------------------------------------------------------- /assets/boards/schematics/UnitCamS3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/schematics/UnitCamS3.png -------------------------------------------------------------------------------- /assets/boards/schematics/XIAO_ESP32S3_ExpBoard_v1.0_SCH.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/schematics/XIAO_ESP32S3_ExpBoard_v1.0_SCH.pdf -------------------------------------------------------------------------------- /assets/boards/schematics/ai_thinker_esp32cam.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/schematics/ai_thinker_esp32cam.pdf -------------------------------------------------------------------------------- /assets/boards/schematics/m5stack_unit_cam_sch_01.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/schematics/m5stack_unit_cam_sch_01.webp -------------------------------------------------------------------------------- /assets/boards/seeed-studio-xiao-esp32s3-sense.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/boards/seeed-studio-xiao-esp32s3-sense.jpg -------------------------------------------------------------------------------- /assets/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzeldent/esp32cam-rtsp/00635d03b73be82c0795266f299155fbf2386cef/assets/index.png -------------------------------------------------------------------------------- /boards/esp32cam_ai_thinker.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_AI_THINKER'", 10 | "'-D BOARD_HAS_PSRAM'", 11 | "'-mfix-esp32-psram-cache-issue'", 12 | "'-D USER_LED_GPIO=33'", 13 | "'-D USER_LED_ON_LEVEL=LOW'", 14 | "'-D CAMERA_CONFIG_PIN_PWDN=32'", 15 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 16 | "'-D CAMERA_CONFIG_PIN_XCLK=0'", 17 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=26'", 18 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=27'", 19 | "'-D CAMERA_CONFIG_PIN_Y9=35'", 20 | "'-D CAMERA_CONFIG_PIN_Y8=34'", 21 | "'-D CAMERA_CONFIG_PIN_Y7=39'", 22 | "'-D CAMERA_CONFIG_PIN_Y6=36'", 23 | "'-D CAMERA_CONFIG_PIN_Y5=21'", 24 | "'-D CAMERA_CONFIG_PIN_Y4=19'", 25 | "'-D CAMERA_CONFIG_PIN_Y3=18'", 26 | "'-D CAMERA_CONFIG_PIN_Y2=5'", 27 | "'-D CAMERA_CONFIG_PIN_VSYNC=25'", 28 | "'-D CAMERA_CONFIG_PIN_HREF=23'", 29 | "'-D CAMERA_CONFIG_PIN_PCLK=22'", 30 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 31 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 32 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 33 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 34 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 35 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 36 | ], 37 | "f_cpu": "240000000L", 38 | "f_flash": "40000000L", 39 | "flash_mode": "dio", 40 | "mcu": "esp32", 41 | "variant": "esp32" 42 | }, 43 | "connectivity": [ 44 | "wifi", 45 | "bluetooth", 46 | "ethernet", 47 | "can" 48 | ], 49 | "debug": { 50 | "openocd_board": "esp-wroom-32.cfg" 51 | }, 52 | "frameworks": [ 53 | "arduino", 54 | "espidf" 55 | ], 56 | "name": "ESP32CAM AI Thinker", 57 | "upload": { 58 | "flash_size": "4MB", 59 | "maximum_ram_size": 327680, 60 | "maximum_size": 4194304, 61 | "require_upload_port": true, 62 | "speed": 460800 63 | }, 64 | "url": "https://docs.ai-thinker.com/esp32-cam", 65 | "vendor": "Anxinke" 66 | } 67 | -------------------------------------------------------------------------------- /boards/esp32cam_espressif_esp32s2_cam_board.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32s2_out.ld" 5 | }, 6 | "core": "esp32", 7 | "extra_flags": [ 8 | "'-D ESP32CAM_ESPRESSIF_ESP32S2_CAM_BOARD'", 9 | "'-D BOARD_HAS_PSRAM'", 10 | "'-D ARDUINO_USB_MODE=0'", 11 | "'-D ARDUINO_USB_CDC_ON_BOOT=1'", 12 | "'-D ARDUINO_RUNNING_CORE=1'", 13 | "'-D ARDUINO_EVENT_RUNNING_CORE=1'", 14 | "'-D CAMERA_CONFIG_PIN_PWDN=1'", 15 | "'-D CAMERA_CONFIG_PIN_RESET=2'", 16 | "'-D CAMERA_CONFIG_PIN_XCLK=42'", 17 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=41'", 18 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=18'", 19 | "'-D CAMERA_CONFIG_PIN_Y9=16'", 20 | "'-D CAMERA_CONFIG_PIN_Y8=39'", 21 | "'-D CAMERA_CONFIG_PIN_Y7=40'", 22 | "'-D CAMERA_CONFIG_PIN_Y6=15'", 23 | "'-D CAMERA_CONFIG_PIN_Y5=12'", 24 | "'-D CAMERA_CONFIG_PIN_Y4=5'", 25 | "'-D CAMERA_CONFIG_PIN_Y3=13'", 26 | "'-D CAMERA_CONFIG_PIN_Y2=14'", 27 | "'-D CAMERA_CONFIG_PIN_VSYNC=38'", 28 | "'-D CAMERA_CONFIG_PIN_HREF=4'", 29 | "'-D CAMERA_CONFIG_PIN_PCLK=3'", 30 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 31 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 32 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 33 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 34 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 35 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 36 | ], 37 | "f_cpu": "240000000L", 38 | "f_flash": "80000000L", 39 | "flash_mode": "qio", 40 | "mcu": "esp32s2", 41 | "variant": "esp32s2" 42 | }, 43 | "connectivity": [ 44 | "wifi" 45 | ], 46 | "debug": { 47 | "openocd_target": "esp32s2.cfg" 48 | }, 49 | "frameworks": [ 50 | "arduino", 51 | "espidf" 52 | ], 53 | "name": "Espressif ESP32-S2-Saola-1", 54 | "upload": { 55 | "flash_size": "4MB", 56 | "maximum_ram_size": 327680, 57 | "maximum_size": 4194304, 58 | "require_upload_port": true, 59 | "speed": 460800 60 | }, 61 | "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.html", 62 | "vendor": "Espressif" 63 | } -------------------------------------------------------------------------------- /boards/esp32cam_espressif_esp32s2_cam_header.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32s2_out.ld" 5 | }, 6 | "core": "esp32", 7 | "extra_flags": [ 8 | "'-D ESP32CAM_ESPRESSIF_ESP32S2_CAM_BOARD'", 9 | "'-D BOARD_HAS_PSRAM'", 10 | "'-D ARDUINO_USB_MODE=0'", 11 | "'-D ARDUINO_USB_CDC_ON_BOOT=1'", 12 | "'-D ARDUINO_RUNNING_CORE=1'", 13 | "'-D ARDUINO_EVENT_RUNNING_CORE=1'", 14 | "'-D CAMERA_CONFIG_PIN_PWDN=1'", 15 | "'-D CAMERA_CONFIG_PIN_RESET=2'", 16 | "'-D CAMERA_CONFIG_PIN_XCLK=42'", 17 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=41'", 18 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=18'", 19 | "'-D CAMERA_CONFIG_PIN_Y9=16'", 20 | "'-D CAMERA_CONFIG_PIN_Y8=39'", 21 | "'-D CAMERA_CONFIG_PIN_Y7=40'", 22 | "'-D CAMERA_CONFIG_PIN_Y6=15'", 23 | "'-D CAMERA_CONFIG_PIN_Y5=13'", 24 | "'-D CAMERA_CONFIG_PIN_Y4=5'", 25 | "'-D CAMERA_CONFIG_PIN_Y3=12'", 26 | "'-D CAMERA_CONFIG_PIN_Y2=14'", 27 | "'-D CAMERA_CONFIG_PIN_VSYNC=38'", 28 | "'-D CAMERA_CONFIG_PIN_HREF=4'", 29 | "'-D CAMERA_CONFIG_PIN_PCLK=3'", 30 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 31 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 32 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 33 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 34 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 35 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 36 | ], 37 | "f_cpu": "240000000L", 38 | "f_flash": "80000000L", 39 | "flash_mode": "qio", 40 | "mcu": "esp32s2", 41 | "variant": "esp32s2" 42 | }, 43 | "connectivity": [ 44 | "wifi" 45 | ], 46 | "debug": { 47 | "openocd_target": "esp32s2.cfg" 48 | }, 49 | "frameworks": [ 50 | "arduino", 51 | "espidf" 52 | ], 53 | "name": "Espressif ESP32-S2-Saola-1", 54 | "upload": { 55 | "flash_size": "4MB", 56 | "maximum_ram_size": 327680, 57 | "maximum_size": 4194304, 58 | "require_upload_port": true, 59 | "speed": 460800 60 | }, 61 | "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.html", 62 | "vendor": "Espressif" 63 | } -------------------------------------------------------------------------------- /boards/esp32cam_espressif_esp32s3_cam_lcd.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32s3_out.ld", 5 | "partitions": "default_8MB.csv", 6 | "memory_type": "opi_opi" 7 | }, 8 | "core": "esp32", 9 | "extra_flags": [ 10 | "'-D ESP32CAM_ESP32S3_CAM_LCD'", 11 | "'-D BOARD_HAS_PSRAM'", 12 | "'-D ARDUINO_USB_MODE=1'", 13 | "'-D ARDUINO_USB_CDC_ON_BOOT=1'", 14 | "'-D ARDUINO_RUNNING_CORE=1'", 15 | "'-D ARDUINO_EVENT_RUNNING_CORE=1'", 16 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 17 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 18 | "'-D CAMERA_CONFIG_PIN_XCLK=40'", 19 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=17'", 20 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=18'", 21 | "'-D CAMERA_CONFIG_PIN_Y9=39'", 22 | "'-D CAMERA_CONFIG_PIN_Y8=41'", 23 | "'-D CAMERA_CONFIG_PIN_Y7=42'", 24 | "'-D CAMERA_CONFIG_PIN_Y6=12'", 25 | "'-D CAMERA_CONFIG_PIN_Y5=3'", 26 | "'-D CAMERA_CONFIG_PIN_Y4=14'", 27 | "'-D CAMERA_CONFIG_PIN_Y3=47'", 28 | "'-D CAMERA_CONFIG_PIN_Y2=13'", 29 | "'-D CAMERA_CONFIG_PIN_VSYNC=21'", 30 | "'-D CAMERA_CONFIG_PIN_HREF=38'", 31 | "'-D CAMERA_CONFIG_PIN_PCLK=11'", 32 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 33 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 34 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 35 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 36 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 37 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 38 | ], 39 | "f_cpu": "240000000L", 40 | "f_flash": "80000000L", 41 | "flash_mode": "dout", 42 | "hwids": [ 43 | [ 44 | "0X303A", 45 | "0x1001" 46 | ] 47 | ], 48 | "mcu": "esp32s3", 49 | "variant": "esp32s3camlcd" 50 | }, 51 | "connectivity": [ 52 | "bluetooth", 53 | "wifi" 54 | ], 55 | "debug": { 56 | "openocd_target": "esp32s3.cfg" 57 | }, 58 | "frameworks": [ 59 | "arduino", 60 | "espidf" 61 | ], 62 | "name": "ESP32S3-CAM LCD", 63 | "upload": { 64 | "flash_size": "8MB", 65 | "maximum_ram_size": 327680, 66 | "maximum_size": 8388608, 67 | "require_upload_port": true, 68 | "speed": 460800 69 | }, 70 | "url": "https://www.espressif.com/en/news/Maple_Eye_ESP32-S3", 71 | "vendor": "Espressif" 72 | } -------------------------------------------------------------------------------- /boards/esp32cam_espressif_esp32s3_eye.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32s3_out.ld", 5 | "partitions": "default_8MB.csv", 6 | "memory_type": "qio_opi" 7 | }, 8 | "core": "esp32", 9 | "extra_flags": [ 10 | "'-D ESP32CAM_ESPRESSIF_ESP32S3_EYE'", 11 | "'-D BOARD_HAS_PSRAM'", 12 | "'-D ARDUINO_USB_MODE=1'", 13 | "'-D ARDUINO_USB_CDC_ON_BOOT=1'", 14 | "'-D ARDUINO_RUNNING_CORE=1'", 15 | "'-D ARDUINO_EVENT_RUNNING_CORE=1'", 16 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 17 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 18 | "'-D CAMERA_CONFIG_PIN_XCLK=15'", 19 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=4'", 20 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=5'", 21 | "'-D CAMERA_CONFIG_PIN_Y9=16'", 22 | "'-D CAMERA_CONFIG_PIN_Y8=17'", 23 | "'-D CAMERA_CONFIG_PIN_Y7=18'", 24 | "'-D CAMERA_CONFIG_PIN_Y6=12'", 25 | "'-D CAMERA_CONFIG_PIN_Y5=10'", 26 | "'-D CAMERA_CONFIG_PIN_Y4=8'", 27 | "'-D CAMERA_CONFIG_PIN_Y3=9'", 28 | "'-D CAMERA_CONFIG_PIN_Y2=11'", 29 | "'-D CAMERA_CONFIG_PIN_VSYNC=6'", 30 | "'-D CAMERA_CONFIG_PIN_HREF=7'", 31 | "'-D CAMERA_CONFIG_PIN_PCLK=13'", 32 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 33 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 34 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 35 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 36 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 37 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 38 | ], 39 | "f_cpu": "240000000L", 40 | "f_flash": "80000000L", 41 | "flash_mode": "qio", 42 | "hwids": [ 43 | [ 44 | "0x2886", 45 | "0x0056" 46 | ], 47 | [ 48 | "0x2886", 49 | "0x8056" 50 | ] 51 | ], 52 | "mcu": "esp32s3", 53 | "variant": "esp32s3" 54 | }, 55 | "connectivity": [ 56 | "bluetooth", 57 | "wifi" 58 | ], 59 | "debug": { 60 | "openocd_target": "esp32s3.cfg" 61 | }, 62 | "frameworks": [ 63 | "arduino", 64 | "espidf" 65 | ], 66 | "name": "ESP32S3_EYE", 67 | "upload": { 68 | "flash_size": "8MB", 69 | "maximum_ram_size": 327680, 70 | "maximum_size": 8388608, 71 | "require_upload_port": true, 72 | "speed": 460800 73 | }, 74 | "url": "https://www.espressif.com/en/products/devkits/esp-eye/overview", 75 | "vendor": "Espressif" 76 | } -------------------------------------------------------------------------------- /boards/esp32cam_espressif_esp_eye.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_ESPRESSIF_ESP_EYE'", 10 | "'-D BOARD_HAS_PSRAM'", 11 | "'-mfix-esp32-psram-cache-issue'", 12 | "'-D USER_LED_GPIO=14'", 13 | "'-D USER_LED_ON_LEVEL=HIGH'", 14 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 15 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 16 | "'-D CAMERA_CONFIG_PIN_XCLK=11'", 17 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=17'", 18 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=41'", 19 | "'-D CAMERA_CONFIG_PIN_Y9=13'", 20 | "'-D CAMERA_CONFIG_PIN_Y8=4'", 21 | "'-D CAMERA_CONFIG_PIN_Y7=10'", 22 | "'-D CAMERA_CONFIG_PIN_Y6=5'", 23 | "'-D CAMERA_CONFIG_PIN_Y5=7'", 24 | "'-D CAMERA_CONFIG_PIN_Y4=16'", 25 | "'-D CAMERA_CONFIG_PIN_Y3=15'", 26 | "'-D CAMERA_CONFIG_PIN_Y2=6'", 27 | "'-D CAMERA_CONFIG_PIN_VSYNC=42'", 28 | "'-D CAMERA_CONFIG_PIN_HREF=18'", 29 | "'-D CAMERA_CONFIG_PIN_PCLK=12'", 30 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 31 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 32 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 33 | "'-D CAMERA_CONFIG_FB_COUNT=1'", 34 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 35 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 36 | ], 37 | "f_cpu": "240000000L", 38 | "f_flash": "40000000L", 39 | "flash_mode": "dio", 40 | "mcu": "esp32", 41 | "variant": "esp32" 42 | }, 43 | "connectivity": [ 44 | "wifi", 45 | "bluetooth", 46 | "ethernet", 47 | "can" 48 | ], 49 | "debug": { 50 | "openocd_board": "esp-wroom-32.cfg" 51 | }, 52 | "frameworks": [ 53 | "arduino", 54 | "espidf" 55 | ], 56 | "name": "ESP32-CAM AI Thinker", 57 | "upload": { 58 | "flash_size": "4MB", 59 | "maximum_ram_size": 327680, 60 | "maximum_size": 4194304, 61 | "require_upload_port": true, 62 | "speed": 460800 63 | }, 64 | "url": "https://www.espressif.com/en/products/devkits/esp-eye/overview", 65 | "vendor": "Espressif" 66 | } -------------------------------------------------------------------------------- /boards/esp32cam_freenove_s3_wroom_n8r8.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32s3_out.ld", 5 | "partitions": "default_8MB.csv", 6 | "memory_type": "qio_opi" 7 | }, 8 | "core": "esp32", 9 | "extra_flags": [ 10 | "'-D ARDUINO_ESP32S3_DEV'", 11 | "'-D ARDUINO_USB_MODE=1'", 12 | "'-D BOARD_HAS_PSRAM'", 13 | "'-D ARDUINO_RUNNING_CORE=1'", 14 | "'-D ARDUINO_EVENT_RUNNING_CORE=1'", 15 | "'-D ARDUINO_USB_CDC_ON_BOOT=1'", 16 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 17 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 18 | "'-D CAMERA_CONFIG_PIN_XCLK=15'", 19 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=4'", 20 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=5'", 21 | "'-D CAMERA_CONFIG_PIN_Y9=16'", 22 | "'-D CAMERA_CONFIG_PIN_Y8=17'", 23 | "'-D CAMERA_CONFIG_PIN_Y7=18'", 24 | "'-D CAMERA_CONFIG_PIN_Y6=12'", 25 | "'-D CAMERA_CONFIG_PIN_Y5=10'", 26 | "'-D CAMERA_CONFIG_PIN_Y4=8'", 27 | "'-D CAMERA_CONFIG_PIN_Y3=9'", 28 | "'-D CAMERA_CONFIG_PIN_Y2=11'", 29 | "'-D CAMERA_CONFIG_PIN_VSYNC=6'", 30 | "'-D CAMERA_CONFIG_PIN_HREF=7'", 31 | "'-D CAMERA_CONFIG_PIN_PCLK=13'", 32 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 33 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 34 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 35 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 36 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'" 37 | ], 38 | "f_cpu": "240000000L", 39 | "f_flash": "80000000L", 40 | "flash_mode": "dio", 41 | "hwids": [ 42 | [ 43 | "0x303A", 44 | "0x1001" 45 | ] 46 | ], 47 | "mcu": "esp32s3", 48 | "variant": "esp32s3" 49 | }, 50 | "connectivity": [ 51 | "wifi" 52 | ], 53 | "debug": { 54 | "openocd_target": "esp32s3.cfg" 55 | }, 56 | "frameworks": [ 57 | "arduino", 58 | "espidf" 59 | ], 60 | "name": "ESP32 FREENOVE S3 WROOM", 61 | "upload": { 62 | "flash_size": "4MB", 63 | "maximum_ram_size": 327680, 64 | "maximum_size": 4194304, 65 | "require_upload_port": true, 66 | "speed": 460800 67 | }, 68 | "url": "https://github.com/Freenove/Freenove_ESP32_S3_WROOM_Board", 69 | "vendor": "Freenove" 70 | } 71 | -------------------------------------------------------------------------------- /boards/esp32cam_freenove_wrover_kit.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_WROVER_KIT'", 10 | "'-D BOARD_HAS_PSRAM'", 11 | "'-mfix-esp32-psram-cache-issue'", 12 | "'-D USER_LED_GPIO=2'", 13 | "'-D USER_LED_ON_LEVEL=HIGH'", 14 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 15 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 16 | "'-D CAMERA_CONFIG_PIN_XCLK=21'", 17 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=26'", 18 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=27'", 19 | "'-D CAMERA_CONFIG_PIN_Y9=35'", 20 | "'-D CAMERA_CONFIG_PIN_Y8=34'", 21 | "'-D CAMERA_CONFIG_PIN_Y7=39'", 22 | "'-D CAMERA_CONFIG_PIN_Y6=36'", 23 | "'-D CAMERA_CONFIG_PIN_Y5=19'", 24 | "'-D CAMERA_CONFIG_PIN_Y4=18'", 25 | "'-D CAMERA_CONFIG_PIN_Y3=5'", 26 | "'-D CAMERA_CONFIG_PIN_Y2=4'", 27 | "'-D CAMERA_CONFIG_PIN_VSYNC=25'", 28 | "'-D CAMERA_CONFIG_PIN_HREF=23'", 29 | "'-D CAMERA_CONFIG_PIN_PCLK=22'", 30 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 31 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 32 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 33 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 34 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 35 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 36 | ], 37 | "f_cpu": "240000000L", 38 | "f_flash": "40000000L", 39 | "flash_mode": "dio", 40 | "mcu": "esp32", 41 | "variant": "esp32" 42 | }, 43 | "connectivity": [ 44 | "wifi", 45 | "bluetooth", 46 | "ethernet", 47 | "can" 48 | ], 49 | "debug": { 50 | "openocd_board": "esp-wroom-32.cfg" 51 | }, 52 | "frameworks": [ 53 | "arduino", 54 | "espidf" 55 | ], 56 | "name": "ESP32-CAM WROVER kit", 57 | "upload": { 58 | "flash_size": "4MB", 59 | "maximum_ram_size": 327680, 60 | "maximum_size": 4194304, 61 | "require_upload_port": true, 62 | "speed": 460800 63 | }, 64 | "url": "https://www.aliexpress.com/item/1005004960637276.html", 65 | "vendor": "Freenove" 66 | } -------------------------------------------------------------------------------- /boards/esp32cam_m5stack_atoms3r.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32s3_out.ld", 5 | "partitions": "default_8MB.csv", 6 | "memory_type": "qio_opi" 7 | }, 8 | "core": "esp32", 9 | "extra_flags": [ 10 | "'-D ESP32CAM_M5STACK_ATOMS3R'", 11 | "'-D BOARD_HAS_PSRAM'", 12 | "'-D ARDUINO_USB_MODE=1'", 13 | "'-D ARDUINO_USB_CDC_ON_BOOT=1'", 14 | "'-D ARDUINO_RUNNING_CORE=1'", 15 | "'-D ARDUINO_EVENT_RUNNING_CORE=1'", 16 | "'-D USER_LED_GPIO=GPIO_NUM_NC'", 17 | "'-D USER_LED_ON_LEVEL=GPIO_NUM_NC'", 18 | "'-D CAMERA_POWER_GPIO=18'", 19 | "'-D CAMERA_POWER_ON_LEVEL=LOW'", 20 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 21 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 22 | "'-D CAMERA_CONFIG_PIN_XCLK=21'", 23 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=12'", 24 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=9'", 25 | "'-D CAMERA_CONFIG_PIN_Y9=13'", 26 | "'-D CAMERA_CONFIG_PIN_Y8=11'", 27 | "'-D CAMERA_CONFIG_PIN_Y7=17'", 28 | "'-D CAMERA_CONFIG_PIN_Y6=4'", 29 | "'-D CAMERA_CONFIG_PIN_Y5=48'", 30 | "'-D CAMERA_CONFIG_PIN_Y4=46'", 31 | "'-D CAMERA_CONFIG_PIN_Y3=42'", 32 | "'-D CAMERA_CONFIG_PIN_Y2=3'", 33 | "'-D CAMERA_CONFIG_PIN_VSYNC=10'", 34 | "'-D CAMERA_CONFIG_PIN_HREF=14'", 35 | "'-D CAMERA_CONFIG_PIN_PCLK=40'", 36 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 37 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 38 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 39 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 40 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 41 | "'-D SCCB_I2C_PORT=I2C_NUM_0'", 42 | "'-D GROVE_SDA=2'", 43 | "'-D GROVE_SCL=1'" 44 | ], 45 | "f_cpu": "240000000L", 46 | "f_flash": "80000000L", 47 | "flash_mode": "qio", 48 | "hwids": [ 49 | [ 50 | "0x2886", 51 | "0x0056" 52 | ], 53 | [ 54 | "0x2886", 55 | "0x8056" 56 | ] 57 | ], 58 | "mcu": "esp32s3", 59 | "variant": "esp32s3" 60 | }, 61 | "connectivity": [ 62 | "bluetooth", 63 | "wifi" 64 | ], 65 | "debug": { 66 | "openocd_target": "esp32s3.cfg" 67 | }, 68 | "frameworks": [ 69 | "arduino", 70 | "espidf" 71 | ], 72 | "name": "M5STACK ATOMS3R", 73 | "upload": { 74 | "flash_size": "8MB", 75 | "maximum_ram_size": 327680, 76 | "maximum_size": 8388608, 77 | "require_upload_port": true, 78 | "speed": 460800 79 | }, 80 | "url": "https://docs.m5stack.com/en/unit/esp32cam", 81 | "vendor": "M5STACK" 82 | } 83 | -------------------------------------------------------------------------------- /boards/esp32cam_m5stack_camera.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_M5STACK'", 10 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 11 | "'-D CAMERA_CONFIG_PIN_RESET=15'", 12 | "'-D CAMERA_CONFIG_PIN_XCLK=27'", 13 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'", 14 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'", 15 | "'-D CAMERA_CONFIG_PIN_Y9=19'", 16 | "'-D CAMERA_CONFIG_PIN_Y8=36'", 17 | "'-D CAMERA_CONFIG_PIN_Y7=18'", 18 | "'-D CAMERA_CONFIG_PIN_Y6=39'", 19 | "'-D CAMERA_CONFIG_PIN_Y5=5'", 20 | "'-D CAMERA_CONFIG_PIN_Y4=34'", 21 | "'-D CAMERA_CONFIG_PIN_Y3=35'", 22 | "'-D CAMERA_CONFIG_PIN_Y2=32'", 23 | "'-D CAMERA_CONFIG_PIN_VSYNC=25'", 24 | "'-D CAMERA_CONFIG_PIN_HREF=26'", 25 | "'-D CAMERA_CONFIG_PIN_PCLK=21'", 26 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 27 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 28 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 29 | "'-D CAMERA_CONFIG_FB_COUNT=1'", 30 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'", 31 | "'-D SCCB_I2C_PORT=I2C_NUM_0'", 32 | "'-D GROVE_SDA=13'", 33 | "'-D GROVE_SCL=4'" 34 | ], 35 | "f_cpu": "240000000L", 36 | "f_flash": "40000000L", 37 | "flash_mode": "dio", 38 | "mcu": "esp32", 39 | "variant": "esp32" 40 | }, 41 | "connectivity": [ 42 | "wifi", 43 | "bluetooth", 44 | "ethernet", 45 | "can" 46 | ], 47 | "debug": { 48 | "openocd_board": "esp-wroom-32.cfg" 49 | }, 50 | "frameworks": [ 51 | "arduino", 52 | "espidf" 53 | ], 54 | "name": "ESP32-CAM M5 STACK", 55 | "upload": { 56 | "flash_size": "4MB", 57 | "maximum_ram_size": 327680, 58 | "maximum_size": 4194304, 59 | "require_upload_port": true, 60 | "speed": 460800 61 | }, 62 | "url": "https://docs.m5stack.com/en/unit/m5camera", 63 | "vendor": "M5STACK" 64 | } -------------------------------------------------------------------------------- /boards/esp32cam_m5stack_camera_psram.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_M5STACK_CAMERA_PSRAM'", 10 | "'-D BOARD_HAS_PSRAM'", 11 | "'-mfix-esp32-psram-cache-issue'", 12 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 13 | "'-D CAMERA_CONFIG_PIN_RESET=15'", 14 | "'-D CAMERA_CONFIG_PIN_XCLK=27'", 15 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'", 16 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'", 17 | "'-D CAMERA_CONFIG_PIN_Y9=19'", 18 | "'-D CAMERA_CONFIG_PIN_Y8=36'", 19 | "'-D CAMERA_CONFIG_PIN_Y7=18'", 20 | "'-D CAMERA_CONFIG_PIN_Y6=39'", 21 | "'-D CAMERA_CONFIG_PIN_Y5=5'", 22 | "'-D CAMERA_CONFIG_PIN_Y4=34'", 23 | "'-D CAMERA_CONFIG_PIN_Y3=35'", 24 | "'-D CAMERA_CONFIG_PIN_Y2=32'", 25 | "'-D CAMERA_CONFIG_PIN_VSYNC=22'", 26 | "'-D CAMERA_CONFIG_PIN_HREF=26'", 27 | "'-D CAMERA_CONFIG_PIN_PCLK=21'", 28 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 29 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 30 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 31 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 32 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 33 | "'-D SCCB_I2C_PORT=I2C_NUM_0'", 34 | "'-D GROVE_SDA=13'", 35 | "'-D GROVE_SCL=4'" 36 | ], 37 | "f_cpu": "240000000L", 38 | "f_flash": "40000000L", 39 | "flash_mode": "dio", 40 | "mcu": "esp32", 41 | "variant": "esp32" 42 | }, 43 | "connectivity": [ 44 | "wifi", 45 | "bluetooth", 46 | "ethernet", 47 | "can" 48 | ], 49 | "debug": { 50 | "openocd_board": "esp-wroom-32.cfg" 51 | }, 52 | "frameworks": [ 53 | "arduino", 54 | "espidf" 55 | ], 56 | "name": "ESP32-CAM M5 STACK", 57 | "upload": { 58 | "flash_size": "4MB", 59 | "maximum_ram_size": 327680, 60 | "maximum_size": 4194304, 61 | "require_upload_port": true, 62 | "speed": 460800 63 | }, 64 | "url": "https://docs.m5stack.com/en/unit/m5camera", 65 | "vendor": "M5STACK" 66 | } -------------------------------------------------------------------------------- /boards/esp32cam_m5stack_esp32cam.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_M5STACK_ESP32CAM'", 10 | "'-D BOARD_HAS_PSRAM'", 11 | "'-mfix-esp32-psram-cache-issue'", 12 | "'-D USER_LED_GPIO=16'", 13 | "'-D USER_LED_ON_LEVEL=LOW'", 14 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 15 | "'-D CAMERA_CONFIG_PIN_RESET=15'", 16 | "'-D CAMERA_CONFIG_PIN_XCLK=27'", 17 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'", 18 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'", 19 | "'-D CAMERA_CONFIG_PIN_Y9=19'", 20 | "'-D CAMERA_CONFIG_PIN_Y8=36'", 21 | "'-D CAMERA_CONFIG_PIN_Y7=18'", 22 | "'-D CAMERA_CONFIG_PIN_Y6=39'", 23 | "'-D CAMERA_CONFIG_PIN_Y5=5'", 24 | "'-D CAMERA_CONFIG_PIN_Y4=34'", 25 | "'-D CAMERA_CONFIG_PIN_Y3=35'", 26 | "'-D CAMERA_CONFIG_PIN_Y2=17'", 27 | "'-D CAMERA_CONFIG_PIN_VSYNC=22'", 28 | "'-D CAMERA_CONFIG_PIN_HREF=26'", 29 | "'-D CAMERA_CONFIG_PIN_PCLK=21'", 30 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 31 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 32 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 33 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 34 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 35 | "'-D SCCB_I2C_PORT=I2C_NUM_0'", 36 | "'-D MICROPHONE_GPIO=32'", 37 | "'-D GROVE_SDA=13'", 38 | "'-D GROVE_SCL=4'" 39 | ], 40 | "f_cpu": "240000000L", 41 | "f_flash": "40000000L", 42 | "flash_mode": "dio", 43 | "mcu": "esp32", 44 | "variant": "esp32" 45 | }, 46 | "connectivity": [ 47 | "wifi", 48 | "bluetooth", 49 | "ethernet", 50 | "can" 51 | ], 52 | "debug": { 53 | "openocd_board": "esp-wroom-32.cfg" 54 | }, 55 | "frameworks": [ 56 | "arduino", 57 | "espidf" 58 | ], 59 | "name": "ESP32-CAM M5STACK ESP32CAM", 60 | "upload": { 61 | "flash_size": "4MB", 62 | "maximum_ram_size": 327680, 63 | "maximum_size": 4194304, 64 | "require_upload_port": true, 65 | "speed": 460800 66 | }, 67 | "url": "https://docs.m5stack.com/en/unit/esp32cam", 68 | "vendor": "M5STACK" 69 | } -------------------------------------------------------------------------------- /boards/esp32cam_m5stack_unitcam.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_M5STACK_UNITCAM'", 10 | "'-D USER_LED_GPIO=4'", 11 | "'-D USER_LED_ON_LEVEL=LOW'", 12 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 13 | "'-D CAMERA_CONFIG_PIN_RESET=15'", 14 | "'-D CAMERA_CONFIG_PIN_XCLK=27'", 15 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'", 16 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'", 17 | "'-D CAMERA_CONFIG_PIN_Y9=19'", 18 | "'-D CAMERA_CONFIG_PIN_Y8=36'", 19 | "'-D CAMERA_CONFIG_PIN_Y7=18'", 20 | "'-D CAMERA_CONFIG_PIN_Y6=39'", 21 | "'-D CAMERA_CONFIG_PIN_Y5=5'", 22 | "'-D CAMERA_CONFIG_PIN_Y4=34'", 23 | "'-D CAMERA_CONFIG_PIN_Y3=35'", 24 | "'-D CAMERA_CONFIG_PIN_Y2=32'", 25 | "'-D CAMERA_CONFIG_PIN_VSYNC=22'", 26 | "'-D CAMERA_CONFIG_PIN_HREF=26'", 27 | "'-D CAMERA_CONFIG_PIN_PCLK=21'", 28 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 29 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 30 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 31 | "'-D CAMERA_CONFIG_FB_COUNT=1'", 32 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'", 33 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 34 | ], 35 | "f_cpu": "240000000L", 36 | "f_flash": "40000000L", 37 | "flash_mode": "dio", 38 | "mcu": "esp32", 39 | "variant": "esp32" 40 | }, 41 | "connectivity": [ 42 | "wifi", 43 | "bluetooth", 44 | "ethernet", 45 | "can" 46 | ], 47 | "debug": { 48 | "openocd_board": "esp-wroom-32.cfg" 49 | }, 50 | "frameworks": [ 51 | "arduino", 52 | "espidf" 53 | ], 54 | "name": "ESP32-CAM M5STACK UNITCAM", 55 | "upload": { 56 | "flash_size": "4MB", 57 | "maximum_ram_size": 327680, 58 | "maximum_size": 4194304, 59 | "require_upload_port": true, 60 | "speed": 460800 61 | }, 62 | "url": "https://docs.m5stack.com/en/unit/unit_cam", 63 | "vendor": "M5STACK" 64 | } -------------------------------------------------------------------------------- /boards/esp32cam_m5stack_unitcams3.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32s3_out.ld", 5 | "partitions": "default_8MB.csv", 6 | "memory_type": "qio_opi" 7 | }, 8 | "core": "esp32", 9 | "extra_flags": [ 10 | "'-D ESP32CAM_M5STACK_UNITCAMS3'", 11 | "'-D BOARD_HAS_PSRAM'", 12 | "'-D ARDUINO_USB_MODE=1'", 13 | "'-D ARDUINO_USB_CDC_ON_BOOT=1'", 14 | "'-D ARDUINO_RUNNING_CORE=1'", 15 | "'-D ARDUINO_EVENT_RUNNING_CORE=1'", 16 | "'-D USER_LED_GPIO=14'", 17 | "'-D USER_LED_ON_LEVEL=HIGH'", 18 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 19 | "'-D CAMERA_CONFIG_PIN_RESET=21'", 20 | "'-D CAMERA_CONFIG_PIN_XCLK=11'", 21 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=17'", 22 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=41'", 23 | "'-D CAMERA_CONFIG_PIN_Y9=35'", 24 | "'-D CAMERA_CONFIG_PIN_Y8=34'", 25 | "'-D CAMERA_CONFIG_PIN_Y7=39'", 26 | "'-D CAMERA_CONFIG_PIN_Y6=36'", 27 | "'-D CAMERA_CONFIG_PIN_Y5=19'", 28 | "'-D CAMERA_CONFIG_PIN_Y4=18'", 29 | "'-D CAMERA_CONFIG_PIN_Y3=5'", 30 | "'-D CAMERA_CONFIG_PIN_Y2=4'", 31 | "'-D CAMERA_CONFIG_PIN_VSYNC=25'", 32 | "'-D CAMERA_CONFIG_PIN_HREF=23'", 33 | "'-D CAMERA_CONFIG_PIN_PCLK=22'", 34 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 35 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 36 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 37 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 38 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'", 39 | "'-D SCCB_I2C_PORT=I2C_NUM_0'", 40 | "'-D I2C_MEMS_SDA=48'", 41 | "'-D I2C_MEMS_SCL=47'", 42 | "'-D TF_CS=9'", 43 | "'-D TF_MOSI=38'", 44 | "'-D TF_CLK=39'", 45 | "'-D TF_MISO=40'" 46 | ], 47 | "f_cpu": "240000000L", 48 | "f_flash": "80000000L", 49 | "flash_mode": "qio", 50 | "hwids": [ 51 | [ 52 | "0x2886", 53 | "0x0056" 54 | ], 55 | [ 56 | "0x2886", 57 | "0x8056" 58 | ] 59 | ], 60 | "mcu": "esp32s3", 61 | "variant": "esp32s3" 62 | }, 63 | "connectivity": [ 64 | "bluetooth", 65 | "wifi" 66 | ], 67 | "debug": { 68 | "openocd_target": "esp32s3.cfg" 69 | }, 70 | "frameworks": [ 71 | "arduino", 72 | "espidf" 73 | ], 74 | "name": "ESP32-CAM M5STACK UNITCAMS3", 75 | "upload": { 76 | "flash_size": "16MB", 77 | "maximum_ram_size": 327680, 78 | "maximum_size": 16777216, 79 | "require_upload_port": true, 80 | "speed": 460800 81 | }, 82 | "url": "https://docs.m5stack.com/en/unit/Unit-CamS3", 83 | "vendor": "M5STACK" 84 | } -------------------------------------------------------------------------------- /boards/esp32cam_m5stack_wide.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino":{ 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_M5STACK_WIDE'", 10 | "'-D BOARD_HAS_PSRAM'", 11 | "'-mfix-esp32-psram-cache-issue'", 12 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 13 | "'-D CAMERA_CONFIG_PIN_RESET=15'", 14 | "'-D CAMERA_CONFIG_PIN_XCLK=27'", 15 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=22'", 16 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'", 17 | "'-D CAMERA_CONFIG_PIN_Y9=19'", 18 | "'-D CAMERA_CONFIG_PIN_Y8=36'", 19 | "'-D CAMERA_CONFIG_PIN_Y7=18'", 20 | "'-D CAMERA_CONFIG_PIN_Y6=39'", 21 | "'-D CAMERA_CONFIG_PIN_Y5=5'", 22 | "'-D CAMERA_CONFIG_PIN_Y4=34'", 23 | "'-D CAMERA_CONFIG_PIN_Y3=35'", 24 | "'-D CAMERA_CONFIG_PIN_Y2=32'", 25 | "'-D CAMERA_CONFIG_PIN_VSYNC=25'", 26 | "'-D CAMERA_CONFIG_PIN_HREF=26'", 27 | "'-D CAMERA_CONFIG_PIN_PCLK=21'", 28 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 29 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 30 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 31 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 32 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 33 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 34 | ], 35 | "f_cpu": "240000000L", 36 | "f_flash": "40000000L", 37 | "flash_mode": "dio", 38 | "mcu": "esp32", 39 | "variant": "esp32" 40 | }, 41 | "connectivity": [ 42 | "wifi", 43 | "bluetooth", 44 | "ethernet", 45 | "can" 46 | ], 47 | "debug": { 48 | "openocd_board": "esp-wroom-32.cfg" 49 | }, 50 | "frameworks": [ 51 | "arduino", 52 | "espidf" 53 | ], 54 | "name": "ESP32-CAM M5 STACK WIDE", 55 | "upload": { 56 | "flash_size": "4MB", 57 | "maximum_ram_size": 327680, 58 | "maximum_size": 4194304, 59 | "require_upload_port": true, 60 | "speed": 460800 61 | }, 62 | "url": "https://shop.m5stack.com/collections/m5-cameras", 63 | "vendor": "M5STACK" 64 | } -------------------------------------------------------------------------------- /boards/esp32cam_seeed_xiao_esp32s3_sense.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32s3_out.ld", 5 | "partitions": "default_8MB.csv", 6 | "memory_type": "qio_opi" 7 | }, 8 | "core": "esp32", 9 | "extra_flags": [ 10 | "'-D ESP32CAM_SEEED_XIAO_ESP32S3_SENSE'", 11 | "'-D BOARD_HAS_PSRAM'", 12 | "'-D ARDUINO_USB_MODE=1'", 13 | "'-D ARDUINO_USB_CDC_ON_BOOT=1'", 14 | "'-D ARDUINO_RUNNING_CORE=1'", 15 | "'-D ARDUINO_EVENT_RUNNING_CORE=1'", 16 | "'-D USER_LED_GPIO=21'", 17 | "'-D USER_LED_ON_LEVEL=LOW'", 18 | "'-D CAMERA_CONFIG_PIN_PWDN=GPIO_NUM_NC'", 19 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 20 | "'-D CAMERA_CONFIG_PIN_XCLK=10'", 21 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=40'", 22 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=39'", 23 | "'-D CAMERA_CONFIG_PIN_Y9=48'", 24 | "'-D CAMERA_CONFIG_PIN_Y8=11'", 25 | "'-D CAMERA_CONFIG_PIN_Y7=12'", 26 | "'-D CAMERA_CONFIG_PIN_Y6=14'", 27 | "'-D CAMERA_CONFIG_PIN_Y5=16'", 28 | "'-D CAMERA_CONFIG_PIN_Y4=18'", 29 | "'-D CAMERA_CONFIG_PIN_Y3=17'", 30 | "'-D CAMERA_CONFIG_PIN_Y2=15'", 31 | "'-D CAMERA_CONFIG_PIN_VSYNC=38'", 32 | "'-D CAMERA_CONFIG_PIN_HREF=47'", 33 | "'-D CAMERA_CONFIG_PIN_PCLK=13'", 34 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 35 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 36 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 37 | "'-D CAMERA_CONFIG_FB_COUNT=2'", 38 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_PSRAM'", 39 | "'-D SCCB_I2C_PORT=I2C_NUM_0'", 40 | "'-D I2C_MEMS_SDA=41'", 41 | "'-D I2C_MEMS_SCL=42'", 42 | "'-D TF_CS=21'", 43 | "'-D TF_MOSI=10'", 44 | "'-D TF_CLK=8'", 45 | "'-D TF_MISO=9'" 46 | ], 47 | "f_cpu": "240000000L", 48 | "f_flash": "80000000L", 49 | "flash_mode": "qio", 50 | "hwids": [ 51 | [ 52 | "0x2886", 53 | "0x0056" 54 | ], 55 | [ 56 | "0x2886", 57 | "0x8056" 58 | ] 59 | ], 60 | "mcu": "esp32s3", 61 | "variant": "esp32s3" 62 | }, 63 | "connectivity": [ 64 | "bluetooth", 65 | "wifi" 66 | ], 67 | "debug": { 68 | "openocd_target": "esp32s3.cfg" 69 | }, 70 | "frameworks": [ 71 | "arduino", 72 | "espidf" 73 | ], 74 | "name": "Seeed Studio XIAO ESP32S3 Sense", 75 | "upload": { 76 | "flash_size": "8MB", 77 | "maximum_ram_size": 327680, 78 | "maximum_size": 8388608, 79 | "require_upload_port": true, 80 | "speed": 460800 81 | }, 82 | "url": "https://www.seeedstudio.com/XIAO-ESP32S3-p-5627.html", 83 | "vendor": "Seeed Studio" 84 | } -------------------------------------------------------------------------------- /boards/esp32cam_ttgo_t_camera.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_TTGO_T_CAMERA'", 10 | "'-D CAMERA_CONFIG_PIN_PWDN=26'", 11 | "'-D CAMERA_CONFIG_PIN_RESET=GPIO_NUM_NC'", 12 | "'-D CAMERA_CONFIG_PIN_XCLK=32'", 13 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=13'", 14 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=12'", 15 | "'-D CAMERA_CONFIG_PIN_Y9=39'", 16 | "'-D CAMERA_CONFIG_PIN_Y8=36'", 17 | "'-D CAMERA_CONFIG_PIN_Y7=23'", 18 | "'-D CAMERA_CONFIG_PIN_Y6=18'", 19 | "'-D CAMERA_CONFIG_PIN_Y5=15'", 20 | "'-D CAMERA_CONFIG_PIN_Y4=4'", 21 | "'-D CAMERA_CONFIG_PIN_Y3=14'", 22 | "'-D CAMERA_CONFIG_PIN_Y2=5'", 23 | "'-D CAMERA_CONFIG_PIN_VSYNC=27'", 24 | "'-D CAMERA_CONFIG_PIN_HREF=25'", 25 | "'-D CAMERA_CONFIG_PIN_PCLK=19'", 26 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 27 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 28 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 29 | "'-D CAMERA_CONFIG_FB_COUNT=1'", 30 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'", 31 | "'-D SCCB_I2C_PORT=I2C_NUM_0'", 32 | "'-D LCD_SSD1306_PIN_SDA=21'", 33 | "'-D LCD_SSD1306_PIN_SCL=22'", 34 | "'-D BUTTON_RIGHT_PIN=34'", 35 | "'-D PIR_PIN=33'" 36 | ], 37 | "f_cpu": "240000000L", 38 | "f_flash": "40000000L", 39 | "flash_mode": "dio", 40 | "mcu": "esp32", 41 | "variant": "esp32" 42 | }, 43 | "connectivity": [ 44 | "wifi", 45 | "bluetooth", 46 | "ethernet", 47 | "can" 48 | ], 49 | "debug": { 50 | "openocd_board": "esp-wroom-32.cfg" 51 | }, 52 | "frameworks": [ 53 | "arduino", 54 | "espidf" 55 | ], 56 | "name": "ESP32-CAM TTGO-T-CAMERA", 57 | "upload": { 58 | "flash_size": "4MB", 59 | "maximum_ram_size": 327680, 60 | "maximum_size": 4194304, 61 | "require_upload_port": true, 62 | "speed": 460800 63 | }, 64 | "url": "https://www.lilygo.cc/products/", 65 | "vendor": "LILYGO" 66 | } -------------------------------------------------------------------------------- /boards/esp32cam_ttgo_t_journal.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "arduino": { 4 | "ldscript": "esp32_out.ld", 5 | "partitions": "huge_app.csv" 6 | }, 7 | "core": "esp32", 8 | "extra_flags": [ 9 | "'-D ESP32CAM_TTGO_T_JOURNAL'", 10 | "'-D CAMERA_CONFIG_PIN_PWDN=0'", 11 | "'-D CAMERA_CONFIG_PIN_RESET=15'", 12 | "'-D CAMERA_CONFIG_PIN_XCLK=27'", 13 | "'-D CAMERA_CONFIG_PIN_SCCB_SDA=25'", 14 | "'-D CAMERA_CONFIG_PIN_SCCB_SCL=23'", 15 | "'-D CAMERA_CONFIG_PIN_Y9=19'", 16 | "'-D CAMERA_CONFIG_PIN_Y8=36'", 17 | "'-D CAMERA_CONFIG_PIN_Y7=18'", 18 | "'-D CAMERA_CONFIG_PIN_Y6=39'", 19 | "'-D CAMERA_CONFIG_PIN_Y5=5'", 20 | "'-D CAMERA_CONFIG_PIN_Y4=34'", 21 | "'-D CAMERA_CONFIG_PIN_Y3=35'", 22 | "'-D CAMERA_CONFIG_PIN_Y2=17'", 23 | "'-D CAMERA_CONFIG_PIN_VSYNC=22'", 24 | "'-D CAMERA_CONFIG_PIN_HREF=26'", 25 | "'-D CAMERA_CONFIG_PIN_PCLK=21'", 26 | "'-D CAMERA_CONFIG_CLK_FREQ_HZ=20000000'", 27 | "'-D CAMERA_CONFIG_LEDC_TIMER=LEDC_TIMER_0'", 28 | "'-D CAMERA_CONFIG_LEDC_CHANNEL=LEDC_CHANNEL_0'", 29 | "'-D CAMERA_CONFIG_FB_COUNT=1'", 30 | "'-D CAMERA_CONFIG_FB_LOCATION=CAMERA_FB_IN_DRAM'", 31 | "'-D SCCB_I2C_PORT=I2C_NUM_0'" 32 | ], 33 | "f_cpu": "240000000L", 34 | "f_flash": "40000000L", 35 | "flash_mode": "dio", 36 | "mcu": "esp32", 37 | "variant": "esp32" 38 | }, 39 | "connectivity": [ 40 | "wifi", 41 | "bluetooth", 42 | "ethernet", 43 | "can" 44 | ], 45 | "debug": { 46 | "openocd_board": "esp-wroom-32.cfg" 47 | }, 48 | "frameworks": [ 49 | "arduino", 50 | "espidf" 51 | ], 52 | "name": "ESP32-CAM TTGO-T-JOURNAL", 53 | "upload": { 54 | "flash_size": "4MB", 55 | "maximum_ram_size": 327680, 56 | "maximum_size": 4194304, 57 | "require_upload_port": true, 58 | "speed": 460800 59 | }, 60 | "url": "https://www.lilygo.cc/products/", 61 | "vendor": "LILYGO" 62 | } -------------------------------------------------------------------------------- /generate_html.ps1: -------------------------------------------------------------------------------- 1 | . python3 -m pip install --upgrade pip setuptools wheel 2 | . python3 -m pip install minify-html 3 | 4 | . python3 ./minify.py ./html/index.html ./html/index.min.html -------------------------------------------------------------------------------- /generate_html.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | python3 -m pip install --upgrade pip setuptools wheel 4 | python3 -m pip install minify-html 5 | 6 | python3 ./minify.py ./html/index.html ./html/index.min.html -------------------------------------------------------------------------------- /html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 92 | {{AppTitle}} v{{AppVersion}} 93 | 94 | 95 | 96 |

{{ThingName}}

97 |
98 | 99 |
100 |

101 | Press on the button below to change the settings

102 | 104 |

105 |
106 | 107 | 108 |

ESP32

109 |
110 |
Board type:
111 |
{{BoardType}}
112 |
SDK Version:
113 |
{{SDKVersion}}
114 |
CPU model:
115 |
{{ChipModel}} rev. {{ChipRevision}}
116 |
CPU speed:
117 |
{{CpuFreqMHz}} Mhz
118 |
CPU cores:
119 |
{{CpuCores}}
120 |
RAM size:
121 |
{{HeapSize}}
122 |
PSRAM size:
123 |
{{PsRamSize}}
124 |
Flash size:
125 |
{{FlashSize}}
126 |
127 | 128 |

Diagnostics

129 |
130 |
Uptime:
131 |
{{Uptime}}
132 |
RTSP sessions:
133 |
{{NumRTSPSessions}}
134 |
Free heap:
135 |
{{FreeHeap}}
136 |
Max free block:
137 |
{{MaxAllocHeap}}
138 |
139 | 140 |

Network

141 |
142 |
Host name:
143 |
{{HostName}}
144 |
Mac address:
145 |
{{MacAddress}}
146 |
Wifi mode:
147 |
{{WifiMode}}
148 |
Access point:
149 |
{{AccessPoint}}
150 |
Signal strength:
151 |
{{SignalStrength}} dbm
152 |
IPv4 address:
153 |
{{IPv4}}
154 |
IPv6 address:
155 |
{{IPv6}}
156 |
157 | 158 | {{#NetworkState.ApMode}} 159 |
160 |

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

161 |
162 | {{/NetworkState.ApMode}} 163 | 164 | {{#NetworkState.OnLine}} 165 |
166 |

Connected to the access point

167 |
168 | {{/NetworkState.OnLine}} 169 | 170 |

Camera

171 |
172 |
Frame rate:
173 |
{{FrameDuration}} ms ({{FrameFrequency}} f/s)
174 |
Frame size:
175 |
{{FrameSize}}
176 |
JPEG quality:
177 |
{{JpegQuality}} [1-100]
178 |
Brightness:
179 |
{{Brightness}} [-2,2]
180 |
Contrast:
181 |
{{Contrast}} [-2,2]
182 |
Saturation:
183 |
{{Saturation}} [-2,2]
184 |
Special effect:
185 |
{{SpecialEffect}}
186 |
White balance:
187 |
{{#WhiteBal}}Auto{{/WhiteBal}}{{^WhiteBal}}Manual{{/WhiteBal}}
188 |
AWB gain:
189 |
{{#AwbGain}}Auto{{/AwbGain}}{{^AwbGain}}Manual{{/AwbGain}}
190 |
WB mode:
191 |
{{WbMode}}
192 |
Exposure control:
193 |
{{#ExposureCtrl}}Auto{{/ExposureCtrl}}{{^ExposureCtrl}}Manual{{/ExposureCtrl}}
194 |
Auto exposure control (dsp):
195 |
{{#Aec2}}Enabled{{/Aec2}}{{^Aec2}}Disabled{{/Aec2}}
196 |
Auto Exposure level:
197 |
{{AeLevel}}
198 |
Manual exposure value:
199 |
{{AecValue}}
200 |
Gain control:
201 |
{{#GainCtrl}}Auto{{/GainCtrl}}{{^GainCtrl}}Manual{{/GainCtrl}}
202 |
AGC gain:
203 |
{{AgcGain}}
204 |
Gain ceiling:
205 |
{{GainCeiling}}
206 |
Black pixel correct:
207 |
{{#Bpc}}Auto{{/Bpc}}{{^Bpc}}Manual{{/Bpc}}
208 |
White pixel correct:
209 |
{{#Wpc}}Auto{{/Wpc}}{{^Wpc}}Manual{{/Wpc}}
210 |
Gamma correct:
211 |
{{#RawGma}}Enabled{{/RawGma}}{{^RawGma}}Disabled{{/RawGma}}
212 |
Lens correction:
213 |
{{#Lenc}}Enabled{{/Lenc}}{{^Lenc}}Disabled{{/Lenc}}
214 |
Horizontal mirror:
215 |
{{#HMirror}}Mirrored{{/HMirror}}{{^HMirror}}Normal{{/HMirror}}
216 |
Vertical flip:
217 |
{{#VFlip}}Flipped{{/VFlip}}{{^VFlip}}Normal{{/VFlip}}
218 |
Downsize enable:
219 |
{{#Dcw}}Enabled{{/Dcw}}{{^Dcw}}Disabled{{/Dcw}}
220 |
Color bar:
221 |
{{#ColorBar}}Enabled{{/ColorBar}}{{^ColorBar}}Camera{{/ColorBar}}
222 |
223 | 224 | {{#CameraInitialized}} 225 |
226 |

Camera was initialized successfully!

227 |
228 | {{/CameraInitialized}} 229 | {{^CameraInitialized}} 230 |
231 |

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

234 | 235 |

236 |
237 | {{/CameraInitialized}} 238 | 239 | 240 |

Special URLs / API

241 |
242 |
RTSP camera stream:
243 |
rtsp://{{IPv4}}:{{RtspPort}}/mjpeg/1
244 |
JPEG Motion stream:
245 |
http://{{IPv4}}/stream
246 |
Snapshot of the camera:
247 |
http://{{IPv4}}/snapshot
248 |
249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /html/index.min.html: -------------------------------------------------------------------------------- 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
-------------------------------------------------------------------------------- /include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /include/format_duration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | String format_duration(time_t seconds) 4 | { 5 | auto days = seconds / (60 * 60 * 24); 6 | auto tm = gmtime(&seconds); 7 | String duration = days > 0 ? String(days) + " days, " : ""; 8 | char time_buff[9]; 9 | strftime(time_buff, 9, "%H:%M:%S", tm); 10 | return duration + time_buff; 11 | } -------------------------------------------------------------------------------- /include/format_number.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | String format_value(double value) 6 | { 7 | if (value == 0.0) 8 | return "0"; 9 | 10 | if (value < 0) 11 | return "-" + format_value(-value); 12 | 13 | // No decimal places 14 | if (value >= 1) 15 | return String(value, 0); 16 | if (value < 0.00001) 17 | return String(value, 6); 18 | if (value < 0.0001) 19 | return String(value, 5); 20 | if (value < 0.001) 21 | return String(value, 4); 22 | if (value < 0.01) 23 | return String(value, 3); 24 | if (value < 0.1) 25 | return String(value, 2); 26 | return String(value, 1); 27 | } 28 | 29 | String format_si(double value, int decimal_places = 2) 30 | { 31 | if (value == 0.0) 32 | return "0"; 33 | 34 | if (value < 0) 35 | return "-" + format_si(-value, decimal_places); 36 | 37 | auto value_abs = fabs(value); 38 | if (value_abs < 1E-9) 39 | return String(value * 1E12, decimal_places) + "p"; 40 | if (value_abs < 1E-6) 41 | return String(value * 1E9, decimal_places) + "n"; 42 | if (value_abs < 1E-3) 43 | return String(value * 1E6, decimal_places) + "u"; 44 | if (value_abs < 1) 45 | return String(value * 1E3, decimal_places) + "m"; 46 | if (value_abs < 1E3) 47 | return String(value, decimal_places); 48 | if (value_abs < 1E6) 49 | return String(value / 1E3, decimal_places) + "k"; 50 | if (value_abs < 1E9) 51 | return String(value / 1E6, decimal_places) + "M"; 52 | if (value_abs < 1E12) 53 | return String(value / 1E9, decimal_places) + "G"; 54 | if (value_abs < 1E15) 55 | return String(value / 1E12, decimal_places) + "T"; 56 | 57 | return "NaN"; 58 | } 59 | 60 | String format_memory(size_t bytes, int decimal_places = 2) 61 | { 62 | const char *suffix[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}; 63 | auto val = (double)bytes; 64 | auto suffix_index = 0; 65 | while (val >= 1024.0) 66 | { 67 | val /= 1024; 68 | suffix_index++; 69 | } 70 | 71 | return String(val, decimal_places) + " " + suffix[suffix_index]; 72 | } -------------------------------------------------------------------------------- /include/lookup_camera_effect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct 6 | { 7 | const char name[11]; 8 | const int value; 9 | } camera_effect_entry_t; 10 | 11 | constexpr const camera_effect_entry_t camera_effects[] = { 12 | {"Normal", 0}, 13 | {"Negative", 1}, 14 | {"Grayscale", 2}, 15 | {"Red tint", 3}, 16 | {"Green tint", 4}, 17 | {"Blue tint", 5}, 18 | {"Sepia", 6}}; 19 | 20 | const int lookup_camera_effect(const char *name) 21 | { 22 | // Lookup table for the frame name to framesize_t 23 | for (const auto &entry : camera_effects) 24 | if (strncmp(entry.name, name, sizeof(entry.name)) == 0) 25 | return entry.value; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /include/lookup_camera_frame_size.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | typedef struct frame_size_entry 7 | { 8 | const char name[17]; 9 | const framesize_t frame_size; 10 | } frame_size_entry_t; 11 | 12 | constexpr const frame_size_entry_t frame_sizes[] = { 13 | {"QQVGA (160x120)", FRAMESIZE_QQVGA}, 14 | {"QCIF (176x144)", FRAMESIZE_QCIF}, 15 | {"HQVGA (240x176)", FRAMESIZE_HQVGA}, 16 | {"240x240", FRAMESIZE_240X240}, 17 | {"QVGA (320x240)", FRAMESIZE_QVGA}, 18 | {"CIF (400x296)", FRAMESIZE_CIF}, 19 | {"HVGA (480x320)", FRAMESIZE_HVGA}, 20 | {"VGA (640x480)", FRAMESIZE_VGA}, 21 | {"SVGA (800x600)", FRAMESIZE_SVGA}, 22 | {"XGA (1024x768)", FRAMESIZE_XGA}, 23 | {"HD (1280x720)", FRAMESIZE_HD}, 24 | {"SXGA (1280x1024)", FRAMESIZE_SXGA}, 25 | {"UXGA (1600x1200)", FRAMESIZE_UXGA}}; 26 | 27 | const framesize_t lookup_frame_size(const char *pin) 28 | { 29 | // Lookup table for the frame name to framesize_t 30 | for (const auto &entry : frame_sizes) 31 | if (strncmp(entry.name, pin, sizeof(entry.name)) == 0) 32 | return entry.frame_size; 33 | 34 | return FRAMESIZE_INVALID; 35 | } -------------------------------------------------------------------------------- /include/lookup_camera_gainceiling.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | typedef struct 7 | { 8 | const char name[5]; 9 | const gainceiling_t value; 10 | } camera_gainceiling_entry_t; 11 | 12 | constexpr const camera_gainceiling_entry_t camera_gain_ceilings[] = { 13 | {"2X", GAINCEILING_2X}, 14 | {"4X", GAINCEILING_4X}, 15 | {"8X", GAINCEILING_8X}, 16 | {"16X", GAINCEILING_16X}, 17 | {"32X", GAINCEILING_32X}, 18 | {"64X", GAINCEILING_64X}, 19 | {"128X", GAINCEILING_128X}}; 20 | 21 | const gainceiling_t lookup_camera_gainceiling(const char *name) 22 | { 23 | // Lookup table for the frame name to framesize_t 24 | for (const auto &entry : camera_gain_ceilings) 25 | if (strncmp(entry.name, name, sizeof(entry.name)) == 0) 26 | return entry.value; 27 | 28 | return GAINCEILING_2X; 29 | } 30 | -------------------------------------------------------------------------------- /include/lookup_camera_wb_mode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct 6 | { 7 | const char name[7]; 8 | const int value; 9 | } camera_wb_mode_entry_t; 10 | 11 | constexpr const camera_wb_mode_entry_t camera_wb_modes[] = { 12 | {"Auto", 0}, 13 | {"Sunny", 1}, 14 | {"Cloudy", 2}, 15 | {"Office", 3}, 16 | {"Home", 4}}; 17 | 18 | const int lookup_camera_wb_mode(const char *name) 19 | { 20 | // Lookup table for the frame name to framesize_t 21 | for (const auto &entry : camera_wb_modes) 22 | if (strncmp(entry.name, name, sizeof(entry.name)) == 0) 23 | return entry.value; 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /include/settings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define APP_TITLE "ESP32CAM-RTSP" 4 | #define APP_VERSION "1.0" 5 | 6 | #define WIFI_SSID "ESP32CAM-RTSP" 7 | #define WIFI_PASSWORD nullptr 8 | #define CONFIG_VERSION "1.6" 9 | 10 | #define OTA_PASSWORD "ESP32CAM-RTSP" 11 | 12 | #define RTSP_PORT 554 13 | 14 | #define DEFAULT_FRAME_DURATION 200 15 | #define DEFAULT_FRAME_SIZE "VGA (640x480)" 16 | #define DEFAULT_JPEG_QUALITY (psramFound() ? 12 : 14) 17 | 18 | #define DEFAULT_BRIGHTNESS 0 19 | #define DEFAULT_CONTRAST 0 20 | #define DEFAULT_SATURATION 0 21 | #define DEFAULT_EFFECT "Normal" 22 | #define DEFAULT_WHITE_BALANCE true 23 | #define DEFAULT_WHITE_BALANCE_GAIN true 24 | #define DEFAULT_WHITE_BALANCE_MODE "Auto" 25 | #define DEFAULT_EXPOSURE_CONTROL true 26 | #define DEFAULT_AEC2 true 27 | #define DEFAULT_AE_LEVEL 0 28 | #define DEFAULT_AEC_VALUE 300 29 | #define DEFAULT_GAIN_CONTROL true 30 | #define DEFAULT_AGC_GAIN 0 31 | #define DEFAULT_GAIN_CEILING "2X" 32 | #define DEFAULT_BPC false 33 | #define DEFAULT_WPC true 34 | #define DEFAULT_RAW_GAMMA true 35 | #define DEFAULT_LENC true 36 | #define DEFAULT_HORIZONTAL_MIRROR false 37 | #define DEFAULT_VERTICAL_MIRROR false 38 | #define DEFAULT_DCW true 39 | #define DEFAULT_COLORBAR false 40 | 41 | #define DEFAULT_LED_INTENSITY 0 -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /lib/rtsp_server/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RTSPServer", 3 | "version": "1.0.0", 4 | "description": "RTSP Server", 5 | "dependencies": { 6 | "contrem/arduino-timer": "^2.3.1" 7 | } 8 | } -------------------------------------------------------------------------------- /lib/rtsp_server/rtsp_server.cpp: -------------------------------------------------------------------------------- 1 | #include "rtsp_server.h" 2 | #include 3 | #include 4 | 5 | // URI: e.g. rtsp://192.168.178.27:554/mjpeg/1 6 | rtsp_server::rtsp_server(OV2640 &cam, unsigned long interval, int port /*= 554*/) 7 | : WiFiServer(port), cam_(cam) 8 | { 9 | log_i("Starting RTSP server"); 10 | WiFiServer::begin(); 11 | timer_.every(interval, client_handler, this); 12 | } 13 | size_t rtsp_server::num_connected() 14 | { 15 | return clients_.size(); 16 | } 17 | 18 | void rtsp_server::doLoop() 19 | { 20 | timer_.tick(); 21 | } 22 | 23 | rtsp_server::rtsp_client::rtsp_client(const WiFiClient &client, OV2640 &cam) 24 | { 25 | wifi_client = client; 26 | streamer = std::shared_ptr(new OV2640Streamer(&wifi_client, cam)); 27 | session = std::shared_ptr(new CRtspSession(&wifi_client, streamer.get())); 28 | } 29 | 30 | bool rtsp_server::client_handler(void *arg) 31 | { 32 | auto self = static_cast(arg); 33 | // Check if a client wants to connect 34 | auto new_client = self->accept(); 35 | if (new_client) 36 | self->clients_.push_back(std::unique_ptr(new rtsp_client(new_client, self->cam_))); 37 | 38 | auto now = millis(); 39 | for (const auto &client : self->clients_) 40 | { 41 | // Handle requests 42 | client->session->handleRequests(0); 43 | // Send the frame. For now return the uptime as time marker, currMs 44 | client->session->broadcastCurrentFrame(now); 45 | } 46 | 47 | self->clients_.remove_if([](std::unique_ptr const &c) 48 | { return c->session->m_stopped; }); 49 | 50 | return true; 51 | } -------------------------------------------------------------------------------- /lib/rtsp_server/rtsp_server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class rtsp_server : public WiFiServer 11 | { 12 | public: 13 | rtsp_server(OV2640 &cam, unsigned long interval, int port = 554); 14 | 15 | void doLoop(); 16 | 17 | size_t num_connected(); 18 | 19 | private: 20 | struct rtsp_client 21 | { 22 | public: 23 | rtsp_client(const WiFiClient &client, OV2640 &cam); 24 | 25 | WiFiClient wifi_client; 26 | // Streamer for UDP/TCP based RTP transport 27 | std::shared_ptr streamer; 28 | // RTSP session and state 29 | std::shared_ptr session; 30 | }; 31 | 32 | OV2640 cam_; 33 | std::list> clients_; 34 | uintptr_t task_; 35 | Timer<> timer_; 36 | 37 | static bool client_handler(void *); 38 | }; -------------------------------------------------------------------------------- /minify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | import minify_html 5 | 6 | if (len(sys.argv) <= 2): 7 | print('Usage: minify.py input.html output.html') 8 | sys.exit(1) 9 | 10 | input_file = open(sys.argv[1], 'r') 11 | output_file = open(sys.argv[2], 'w') 12 | 13 | html = input_file.read() 14 | input_file.close() 15 | 16 | html_minified = minify_html.minify(html, minify_css=True) 17 | output_file.write(html_minified) 18 | 19 | output_file.close() 20 | print('Done.') -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | ############################################################################### 12 | [platformio] 13 | #default_envs = esp32cam_ai_thinker 14 | #default_envs = esp32cam_espressif_esp_eye 15 | #default_envs = esp32cam_espressif_esp32s2_cam_board 16 | #default_envs = esp32cam_espressif_esp32s2_cam_header 17 | #default_envs = esp32cam_espressif_esp32s3_cam_lcd 18 | #default_envs = esp32cam_espressif_esp32s3_eye 19 | #default_envs = esp32cam_freenove_wrover_kit 20 | #default_envs = esp32cam_m5stack_camera_psram 21 | #default_envs = esp32cam_m5stack_camera 22 | #default_envs = esp32cam_m5stack_esp32cam 23 | 24 | #default_envs = esp32cam_m5stack_unitcam 25 | #default_envs = esp32cam_m5stack_unitcams3 26 | #default_envs = esp32cam_m5stack_wide 27 | #default_envs = esp32cam_seeed_xiao_esp32s3_sense 28 | #default_envs = esp32cam_ttgo_t_camera 29 | #default_envs = esp32cam_ttgo_t_journal 30 | 31 | [env] 32 | platform = espressif32 33 | framework = arduino 34 | 35 | #upload_protocol = espota 36 | #upload_port = 192.168.178.223 37 | #upload_flags = --auth='ESP32CAM-RTSP' 38 | 39 | # Partition scheme for OTA 40 | board_build.partitions = min_spiffs.csv 41 | 42 | monitor_speed = 115200 43 | monitor_rts = 0 44 | monitor_dtr = 0 45 | monitor_filters = log2file, time, default, esp32_exception_decoder 46 | 47 | build_flags = 48 | -Ofast 49 | -D 'BOARD_NAME="${this.board}"' 50 | -D 'CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE' 51 | -D 'IOTWEBCONF_PASSWORD_LEN=64' 52 | 53 | board_build.embed_txtfiles = 54 | html/index.min.html 55 | 56 | lib_deps = 57 | prampec/IotWebConf@^3.2.1 58 | geeksville/Micro-RTSP@^0.1.6 59 | rzeldent/micro-moustache@^1.0.1 60 | 61 | [env:esp32cam_ai_thinker] 62 | board = esp32cam_ai_thinker 63 | 64 | [env:esp32cam_espressif_esp_eye] 65 | board = esp32cam_espressif_esp_eye 66 | 67 | [env:esp32cam_espressif_esp32s2_cam_board] 68 | # Use board connection 69 | # The 18 pin header on the board has Y5 and Y3 swapped 70 | board = esp32cam_espressif_esp32s2_cam_board 71 | 72 | [env:esp32cam_espressif_esp32s2_cam_header] 73 | # Use header connection 74 | # The 18 pin header on the board has Y5 and Y3 swapped 75 | board = esp32cam_espressif_esp32s2_cam_header 76 | 77 | [env:esp32cam_espressif_esp32s3_cam_lcd] 78 | board = esp32cam_espressif_esp32s3_cam_lcd 79 | 80 | [env:esp32cam_espressif_esp32s3_eye] 81 | board = esp32cam_espressif_esp32s3_eye 82 | 83 | [env:esp32cam_freenove_wrover_kit] 84 | board = esp32cam_freenove_wrover_kit 85 | 86 | [env:esp32cam_m5stack_atoms3r] 87 | board = esp32cam_m5stack_atoms3r 88 | 89 | [env:esp32cam_m5stack_camera_psram] 90 | board = esp32cam_m5stack_camera_psram 91 | 92 | [env:esp32cam_m5stack_camera] 93 | board = esp32cam_m5stack_camera 94 | 95 | [env:esp32cam_m5stack_esp32cam] 96 | board = esp32cam_m5stack_esp32cam 97 | 98 | [env:esp32cam_m5stack_unitcam] 99 | board = esp32cam_m5stack_unitcam 100 | 101 | [env:esp32cam_m5stack_unitcams3] 102 | board = esp32cam_m5stack_unitcams3 103 | 104 | [env:esp32cam_m5stack_wide] 105 | board = esp32cam_m5stack_wide 106 | 107 | [env:esp32cam_seeed_xiao_esp32s3_sense] 108 | board = esp32cam_seeed_xiao_esp32s3_sense 109 | 110 | [env:esp32cam_ttgo_t_camera] 111 | board = esp32cam_ttgo_t_camera 112 | 113 | [env:esp32cam_ttgo_t_journal] 114 | board = esp32cam_ttgo_t_journal -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | // HTML files 20 | extern const char index_html_min_start[] asm("_binary_html_index_min_html_start"); 21 | 22 | auto param_group_camera = iotwebconf::ParameterGroup("camera", "Camera settings"); 23 | auto param_frame_duration = iotwebconf::Builder>("fd").label("Frame duration (ms)").defaultValue(DEFAULT_FRAME_DURATION).min(10).build(); 24 | 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(); 25 | auto param_jpg_quality = iotwebconf::Builder>("q").label("JPG quality").defaultValue(DEFAULT_JPEG_QUALITY).min(1).max(100).build(); 26 | auto param_brightness = iotwebconf::Builder>("b").label("Brightness").defaultValue(DEFAULT_BRIGHTNESS).min(-2).max(2).build(); 27 | auto param_contrast = iotwebconf::Builder>("c").label("Contrast").defaultValue(DEFAULT_CONTRAST).min(-2).max(2).build(); 28 | auto param_saturation = iotwebconf::Builder>("s").label("Saturation").defaultValue(DEFAULT_SATURATION).min(-2).max(2).build(); 29 | 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(); 30 | auto param_whitebal = iotwebconf::Builder("wb").label("White balance").defaultValue(DEFAULT_WHITE_BALANCE).build(); 31 | auto param_awb_gain = iotwebconf::Builder("awbg").label("Automatic white balance gain").defaultValue(DEFAULT_WHITE_BALANCE_GAIN).build(); 32 | 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(); 33 | auto param_exposure_ctrl = iotwebconf::Builder("ec").label("Exposure control").defaultValue(DEFAULT_EXPOSURE_CONTROL).build(); 34 | auto param_aec2 = iotwebconf::Builder("aec2").label("Auto exposure (dsp)").defaultValue(DEFAULT_AEC2).build(); 35 | auto param_ae_level = iotwebconf::Builder>("ael").label("Auto Exposure level").defaultValue(DEFAULT_AE_LEVEL).min(-2).max(2).build(); 36 | auto param_aec_value = iotwebconf::Builder>("aecv").label("Manual exposure value").defaultValue(DEFAULT_AEC_VALUE).min(9).max(1200).build(); 37 | auto param_gain_ctrl = iotwebconf::Builder("gc").label("Gain control").defaultValue(DEFAULT_GAIN_CONTROL).build(); 38 | auto param_agc_gain = iotwebconf::Builder>("agcg").label("AGC gain").defaultValue(DEFAULT_AGC_GAIN).min(0).max(30).build(); 39 | 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(); 40 | auto param_bpc = iotwebconf::Builder("bpc").label("Black pixel correct").defaultValue(DEFAULT_BPC).build(); 41 | auto param_wpc = iotwebconf::Builder("wpc").label("White pixel correct").defaultValue(DEFAULT_WPC).build(); 42 | auto param_raw_gma = iotwebconf::Builder("rg").label("Gamma correct").defaultValue(DEFAULT_RAW_GAMMA).build(); 43 | auto param_lenc = iotwebconf::Builder("lenc").label("Lens correction").defaultValue(DEFAULT_LENC).build(); 44 | auto param_hmirror = iotwebconf::Builder("hm").label("Horizontal mirror").defaultValue(DEFAULT_HORIZONTAL_MIRROR).build(); 45 | auto param_vflip = iotwebconf::Builder("vm").label("Vertical mirror").defaultValue(DEFAULT_VERTICAL_MIRROR).build(); 46 | auto param_dcw = iotwebconf::Builder("dcw").label("Downsize enable").defaultValue(DEFAULT_DCW).build(); 47 | auto param_colorbar = iotwebconf::Builder("cb").label("Colorbar").defaultValue(DEFAULT_COLORBAR).build(); 48 | 49 | // Camera 50 | OV2640 cam; 51 | // DNS Server 52 | DNSServer dnsServer; 53 | // RTSP Server 54 | std::unique_ptr camera_server; 55 | // Web server 56 | WebServer web_server(80); 57 | 58 | auto thingName = String(WIFI_SSID) + "-" + String(ESP.getEfuseMac(), 16); 59 | IotWebConf iotWebConf(thingName.c_str(), &dnsServer, &web_server, WIFI_PASSWORD, CONFIG_VERSION); 60 | 61 | // Camera initialization result 62 | esp_err_t camera_init_result; 63 | 64 | void handle_root() 65 | { 66 | log_v("Handle root"); 67 | // Let IotWebConf test and handle captive portal requests. 68 | if (iotWebConf.handleCaptivePortal()) 69 | return; 70 | 71 | // Format hostname 72 | auto hostname = "esp32-" + WiFi.macAddress() + ".local"; 73 | hostname.replace(":", ""); 74 | hostname.toLowerCase(); 75 | 76 | // Wifi Modes 77 | const char *wifi_modes[] = {"NULL", "STA", "AP", "STA+AP"}; 78 | auto ipv4 = WiFi.getMode() == WIFI_MODE_AP ? WiFi.softAPIP() : WiFi.localIP(); 79 | auto ipv6 = WiFi.getMode() == WIFI_MODE_AP ? WiFi.softAPIPv6() : WiFi.localIPv6(); 80 | 81 | auto initResult = esp_err_to_name(camera_init_result); 82 | if (initResult == nullptr) 83 | initResult = "Unknown reason"; 84 | 85 | moustache_variable_t substitutions[] = { 86 | // Version / CPU 87 | {"AppTitle", APP_TITLE}, 88 | {"AppVersion", APP_VERSION}, 89 | {"BoardType", BOARD_NAME}, 90 | {"ThingName", iotWebConf.getThingName()}, 91 | {"SDKVersion", ESP.getSdkVersion()}, 92 | {"ChipModel", ESP.getChipModel()}, 93 | {"ChipRevision", String(ESP.getChipRevision())}, 94 | {"CpuFreqMHz", String(ESP.getCpuFreqMHz())}, 95 | {"CpuCores", String(ESP.getChipCores())}, 96 | {"FlashSize", format_memory(ESP.getFlashChipSize(), 0)}, 97 | {"HeapSize", format_memory(ESP.getHeapSize())}, 98 | {"PsRamSize", format_memory(ESP.getPsramSize(), 0)}, 99 | // Diagnostics 100 | {"Uptime", String(format_duration(millis() / 1000))}, 101 | {"FreeHeap", format_memory(ESP.getFreeHeap())}, 102 | {"MaxAllocHeap", format_memory(ESP.getMaxAllocHeap())}, 103 | {"NumRTSPSessions", camera_server != nullptr ? String(camera_server->num_connected()) : "RTSP server disabled"}, 104 | // Network 105 | {"HostName", hostname}, 106 | {"MacAddress", WiFi.macAddress()}, 107 | {"AccessPoint", WiFi.SSID()}, 108 | {"SignalStrength", String(WiFi.RSSI())}, 109 | {"WifiMode", wifi_modes[WiFi.getMode()]}, 110 | {"IPv4", ipv4.toString()}, 111 | {"IPv6", ipv6.toString()}, 112 | {"NetworkState.ApMode", String(iotWebConf.getState() == iotwebconf::NetworkState::ApMode)}, 113 | {"NetworkState.OnLine", String(iotWebConf.getState() == iotwebconf::NetworkState::OnLine)}, 114 | // Camera 115 | {"FrameSize", String(param_frame_size.value())}, 116 | {"FrameDuration", String(param_frame_duration.value())}, 117 | {"FrameFrequency", String(1000.0 / param_frame_duration.value(), 1)}, 118 | {"JpegQuality", String(param_jpg_quality.value())}, 119 | {"CameraInitialized", String(camera_init_result == ESP_OK)}, 120 | {"CameraInitResult", String(camera_init_result)}, 121 | {"CameraInitResultText", initResult}, 122 | // Settings 123 | {"Brightness", String(param_brightness.value())}, 124 | {"Contrast", String(param_contrast.value())}, 125 | {"Saturation", String(param_saturation.value())}, 126 | {"SpecialEffect", String(param_special_effect.value())}, 127 | {"WhiteBal", String(param_whitebal.value())}, 128 | {"AwbGain", String(param_awb_gain.value())}, 129 | {"WbMode", String(param_wb_mode.value())}, 130 | {"ExposureCtrl", String(param_exposure_ctrl.value())}, 131 | {"Aec2", String(param_aec2.value())}, 132 | {"AeLevel", String(param_ae_level.value())}, 133 | {"AecValue", String(param_aec_value.value())}, 134 | {"GainCtrl", String(param_gain_ctrl.value())}, 135 | {"AgcGain", String(param_agc_gain.value())}, 136 | {"GainCeiling", String(param_gain_ceiling.value())}, 137 | {"Bpc", String(param_bpc.value())}, 138 | {"Wpc", String(param_wpc.value())}, 139 | {"RawGma", String(param_raw_gma.value())}, 140 | {"Lenc", String(param_lenc.value())}, 141 | {"HMirror", String(param_hmirror.value())}, 142 | {"VFlip", String(param_vflip.value())}, 143 | {"Dcw", String(param_dcw.value())}, 144 | {"ColorBar", String(param_colorbar.value())}, 145 | // RTSP 146 | {"RtspPort", String(RTSP_PORT)}}; 147 | 148 | web_server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); 149 | auto html = moustache_render(index_html_min_start, substitutions); 150 | web_server.send(200, "text/html", html); 151 | } 152 | 153 | void handle_snapshot() 154 | { 155 | log_v("handle_snapshot"); 156 | if (camera_init_result != ESP_OK) 157 | { 158 | web_server.send(404, "text/plain", "Camera is not initialized"); 159 | return; 160 | } 161 | 162 | // Remove old images stored in the frame buffer 163 | auto frame_buffers = CAMERA_CONFIG_FB_COUNT; 164 | while (frame_buffers--) 165 | cam.run(); 166 | 167 | auto fb_len = cam.getSize(); 168 | auto fb = (const char *)cam.getfb(); 169 | if (fb == nullptr) 170 | { 171 | web_server.send(404, "text/plain", "Unable to obtain frame buffer from the camera"); 172 | return; 173 | } 174 | 175 | web_server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); 176 | web_server.setContentLength(fb_len); 177 | web_server.send(200, "image/jpeg", ""); 178 | web_server.sendContent(fb, fb_len); 179 | } 180 | 181 | #define STREAM_CONTENT_BOUNDARY "123456789000000000000987654321" 182 | 183 | void handle_stream() 184 | { 185 | log_v("handle_stream"); 186 | if (camera_init_result != ESP_OK) 187 | { 188 | web_server.send(404, "text/plain", "Camera is not initialized"); 189 | return; 190 | } 191 | 192 | log_v("starting streaming"); 193 | // Blocks further handling of HTTP server until stopped 194 | char size_buf[12]; 195 | auto client = web_server.client(); 196 | 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"); 197 | while (client.connected()) 198 | { 199 | client.write("\r\n--" STREAM_CONTENT_BOUNDARY "\r\n"); 200 | cam.run(); 201 | client.write("Content-Type: image/jpeg\r\nContent-Length: "); 202 | sprintf(size_buf, "%d\r\n\r\n", cam.getSize()); 203 | client.write(size_buf); 204 | client.write(cam.getfb(), cam.getSize()); 205 | } 206 | 207 | log_v("client disconnected"); 208 | client.stop(); 209 | log_v("stopped streaming"); 210 | } 211 | 212 | esp_err_t initialize_camera() 213 | { 214 | log_v("initialize_camera"); 215 | 216 | log_i("Frame size: %s", param_frame_size.value()); 217 | auto frame_size = lookup_frame_size(param_frame_size.value()); 218 | log_i("JPEG quality: %d", param_jpg_quality.value()); 219 | auto jpeg_quality = param_jpg_quality.value(); 220 | log_i("Frame duration: %d ms", param_frame_duration.value()); 221 | const camera_config_t camera_config = { 222 | .pin_pwdn = CAMERA_CONFIG_PIN_PWDN, // GPIO pin for camera power down line 223 | .pin_reset = CAMERA_CONFIG_PIN_RESET, // GPIO pin for camera reset line 224 | .pin_xclk = CAMERA_CONFIG_PIN_XCLK, // GPIO pin for camera XCLK line 225 | .pin_sccb_sda = CAMERA_CONFIG_PIN_SCCB_SDA, // GPIO pin for camera SDA line 226 | .pin_sccb_scl = CAMERA_CONFIG_PIN_SCCB_SCL, // GPIO pin for camera SCL line 227 | .pin_d7 = CAMERA_CONFIG_PIN_Y9, // GPIO pin for camera D7 line 228 | .pin_d6 = CAMERA_CONFIG_PIN_Y8, // GPIO pin for camera D6 line 229 | .pin_d5 = CAMERA_CONFIG_PIN_Y7, // GPIO pin for camera D5 line 230 | .pin_d4 = CAMERA_CONFIG_PIN_Y6, // GPIO pin for camera D4 line 231 | .pin_d3 = CAMERA_CONFIG_PIN_Y5, // GPIO pin for camera D3 line 232 | .pin_d2 = CAMERA_CONFIG_PIN_Y4, // GPIO pin for camera D2 line 233 | .pin_d1 = CAMERA_CONFIG_PIN_Y3, // GPIO pin for camera D1 line 234 | .pin_d0 = CAMERA_CONFIG_PIN_Y2, // GPIO pin for camera D0 line 235 | .pin_vsync = CAMERA_CONFIG_PIN_VSYNC, // GPIO pin for camera VSYNC line 236 | .pin_href = CAMERA_CONFIG_PIN_HREF, // GPIO pin for camera HREF line 237 | .pin_pclk = CAMERA_CONFIG_PIN_PCLK, // GPIO pin for camera PCLK line 238 | .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 239 | .ledc_timer = CAMERA_CONFIG_LEDC_TIMER, // LEDC timer to be used for generating XCLK 240 | .ledc_channel = CAMERA_CONFIG_LEDC_CHANNEL, // LEDC channel to be used for generating XCLK 241 | .pixel_format = PIXFORMAT_JPEG, // Format of the pixel data: PIXFORMAT_ + YUV422|GRAYSCALE|RGB565|JPEG 242 | .frame_size = frame_size, // Size of the output image: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA 243 | .jpeg_quality = jpeg_quality, // Quality of JPEG output. 0-63 lower means higher quality 244 | .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) 245 | .fb_location = CAMERA_CONFIG_FB_LOCATION, // The location where the frame buffer will be allocated 246 | .grab_mode = CAMERA_GRAB_LATEST, // When buffers should be filled 247 | #if CONFIG_CAMERA_CONVERTER_ENABLED 248 | conv_mode = CONV_DISABLE, // RGB<->YUV Conversion mode 249 | #endif 250 | .sccb_i2c_port = SCCB_I2C_PORT // If pin_sccb_sda is -1, use the already configured I2C bus by number 251 | }; 252 | 253 | return cam.init(camera_config); 254 | } 255 | 256 | void update_camera_settings() 257 | { 258 | auto camera = esp_camera_sensor_get(); 259 | if (camera == nullptr) 260 | { 261 | log_e("Unable to get camera sensor"); 262 | return; 263 | } 264 | 265 | camera->set_brightness(camera, param_brightness.value()); 266 | camera->set_contrast(camera, param_contrast.value()); 267 | camera->set_saturation(camera, param_saturation.value()); 268 | camera->set_special_effect(camera, lookup_camera_effect(param_special_effect.value())); 269 | camera->set_whitebal(camera, param_whitebal.value()); 270 | camera->set_awb_gain(camera, param_awb_gain.value()); 271 | camera->set_wb_mode(camera, lookup_camera_wb_mode(param_wb_mode.value())); 272 | camera->set_exposure_ctrl(camera, param_exposure_ctrl.value()); 273 | camera->set_aec2(camera, param_aec2.value()); 274 | camera->set_ae_level(camera, param_ae_level.value()); 275 | camera->set_aec_value(camera, param_aec_value.value()); 276 | camera->set_gain_ctrl(camera, param_gain_ctrl.value()); 277 | camera->set_agc_gain(camera, param_agc_gain.value()); 278 | camera->set_gainceiling(camera, lookup_camera_gainceiling(param_gain_ceiling.value())); 279 | camera->set_bpc(camera, param_bpc.value()); 280 | camera->set_wpc(camera, param_wpc.value()); 281 | camera->set_raw_gma(camera, param_raw_gma.value()); 282 | camera->set_lenc(camera, param_lenc.value()); 283 | camera->set_hmirror(camera, param_hmirror.value()); 284 | camera->set_vflip(camera, param_vflip.value()); 285 | camera->set_dcw(camera, param_dcw.value()); 286 | camera->set_colorbar(camera, param_colorbar.value()); 287 | } 288 | 289 | void start_rtsp_server() 290 | { 291 | log_v("start_rtsp_server"); 292 | camera_server = std::unique_ptr(new rtsp_server(cam, param_frame_duration.value(), RTSP_PORT)); 293 | // Add RTSP service to mDNS 294 | // HTTP is already set by iotWebConf 295 | MDNS.addService("rtsp", "tcp", RTSP_PORT); 296 | } 297 | 298 | void on_connected() 299 | { 300 | log_v("on_connected"); 301 | // Start the RTSP Server if initialized 302 | if (camera_init_result == ESP_OK) 303 | start_rtsp_server(); 304 | else 305 | log_e("Not starting RTSP server: camera not initialized"); 306 | } 307 | 308 | void on_config_saved() 309 | { 310 | log_v("on_config_saved"); 311 | update_camera_settings(); 312 | } 313 | 314 | void setup() 315 | { 316 | // Disable brownout 317 | WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); 318 | 319 | #ifdef CAMERA_POWER_GPIO 320 | pinMode(CAMERA_POWER_GPIO, OUTPUT); 321 | digitalWrite(CAMERA_POWER_GPIO, CAMERA_POWER_ON_LEVEL); 322 | #endif 323 | 324 | #ifdef USER_LED_GPIO 325 | pinMode(USER_LED_GPIO, OUTPUT); 326 | digitalWrite(USER_LED_GPIO, !USER_LED_ON_LEVEL); 327 | #endif 328 | 329 | Serial.begin(115200); 330 | Serial.setDebugOutput(true); 331 | 332 | #ifdef ARDUINO_USB_CDC_ON_BOOT 333 | // Delay for USB to connect/settle 334 | delay(5000); 335 | #endif 336 | 337 | log_i("Core debug level: %d", CORE_DEBUG_LEVEL); 338 | log_i("CPU Freq: %d Mhz, %d core(s)", getCpuFrequencyMhz(), ESP.getChipCores()); 339 | log_i("Free heap: %d bytes", ESP.getFreeHeap()); 340 | log_i("SDK version: %s", ESP.getSdkVersion()); 341 | log_i("Board: %s", BOARD_NAME); 342 | log_i("Starting " APP_TITLE "..."); 343 | 344 | if (CAMERA_CONFIG_FB_LOCATION == CAMERA_FB_IN_PSRAM && !psramInit()) 345 | log_e("Failed to initialize PSRAM"); 346 | 347 | param_group_camera.addItem(¶m_frame_duration); 348 | param_group_camera.addItem(¶m_frame_size); 349 | param_group_camera.addItem(¶m_jpg_quality); 350 | param_group_camera.addItem(¶m_brightness); 351 | param_group_camera.addItem(¶m_contrast); 352 | param_group_camera.addItem(¶m_saturation); 353 | param_group_camera.addItem(¶m_special_effect); 354 | param_group_camera.addItem(¶m_whitebal); 355 | param_group_camera.addItem(¶m_awb_gain); 356 | param_group_camera.addItem(¶m_wb_mode); 357 | param_group_camera.addItem(¶m_exposure_ctrl); 358 | param_group_camera.addItem(¶m_aec2); 359 | param_group_camera.addItem(¶m_ae_level); 360 | param_group_camera.addItem(¶m_aec_value); 361 | param_group_camera.addItem(¶m_gain_ctrl); 362 | param_group_camera.addItem(¶m_agc_gain); 363 | param_group_camera.addItem(¶m_gain_ceiling); 364 | param_group_camera.addItem(¶m_bpc); 365 | param_group_camera.addItem(¶m_wpc); 366 | param_group_camera.addItem(¶m_raw_gma); 367 | param_group_camera.addItem(¶m_lenc); 368 | param_group_camera.addItem(¶m_hmirror); 369 | param_group_camera.addItem(¶m_vflip); 370 | param_group_camera.addItem(¶m_dcw); 371 | param_group_camera.addItem(¶m_colorbar); 372 | iotWebConf.addParameterGroup(¶m_group_camera); 373 | 374 | iotWebConf.getApTimeoutParameter()->visible = true; 375 | iotWebConf.setConfigSavedCallback(on_config_saved); 376 | iotWebConf.setWifiConnectionCallback(on_connected); 377 | #ifdef USER_LED_GPIO 378 | iotWebConf.setStatusPin(USER_LED_GPIO, USER_LED_ON_LEVEL); 379 | #endif 380 | iotWebConf.init(); 381 | 382 | // Try to initialize 3 times 383 | for (auto i = 0; i < 3; i++) 384 | { 385 | camera_init_result = initialize_camera(); 386 | if (camera_init_result == ESP_OK) 387 | { 388 | update_camera_settings(); 389 | break; 390 | } 391 | 392 | esp_camera_deinit(); 393 | 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()); 394 | delay(500); 395 | } 396 | 397 | // Set up required URL handlers on the web server 398 | web_server.on("/", HTTP_GET, handle_root); 399 | web_server.on("/config", [] 400 | { iotWebConf.handleConfig(); }); 401 | // Camera snapshot 402 | web_server.on("/snapshot", HTTP_GET, handle_snapshot); 403 | // Camera stream 404 | web_server.on("/stream", HTTP_GET, handle_stream); 405 | 406 | web_server.onNotFound([]() 407 | { iotWebConf.handleNotFound(); }); 408 | } 409 | 410 | void loop() 411 | { 412 | iotWebConf.doLoop(); 413 | 414 | if (camera_server) 415 | camera_server->doLoop(); 416 | } -------------------------------------------------------------------------------- /test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | --------------------------------------------------------------------------------