Compare commits
124 Commits
v1.0.3-rc1
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
db0112e9c2 | |
|
|
9a70b1c31b | |
|
|
d42ba99511 | |
|
|
0b1f3b75cd | |
|
|
8dd9cf66e9 | |
|
|
10cb00fdcd | |
|
|
5608b4c4c4 | |
|
|
df58d5d5cb | |
|
|
80711f9722 | |
|
|
d7e39a1a4d | |
|
|
5888e42c9d | |
|
|
1770b0bc62 | |
|
|
734fe6325b | |
|
|
e93f7ee0e4 | |
|
|
999968ef94 | |
|
|
8180aa84c0 | |
|
|
7a90f47a1e | |
|
|
aebd048651 | |
|
|
607c768832 | |
|
|
41fad4bcd3 | |
|
|
5d0527e7a2 | |
|
|
bc8d613edb | |
|
|
78ed136785 | |
|
|
1e22640cdf | |
|
|
d55035b31a | |
|
|
d9394e4c6b | |
|
|
cf6af3958f | |
|
|
cd63bcb8ad | |
|
|
7148425bd6 | |
|
|
e5814de1ad | |
|
|
6f787e3f9d | |
|
|
fab36176f7 | |
|
|
08a3f076ab | |
|
|
1394cc891f | |
|
|
09fce11834 | |
|
|
e73241d68b | |
|
|
948ebdbd4d | |
|
|
4b2fde2a21 | |
|
|
ba3d4660c7 | |
|
|
4edd60f1c3 | |
|
|
39f10d23df | |
|
|
b29b541eb3 | |
|
|
a80b349576 | |
|
|
9b9fc6cf8a | |
|
|
49c4bb80fe | |
|
|
8e87eaca88 | |
|
|
b29945df10 | |
|
|
009ff6741c | |
|
|
6d13443061 | |
|
|
5a78bc6df3 | |
|
|
65383926d7 | |
|
|
92a8ccfe75 | |
|
|
24e71d5ade | |
|
|
fa57491e22 | |
|
|
496fd111af | |
|
|
5c420e384c | |
|
|
8d6c15d3f2 | |
|
|
9bd5861a0c | |
|
|
b5872f4cf9 | |
|
|
0d94e0a069 | |
|
|
218a3cb02d | |
|
|
be284668b1 | |
|
|
627b951155 | |
|
|
87b950ad2e | |
|
|
6bf260b72c | |
|
|
71de485127 | |
|
|
84f4c965a2 | |
|
|
cff7cf2d19 | |
|
|
ed6e85c494 | |
|
|
dc4a0a6d40 | |
|
|
d1949c0159 | |
|
|
1c44231b82 | |
|
|
c314783328 | |
|
|
b559cbaa42 | |
|
|
220573519a | |
|
|
3f85abd5f3 | |
|
|
2dedf106d1 | |
|
|
3eb1262366 | |
|
|
44e6028a0a | |
|
|
20d030c808 | |
|
|
adf6747aa9 | |
|
|
b64d86d308 | |
|
|
d17f037507 | |
|
|
572da07167 | |
|
|
ed92eb2fdb | |
|
|
7a787943dd | |
|
|
e99a5b6afa | |
|
|
b0c88946b4 | |
|
|
b9d3b9b495 | |
|
|
d792a1c714 | |
|
|
7eec29558f | |
|
|
df1f9e7f4a | |
|
|
ca31ea025f | |
|
|
65e2cee87b | |
|
|
f6e3de0f6f | |
|
|
2689a8f563 | |
|
|
7cbc3b39be | |
|
|
c88d352720 | |
|
|
4fd16e3396 | |
|
|
eaab5da67e | |
|
|
d5199c98ee | |
|
|
0bac260717 | |
|
|
40dc1e08b5 | |
|
|
213e26d1e0 | |
|
|
d7566411ab | |
|
|
5a8854d220 | |
|
|
e247969bca | |
|
|
fea5f552ed | |
|
|
7ff7fb06f5 | |
|
|
a82fa2e48c | |
|
|
51330258d4 | |
|
|
ba209c8c72 | |
|
|
276d0309c2 | |
|
|
ec7b7eabc7 | |
|
|
cee7ebc8ae | |
|
|
55caed062c | |
|
|
4243473169 | |
|
|
b639de0dd7 | |
|
|
583eee9745 | |
|
|
596ecf9ad3 | |
|
|
1ba476103d | |
|
|
6f1148c385 | |
|
|
829e3746b0 | |
|
|
3c9974983d |
|
|
@ -0,0 +1,70 @@
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/c++,macos
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=c++,macos
|
||||||
|
|
||||||
|
### C++ ###
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### macOS Patch ###
|
||||||
|
# iCloud generated files
|
||||||
|
*.icloud
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/c++,macos
|
||||||
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
/**
|
|
||||||
@file Camera_cfg.h
|
|
||||||
|
|
||||||
@brief Here is saved camera GPIO cfg for camera module OV2640
|
|
||||||
|
|
||||||
@author Miroslav Pivovarsky
|
|
||||||
Contact: miroslav.pivovarsky@gmail.com
|
|
||||||
|
|
||||||
@bug: no know bug
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CAMERA_CFG_H_
|
|
||||||
#define _CAMERA_CFG_H_
|
|
||||||
|
|
||||||
// OV2640 camera module pins (CAMERA_MODEL_AI_THINKER)
|
|
||||||
#define PWDN_GPIO_NUM 32 ///< Power down control pin
|
|
||||||
#define RESET_GPIO_NUM -1 ///< Reset control pin
|
|
||||||
#define XCLK_GPIO_NUM 0 ///< External clock pin
|
|
||||||
#define SIOD_GPIO_NUM 26 ///< SCCB: SI/O data pin
|
|
||||||
#define SIOC_GPIO_NUM 27 ///< SCCB: SI/O control pin
|
|
||||||
#define Y9_GPIO_NUM 35 ///< SCCB: Y9 pin
|
|
||||||
#define Y8_GPIO_NUM 34 ///< SCCB: Y8 pin
|
|
||||||
#define Y7_GPIO_NUM 39 ///< SCCB: Y7 pin
|
|
||||||
#define Y6_GPIO_NUM 36 ///< SCCB: Y6 pin
|
|
||||||
#define Y5_GPIO_NUM 21 ///< SCCB: Y5 pin
|
|
||||||
#define Y4_GPIO_NUM 19 ///< SCCB: Y4 pin
|
|
||||||
#define Y3_GPIO_NUM 18 ///< SCCB: Y3 pin
|
|
||||||
#define Y2_GPIO_NUM 5 ///< SCCB: Y2 pin
|
|
||||||
#define VSYNC_GPIO_NUM 25 ///< Vertical sync pin
|
|
||||||
#define HREF_GPIO_NUM 23 ///< Line sync pin
|
|
||||||
#define PCLK_GPIO_NUM 22 ///< Pixel clock pin
|
|
||||||
|
|
||||||
#define FLASH_GPIO_NUM 4 ///< Flash control pin
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
|
||||||
|
|
@ -9,8 +9,7 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CERTIFICATE_H_
|
#pragma once
|
||||||
#define _CERTIFICATE_H_
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
echo -n | openssl s_client -servername connect.prusa.com -connect connect.prusa.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > connect_prusa_com.crt
|
echo -n | openssl s_client -servername connect.prusa.com -connect connect.prusa.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > connect_prusa_com.crt
|
||||||
|
|
@ -54,6 +53,4 @@ emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
)rawliteral";
|
)rawliteral";
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CERTIFICATE_OTA_H_
|
#pragma once
|
||||||
#define _CERTIFICATE_OTA_H_
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
echo -n | openssl s_client -servername github.com -connect github.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > github_com.crt
|
echo -n | openssl s_client -servername github.com -connect github.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > github_com.crt
|
||||||
|
|
@ -135,6 +134,4 @@ RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
)rawliteral";
|
)rawliteral";
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,18 @@
|
||||||
It's neccesary install support for ESP32 board to the arduino IDE. In the board manager we need add next link
|
It's neccesary install support for ESP32 board to the arduino IDE. In the board manager we need add next link
|
||||||
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
|
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
|
||||||
Then we can install "ESP32 by Espressif Systems" board in the board manager.
|
Then we can install "ESP32 by Espressif Systems" board in the board manager.
|
||||||
ESP32 lib version: 2.0.16 (ESP-IDF v4.4.7) by Espressif Systems
|
ESP32 lib version: 3.0.2 (ESP-IDF v5.1.4) by Espressif Systems
|
||||||
|
|
||||||
This project uses other libraries. It is necessary to install them in the arduino IDE.
|
This project uses other libraries. It is necessary to install them in the arduino IDE.
|
||||||
- Library - License - Version - Link
|
- Library - License - Version - Link
|
||||||
- ESPAsyncWebSrv - LGPL 2.1 - 1.2.7 - https://github.com/dvarrel/ESPAsyncWebSrv
|
- ESPAsyncWebServer - LGPL 3.0 - 3.4.5 - https://github.com/mathieucarbou/ESPAsyncWebServer
|
||||||
- AsyncTCP - LGPL 3.0 - 1.1.4 - https://github.com/dvarrel/ESPAsyncTCP
|
- AsyncTCP - LGPL 3.0 - 3.3.1 - https://github.com/mathieucarbou/AsyncTCP
|
||||||
- ArduinoJson - MIT - 7.0.4 - https://github.com/bblanchon/ArduinoJson
|
- ArduinoJson - MIT - 7.3.0 - https://github.com/bblanchon/ArduinoJson
|
||||||
- ArduinoUniqueID - MIT - 1.3.0 - https://github.com/ricaun/ArduinoUniqueID
|
- ArduinoUniqueID - MIT - 1.3.0 - https://github.com/ricaun/ArduinoUniqueID
|
||||||
- ESP32 - LGPL 2.1 - 2.0.16 - https://github.com/espressif/arduino-esp32
|
- arduino-esp32 - LGPL 2.1 - 3.1.0 - https://github.com/espressif/arduino-esp32
|
||||||
|
- DHTnew - MIT - 0.5.2 - https://github.com/RobTillaart/DHTNew
|
||||||
|
|
||||||
Board configuration in the arduino IDE 2.3.2
|
Arduino IDE configuration for the MCU are stored in the module_XXX.h file.
|
||||||
Tools -> Board -> ESP32 Arduino -> AI Thinker ESP32
|
|
||||||
Tools -> CPU Frequency -> 240MHz (WiFi/BT)
|
|
||||||
Tools -> Core debug level -> None
|
|
||||||
Tools -> Flash frequency -> 80MHz
|
|
||||||
Tools -> Flash Mode -> DIO
|
|
||||||
Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
|
||||||
|
|
||||||
When flashing the firmware to a new, empty ESP32-CAM device for the first time, it is necessary to use the 'Erase' function.
|
When flashing the firmware to a new, empty ESP32-CAM device for the first time, it is necessary to use the 'Erase' function.
|
||||||
This can be found under 'Tools' -> 'Erase all Flash Before Sketch Upload' -> 'Enable'.
|
This can be found under 'Tools' -> 'Erase all Flash Before Sketch Upload' -> 'Enable'.
|
||||||
|
|
@ -28,15 +23,6 @@
|
||||||
If you do not disable this option, your camera configuration will continue to be erased from the flash memory
|
If you do not disable this option, your camera configuration will continue to be erased from the flash memory
|
||||||
after uploading new firmware from the Arduino IDE.
|
after uploading new firmware from the Arduino IDE.
|
||||||
|
|
||||||
Here is partitions table
|
|
||||||
# Name, Type, SubType, Offset, Size, Flags
|
|
||||||
nvs, data, nvs, 0x9000, 0x5000,
|
|
||||||
otadata, data, ota, 0xe000, 0x2000,
|
|
||||||
app0, app, ota_0, 0x10000, 0x1E0000,
|
|
||||||
app1, app, ota_1, 0x1F0000,0x1E0000,
|
|
||||||
spiffs, data, spiffs, 0x3D0000,0x20000,
|
|
||||||
coredump, data, coredump,0x3F0000,0x10000,
|
|
||||||
|
|
||||||
Project: ESP32 PrusaConnect Camera
|
Project: ESP32 PrusaConnect Camera
|
||||||
Developed for: Prusa Research, prusa3d.com
|
Developed for: Prusa Research, prusa3d.com
|
||||||
Author: Miroslav Pivovarsky
|
Author: Miroslav Pivovarsky
|
||||||
|
|
@ -44,14 +30,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* includes */
|
/* includes */
|
||||||
#include <WiFi.h>
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <esp_wifi.h>
|
|
||||||
#include "esp32-hal-cpu.h"
|
#include "esp32-hal-cpu.h"
|
||||||
|
|
||||||
#include "server.h"
|
#include "WebServer.h"
|
||||||
#include "cfg.h"
|
#include "cfg.h"
|
||||||
#include "var.h"
|
#include "var.h"
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
|
|
@ -60,7 +44,6 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "wifi_mngt.h"
|
#include "wifi_mngt.h"
|
||||||
#include "stream.h"
|
|
||||||
#include "serial_cfg.h"
|
#include "serial_cfg.h"
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
|
@ -113,32 +96,43 @@ void setup() {
|
||||||
/* init class for communication with PrusaConnect */
|
/* init class for communication with PrusaConnect */
|
||||||
Connect.Init();
|
Connect.Init();
|
||||||
|
|
||||||
/* init tasks */
|
/* init external temperature sensor */
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("Start tasks"));
|
ExternalTemperatureSensor.Init();
|
||||||
xTaskCreatePinnedToCore(System_TaskMain, "SystemNtpOtaUpdate", 8000, NULL, 1, &Task_SystemMain, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
xTaskCreatePinnedToCore(System_TaskCaptureAndSendPhoto, "CaptureAndSendPhoto", 8000, NULL, 2, &Task_CapturePhotoAndSend, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
xTaskCreatePinnedToCore(System_TaskWifiManagement, "WiFiManagement", 3800, NULL, 3, &Task_WiFiManagement, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
xTaskCreatePinnedToCore(System_TaskSdCardCheck, "CheckMicroSdCard", 3300, NULL, 4, &Task_SdCardCheck, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
xTaskCreatePinnedToCore(System_TaskSerialCfg, "CheckSerialConfiguration", 3300, NULL, 5, &Task_SerialCfg, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
xTaskCreatePinnedToCore(System_TaskStreamTelemetry, "PrintStreamTelemetry", 3300, NULL, 6, &Task_StreamTelemetry, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
xTaskCreatePinnedToCore(System_TaskSysLed, "SystemLed", 3000, NULL, 7, &Task_SysLed, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
xTaskCreatePinnedToCore(System_TaskWiFiWatchdog, "WiFiWatchdog", 3500, NULL, 8, &Task_WiFiWatchdog, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
//xTaskCreatePinnedToCore(System_TaskSdCardRemove, "SdCardRemove", 3000, NULL, 9, &Task_SdCardFileRemove, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
|
||||||
|
|
||||||
/* init wdg */
|
/* init wdg */
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("Init WDG"));
|
SystemLog.AddEvent(LogLevel_Info, F("Init WDG"));
|
||||||
esp_task_wdt_init(WDG_TIMEOUT, true); /* enable panic so ESP32 restarts */
|
esp_task_wdt_config_t twdt_config;
|
||||||
esp_task_wdt_add(NULL); /* add current thread to WDT watch */
|
twdt_config.timeout_ms = WDG_TIMEOUT;
|
||||||
esp_task_wdt_add(Task_CapturePhotoAndSend);
|
twdt_config.idle_core_mask = (1 << portNUM_PROCESSORS) - 1, /* Bitmask of all cores */
|
||||||
esp_task_wdt_add(Task_WiFiManagement);
|
twdt_config.trigger_panic = true;
|
||||||
esp_task_wdt_add(Task_SystemMain);
|
|
||||||
esp_task_wdt_add(Task_SdCardCheck);
|
esp_task_wdt_init(&twdt_config); /* enable panic so ESP32 restarts */
|
||||||
esp_task_wdt_add(Task_SerialCfg);
|
esp_task_wdt_reconfigure(&twdt_config);
|
||||||
esp_task_wdt_add(Task_StreamTelemetry);
|
ESP_ERROR_CHECK(esp_task_wdt_add(NULL)); /* add current thread to WDT watch */
|
||||||
esp_task_wdt_add(Task_SysLed);
|
esp_task_wdt_reset(); /* reset wdg */
|
||||||
esp_task_wdt_add(Task_WiFiWatchdog);
|
|
||||||
|
/* init tasks */
|
||||||
|
SystemLog.AddEvent(LogLevel_Info, F("Start tasks"));
|
||||||
|
xTaskCreatePinnedToCore(System_TaskMain, "SystemNtpOtaUpdate", 5200, NULL, 1, &Task_SystemMain, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(Task_SystemMain));
|
||||||
|
xTaskCreatePinnedToCore(System_TaskCaptureAndSendPhoto, "CaptureAndSendPhoto", 4400, NULL, 2, &Task_CapturePhotoAndSend, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(Task_CapturePhotoAndSend));
|
||||||
|
xTaskCreatePinnedToCore(System_TaskWifiManagement, "WiFiManagement", 2700, NULL, 3, &Task_WiFiManagement, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(Task_WiFiManagement));
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
|
xTaskCreatePinnedToCore(System_TaskSdCardCheck, "CheckMicroSdCard", 3000, NULL, 4, &Task_SdCardCheck, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(Task_SdCardCheck));
|
||||||
|
#endif
|
||||||
|
xTaskCreatePinnedToCore(System_TaskSerialCfg, "CheckSerialConfiguration", 2300, NULL, 5, &Task_SerialCfg, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(Task_SerialCfg));
|
||||||
|
xTaskCreatePinnedToCore(System_TaskSystemTelemetry, "PrintSystemTelemetry", 2200, NULL, 6, &Task_SystemTelemetry, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(Task_SystemTelemetry));
|
||||||
|
xTaskCreatePinnedToCore(System_TaskSysLed, "SystemLed", 2000, NULL, 7, &Task_SysLed, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(Task_SysLed));
|
||||||
|
xTaskCreatePinnedToCore(System_TaskWiFiWatchdog, "WiFiWatchdog", 2200, NULL, 8, &Task_WiFiWatchdog, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
|
ESP_ERROR_CHECK(esp_task_wdt_add(Task_WiFiWatchdog));
|
||||||
|
//xTaskCreatePinnedToCore(System_TaskSdCardRemove, "SdCardRemove", 3000, NULL, 9, &Task_SdCardFileRemove, 0); /*function, description, stack size, parameters, priority, task handle, core*/
|
||||||
//esp_task_wdt_add(Task_SdCardFileRemove);
|
//esp_task_wdt_add(Task_SdCardFileRemove);
|
||||||
esp_task_wdt_reset(); /* reset wdg */
|
|
||||||
|
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("MCU configuration done"));
|
SystemLog.AddEvent(LogLevel_Info, F("MCU configuration done"));
|
||||||
}
|
}
|
||||||
|
|
@ -146,6 +140,7 @@ void setup() {
|
||||||
void loop() {
|
void loop() {
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
/**
|
||||||
|
@file ExternalTemperatureSensor.cpp
|
||||||
|
|
||||||
|
@brief Library for external temperature sensor control
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
@bug: no know bug
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ExternalTemperatureSensor.h"
|
||||||
|
|
||||||
|
ExternalSensor ExternalTemperatureSensor(DHT_SENSOR_PIN, DHT_SENSOR_ENABLE, &SystemLog, &SystemConfig);
|
||||||
|
|
||||||
|
ExternalSensor::ExternalSensor(uint8_t i_pin, bool i_enable, Logs *i_log, Configuration *i_cfg) : DhtSensor(i_pin) {
|
||||||
|
Pin = i_pin;
|
||||||
|
SystemEnable = i_enable;
|
||||||
|
log = i_log;
|
||||||
|
config = i_cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalSensor::Init() {
|
||||||
|
log->AddEvent(LogLevel_Info, F("Init external temperature sensor"));
|
||||||
|
Unit = (TemperatureSensorUnit_enum) config->LoadExternalTemperatureSensorUnit();
|
||||||
|
UserEnable = config->LoadExternalTemperatureSensorEnable();
|
||||||
|
//DhtSensor.setHumOffset(10);
|
||||||
|
//DhtSensor.setTempOffset(-3.5);
|
||||||
|
|
||||||
|
ReadSensorData();
|
||||||
|
}
|
||||||
|
|
||||||
|
String ExternalSensor::GetSensorStatus() {
|
||||||
|
String status = "";
|
||||||
|
|
||||||
|
if (false == SystemEnable) {
|
||||||
|
status = "Unsupport sensor";
|
||||||
|
} else if (false == UserEnable) {
|
||||||
|
status = "Sensor disabled";
|
||||||
|
} else {
|
||||||
|
status = "Detected: ";
|
||||||
|
SensorType = DhtSensor.getType();
|
||||||
|
switch (SensorType) {
|
||||||
|
case 0:
|
||||||
|
status += "not defined";
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
status += "DHT11";
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
status += "DHT22";
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
status += "DHT22";
|
||||||
|
break;
|
||||||
|
case 70:
|
||||||
|
status += "Sonoff Si7021";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status += "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalSensor::EnableSensor(bool i_enable) {
|
||||||
|
if (true == SystemEnable) {
|
||||||
|
UserEnable = i_enable;
|
||||||
|
config->SaveExternalTemperatureSensorEnable(UserEnable);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
UserEnable = false;
|
||||||
|
config->SaveExternalTemperatureSensorEnable(UserEnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalSensor::ReadSensorData() {
|
||||||
|
if ((true == SystemEnable) && (true == UserEnable)) {
|
||||||
|
DhtSensor.read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalSensor::SetUnit(TemperatureSensorUnit_enum i_unit) {
|
||||||
|
Unit = i_unit;
|
||||||
|
config->SaveExternalTemperatureSensorUnit(Unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ExternalSensor::GetTemperature() {
|
||||||
|
float temp = 0.0;
|
||||||
|
if ((true == SystemEnable) && (true == UserEnable)) {
|
||||||
|
if (Unit == TEMPERATURE_UNIT_CELSIUS) {
|
||||||
|
temp = DhtSensor.getTemperature();
|
||||||
|
} else if (Unit == TEMPERATURE_UNIT_FAHRENHEIT) {
|
||||||
|
temp = DhtSensor.getTemperature() * 9.0 / 5.0 + 32.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ExternalSensor::GetHumidity() {
|
||||||
|
if ((true == SystemEnable) && (true == UserEnable)) {
|
||||||
|
return DhtSensor.getHumidity();
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String ExternalSensor::GetTemperatureString() {
|
||||||
|
String temp = "";
|
||||||
|
|
||||||
|
if (false == SystemEnable) {
|
||||||
|
temp = "Unsupport";
|
||||||
|
} else if ((false == UserEnable) || (false == SystemEnable)) {
|
||||||
|
temp = "Disabled";
|
||||||
|
} else {
|
||||||
|
if (Unit == TEMPERATURE_UNIT_CELSIUS) {
|
||||||
|
temp = String(GetTemperature(), 1) + " °C";
|
||||||
|
} else if (Unit == TEMPERATURE_UNIT_FAHRENHEIT) {
|
||||||
|
temp = String(GetTemperature(), 1) + " °F";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
String ExternalSensor::GetHumidityString() {
|
||||||
|
String hum = "";
|
||||||
|
|
||||||
|
if (false == SystemEnable) {
|
||||||
|
hum = "Unsupport";
|
||||||
|
} else if ((false == UserEnable) || (false == SystemEnable)) {
|
||||||
|
hum = "Disabled";
|
||||||
|
} else {
|
||||||
|
hum = String(GetHumidity(), 1) + " %";
|
||||||
|
}
|
||||||
|
|
||||||
|
return hum;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExternalSensor::GetUserEnableSensor() {
|
||||||
|
return UserEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
TemperatureSensorUnit_enum ExternalSensor::GetTemperatureUnit() {
|
||||||
|
return Unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
@file ExternalTemperatureSensor.h
|
||||||
|
|
||||||
|
@brief Library for external temperature sensor control
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
@bug: no know bug
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "log.h"
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
#include "module_templates.h"
|
||||||
|
#include <dhtnew.h>
|
||||||
|
#include "cfg.h"
|
||||||
|
#include "ExternalTemperatureSensorTypes.h"
|
||||||
|
|
||||||
|
class Logs;
|
||||||
|
class Configuration;
|
||||||
|
|
||||||
|
class ExternalSensor {
|
||||||
|
private:
|
||||||
|
TemperatureSensorUnit_enum Unit; ///< unit number
|
||||||
|
DHTNEW DhtSensor; ///< DHT sensor object
|
||||||
|
uint8_t Pin; ///< pin number
|
||||||
|
bool SystemEnable; ///< system enable flag
|
||||||
|
bool UserEnable; ///< user enable flag
|
||||||
|
uint8_t SensorType; ///< sensor type
|
||||||
|
|
||||||
|
Logs *log; ///< log object
|
||||||
|
Configuration *config; ///< configuration object
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExternalSensor(uint8_t, bool, Logs *, Configuration *);
|
||||||
|
~ExternalSensor(){};
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
String GetSensorStatus();
|
||||||
|
|
||||||
|
void EnableSensor(bool);
|
||||||
|
void ReadSensorData();
|
||||||
|
void SetUnit(TemperatureSensorUnit_enum);
|
||||||
|
|
||||||
|
float GetTemperature();
|
||||||
|
float GetHumidity();
|
||||||
|
String GetTemperatureString();
|
||||||
|
String GetHumidityString();
|
||||||
|
|
||||||
|
bool GetUserEnableSensor();
|
||||||
|
TemperatureSensorUnit_enum GetTemperatureUnit();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ExternalSensor ExternalTemperatureSensor;
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
@file connect_types.h
|
||||||
|
|
||||||
|
@brief Here are defined types for communication with prusa connect backend
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
@bug: no know bug
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum TemperatureSensorUnit_enum {
|
||||||
|
TEMPERATURE_UNIT_CELSIUS = 0, ///< Celsius
|
||||||
|
TEMPERATURE_UNIT_FAHRENHEIT = 1 ///< Fahrenheit
|
||||||
|
};
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
@ -11,8 +11,7 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _WEB_PAGE_H_
|
#pragma once
|
||||||
#define _WEB_PAGE_H_
|
|
||||||
|
|
||||||
#define MSG_REBOOT_MCU "Reboot process started, wait several seconds for mcu to boot up. You can close this window now"
|
#define MSG_REBOOT_MCU "Reboot process started, wait several seconds for mcu to boot up. You can close this window now"
|
||||||
#define MSG_SAVE_OK_REBOOT "Save OK. Please reboot MCU" ///< WEB app msg save OK
|
#define MSG_SAVE_OK_REBOOT "Save OK. Please reboot MCU" ///< WEB app msg save OK
|
||||||
|
|
@ -28,10 +27,9 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||||
<head>
|
<head>
|
||||||
<meta name="Prusa ESP32-cam" content="width=device-width, initial-scale=1">
|
<meta name="Prusa ESP32-cam" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||||
<title>Prusa ESP32-cam</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="styles.css">
|
<link rel="stylesheet" type="text/css" href="styles.css?v=1.0.0">
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="/jquery-3.7.0.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$("a").click(function (e) {
|
$("a").click(function (e) {
|
||||||
|
|
@ -52,6 +50,7 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||||
<img src="esp32_cam.svg" id=logo alt="Logo image" style="margin-left: 10px;" />
|
<img src="esp32_cam.svg" id=logo alt="Logo image" style="margin-left: 10px;" />
|
||||||
<ul class="top_bar" style="justify-content:flex-start;">
|
<ul class="top_bar" style="justify-content:flex-start;">
|
||||||
<li><a class=p5 href="https://forum.prusa3d.com/forum/prusa-connect-prusalink" id="forum-link">Forum</a></li>
|
<li><a class=p5 href="https://forum.prusa3d.com/forum/prusa-connect-prusalink" id="forum-link">Forum</a></li>
|
||||||
|
<li><a class=p5 href="https://help.prusa3d.com/guide/esp-camera-for-prusa-connect_390199" id="forum-link">Help</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="top_bar" style="justify-content:flex-end;">
|
<ul class="top_bar" style="justify-content:flex-end;">
|
||||||
<li><a class=p4 href="#" onclick="javascript:actionButton('/action_led',true,'')"><div id="light-icon"></div> Light </a></li>
|
<li><a class=p4 href="#" onclick="javascript:actionButton('/action_led',true,'')"><div id="light-icon"></div> Light </a></li>
|
||||||
|
|
@ -70,8 +69,9 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||||
<article>
|
<article>
|
||||||
<p class="p1">Trigger interval: <b><span id="refreshInterval"></span><b>s</p><br><br>
|
<p class="p1">Trigger interval: <b><span id="refreshInterval"></span><b>s</p><br><br>
|
||||||
<button class="btn" onclick="actionButton('/action_capture',true,'')">Refresh Snapshot</button> <br><br>
|
<button class="btn" onclick="actionButton('/action_capture',true,'')">Refresh Snapshot</button> <br><br>
|
||||||
<button class="btn" onclick="actionButton('/action_send',false,'')">Send snapshot</button><br><br><br>
|
<button class="btn" onclick="actionButton('/action_send',false,'Sending snapshot...')">Send snapshot</button><br><br><br>
|
||||||
<button class="btn" onclick="window.open('saved-photo.jpg')">Download snapshot</button><br><br>
|
<button class="btn" onclick="window.open('saved-photo.jpg')">Download snapshot</button><br><br>
|
||||||
|
<button class="btn" onclick="window.open('stream.mjpg')">Start stream</button><br><br>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -79,10 +79,11 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||||
<div id="cfg">
|
<div id="cfg">
|
||||||
<div id="cfg_bar">
|
<div id="cfg_bar">
|
||||||
<div id="links">
|
<div id="links">
|
||||||
<li><a href="page_config.html">Camera configuration</a></li>
|
<li><a href="page_config.html">Camera</a></li>
|
||||||
<li><a href="page_wifi.html">Wi-Fi configuration</a></li>
|
<li><a href="page_wifi.html">Wi-Fi</a></li>
|
||||||
<li><a href="page_auth.html">Authentication</a></li>
|
<li><a href="page_auth.html">Authentication</a></li>
|
||||||
<li><a href="page_system.html">System</a></li>
|
<li><a href="page_system.html">System</a></li>
|
||||||
|
<li><a href="page_temperature.html">Temperature</a></li>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -97,19 +98,19 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||||
<td><a href="https://github.com/Prusa-Development/Prusa-Firmware-ESP32-Cam/" id="github-link"><svg height="25"><image href="github-icon.svg"></svg></a></td>
|
<td><a href="https://github.com/Prusa-Development/Prusa-Firmware-ESP32-Cam/" id="github-link"><svg height="25"><image href="github-icon.svg"></svg></a></td>
|
||||||
</tr></table>
|
</tr></table>
|
||||||
</body>
|
</body>
|
||||||
<script src="scripts.js"></script>
|
<script src="scripts.js"></script>
|
||||||
<script>
|
<script>
|
||||||
sliderCheck();
|
sliderCheck();
|
||||||
get_data();
|
get_data();
|
||||||
addClickListener('github-link');
|
addClickListener('github-link');
|
||||||
addClickListener('forum-link');
|
addClickListener('forum-link');
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
)rawliteral";
|
)rawliteral";
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char page_auth_html[] PROGMEM = R"rawliteral(
|
const char page_auth_html[] PROGMEM = R"rawliteral(
|
||||||
<style>@import url("styles.css");</style>
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
<body>
|
<body>
|
||||||
<center>
|
<center>
|
||||||
|
|
@ -134,7 +135,7 @@ const char page_auth_html[] PROGMEM = R"rawliteral(
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char page_wifi_html[] PROGMEM = R"rawliteral(
|
const char page_wifi_html[] PROGMEM = R"rawliteral(
|
||||||
<style>@import url("styles.css");</style>
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
<body>
|
<body>
|
||||||
<table id="center_tb">
|
<table id="center_tb">
|
||||||
|
|
@ -175,7 +176,7 @@ const char page_wifi_html[] PROGMEM = R"rawliteral(
|
||||||
<table>
|
<table>
|
||||||
<tr><td class="w1">Connect to Wi-Fi network</td></tr>
|
<tr><td class="w1">Connect to Wi-Fi network</td></tr>
|
||||||
<tr><td class="w2" align="right">Wi-Fi network name (SSID) </td><td><input type="text" name="wifi_ssid" id=wifi_ssid_id ></td></tr>
|
<tr><td class="w2" align="right">Wi-Fi network name (SSID) </td><td><input type="text" name="wifi_ssid" id=wifi_ssid_id ></td></tr>
|
||||||
<tr><td class="w2" align="right">Password </td><td><input type="text" name="wifi_pass" id=wifi_pass_id></td></tr>
|
<tr><td class="w2" align="right">Password </td><td><input type="password" name="wifi_pass" id=wifi_pass_id></td></tr>
|
||||||
<tr><td></td><td align="center"><button class="btn_save_w" onclick="setWifi(document.getElementById('wifi_ssid_id').value, document.getElementById('wifi_pass_id').value)">Save & Connect</button></td></tr>
|
<tr><td></td><td align="center"><button class="btn_save_w" onclick="setWifi(document.getElementById('wifi_ssid_id').value, document.getElementById('wifi_pass_id').value)">Save & Connect</button></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</td><td></td></tr>
|
</td><td></td></tr>
|
||||||
|
|
@ -209,12 +210,12 @@ const char page_wifi_html[] PROGMEM = R"rawliteral(
|
||||||
setTimeout(function(){GetDataAndPrintTableWiFi();}, 500);
|
setTimeout(function(){GetDataAndPrintTableWiFi();}, 500);
|
||||||
get_data("wifi");
|
get_data("wifi");
|
||||||
setupCollapsibleButtonsWiFi();
|
setupCollapsibleButtonsWiFi();
|
||||||
</script>
|
</script>
|
||||||
)rawliteral";
|
)rawliteral";
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char page_config_html[] PROGMEM = R"rawliteral(
|
const char page_config_html[] PROGMEM = R"rawliteral(
|
||||||
<style>@import url("styles.css");</style>
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
<body>
|
<body>
|
||||||
<center><table id="data">
|
<center><table id="data">
|
||||||
|
|
@ -307,7 +308,7 @@ const char page_config_html[] PROGMEM = R"rawliteral(
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char page_system_html[] PROGMEM = R"rawliteral(
|
const char page_system_html[] PROGMEM = R"rawliteral(
|
||||||
<style>@import url("styles.css");</style>
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
<body>
|
<body>
|
||||||
<center>
|
<center>
|
||||||
|
|
@ -317,6 +318,7 @@ const char page_system_html[] PROGMEM = R"rawliteral(
|
||||||
<tr><td class="ps1">Wi-Fi mode</td><td class="ps2" id="wifi_mode"></td></tr>
|
<tr><td class="ps1">Wi-Fi mode</td><td class="ps2" id="wifi_mode"></td></tr>
|
||||||
<tr><td class="ps1">Wi-Fi service AP SSID</td><td class="ps2" id="service_ap_ssid"></td></tr>
|
<tr><td class="ps1">Wi-Fi service AP SSID</td><td class="ps2" id="service_ap_ssid"></td></tr>
|
||||||
<tr><td class="ps1">Uptime</td><td class="ps2" id="uptime"></td></tr>
|
<tr><td class="ps1">Uptime</td><td class="ps2" id="uptime"></td></tr>
|
||||||
|
<tr><td class="ps1">ESP32 Temperature</td><td class="ps2" id="mcu_temp"></td></tr>
|
||||||
<tr><td style="height: 1px;"></td><td style="height: 1px;"></td></tr>
|
<tr><td style="height: 1px;"></td><td style="height: 1px;"></td></tr>
|
||||||
<tr><td class="ps3">Firmware</td><td></td></tr>
|
<tr><td class="ps3">Firmware</td><td></td></tr>
|
||||||
<tr><td class="ps1">Version</td><td class="ps2" id="sw_ver"></td></tr>
|
<tr><td class="ps1">Version</td><td class="ps2" id="sw_ver"></td></tr>
|
||||||
|
|
@ -364,6 +366,37 @@ const char page_system_html[] PROGMEM = R"rawliteral(
|
||||||
</script>
|
</script>
|
||||||
)rawliteral";
|
)rawliteral";
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
|
const char page_temperature_html[] PROGMEM = R"rawliteral(
|
||||||
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
|
<body>
|
||||||
|
<center>
|
||||||
|
<table>
|
||||||
|
<tr><td class=pa3>External temperature sensor DHT22/DHT11</td><td></td></tr>
|
||||||
|
<tr><td class=pa1 align="right">Enable sensors</td><td><label class="switch"><input type="checkbox" name="extsens_en" id="extsetsid" onchange="changeValue(this.checked, 'set_bool?extsens_enable=', 'temp')"><span class="checkbox_slider round"></span></label></label> <span class=pa1 id="status_extsens"></span></td></tr>
|
||||||
|
<tr><td class="ps1">Sensor status: </td><td class="pa2" id="extsens_stat"></td></tr>
|
||||||
|
<tr><td style="height: 1px;"></td><td style="height: 1px;"></td></tr>
|
||||||
|
<tr>
|
||||||
|
<td class="pa1">Temperature Unit</td><td><label for="temp_unit"></label>
|
||||||
|
<select class="select" id="temp_unitid" name="temp_unit" onchange="changeValue(this.value, 'set_int?temp_unit=', 'temp')">
|
||||||
|
<option value="0">Celsius</option>
|
||||||
|
<option value="1">Fahrenheit</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td style="height: 1px;"></td><td style="height: 1px;"></td></tr>
|
||||||
|
<tr><td class="pa1">Temperature</td><td class="pa2" id="ext_temp"></td></tr>
|
||||||
|
<tr><td class="pa1">Humidity</td><td class="pa2" id="ext_hum"></td></tr>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
</body>
|
||||||
|
<script src="scripts.js"></script>
|
||||||
|
<script>
|
||||||
|
get_data("temp");
|
||||||
|
</script>
|
||||||
|
)rawliteral";
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char styles_css[] PROGMEM = R"rawliteral(
|
const char styles_css[] PROGMEM = R"rawliteral(
|
||||||
body {
|
body {
|
||||||
|
|
@ -889,7 +922,8 @@ function get_data(val) {
|
||||||
img.src = (obj.led == "true") ? 'light-on-icon.svg' : 'light-off-icon.svg';
|
img.src = (obj.led == "true") ? 'light-on-icon.svg' : 'light-off-icon.svg';
|
||||||
document.getElementById('light-icon').appendChild(img);
|
document.getElementById('light-icon').appendChild(img);
|
||||||
}
|
}
|
||||||
|
document.title = obj.mdns;
|
||||||
|
|
||||||
if (val == "config") {
|
if (val == "config") {
|
||||||
$("#fingerprint").text(obj.fingerprint);
|
$("#fingerprint").text(obj.fingerprint);
|
||||||
$("#refreshInterval").text(obj.refreshInterval);
|
$("#refreshInterval").text(obj.refreshInterval);
|
||||||
|
|
@ -981,6 +1015,7 @@ function get_data(val) {
|
||||||
$("#sd_total").text(obj.sd_total);
|
$("#sd_total").text(obj.sd_total);
|
||||||
$("#sd_free_p").text(obj.sd_free_p);
|
$("#sd_free_p").text(obj.sd_free_p);
|
||||||
$("#sd_used_p").text(obj.sd_used_p);
|
$("#sd_used_p").text(obj.sd_used_p);
|
||||||
|
$("#mcu_temp").text(obj.mcu_temp);
|
||||||
|
|
||||||
var sd_free_prog = document.getElementById("progress_bar_sd_free");
|
var sd_free_prog = document.getElementById("progress_bar_sd_free");
|
||||||
sd_free_prog.style.width = obj.sd_free_p + "%";
|
sd_free_prog.style.width = obj.sd_free_p + "%";
|
||||||
|
|
@ -993,6 +1028,14 @@ function get_data(val) {
|
||||||
document.getElementById('mdnsid').value = obj.mdns;
|
document.getElementById('mdnsid').value = obj.mdns;
|
||||||
document.getElementById('loglevelid').value = obj.log_level;
|
document.getElementById('loglevelid').value = obj.log_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (val == "temp") {
|
||||||
|
$("#extsens_stat").text(obj.extsens_stat);
|
||||||
|
document.getElementById('extsetsid').checked = obj.extsen_en;
|
||||||
|
document.getElementById('temp_unitid').value = obj.exttemp_unit;
|
||||||
|
$("#ext_temp").text(obj.ext_temp);
|
||||||
|
$("#ext_hum").text(obj.ext_hum);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
error: function(html) {
|
error: function(html) {
|
||||||
console.log("json Timeout or error");
|
console.log("json Timeout or error");
|
||||||
|
|
@ -1299,7 +1342,7 @@ function updateProgress() {
|
||||||
|
|
||||||
function checkUpdate() {
|
function checkUpdate() {
|
||||||
var xmlHttp = new XMLHttpRequest();
|
var xmlHttp = new XMLHttpRequest();
|
||||||
alert("Connecting to server... Please wait several second");
|
alert("Connecting to server... Please wait several seconds");
|
||||||
xmlHttp.open("GET", "/check_web_ota_update", false);
|
xmlHttp.open("GET", "/check_web_ota_update", false);
|
||||||
xmlHttp.send(null);
|
xmlHttp.send(null);
|
||||||
alert(xmlHttp.responseText);
|
alert(xmlHttp.responseText);
|
||||||
|
|
@ -1368,7 +1411,7 @@ function setupCollapsibleButtonsWiFi() {
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char license_html[] PROGMEM = R"rawliteral(
|
const char license_html[] PROGMEM = R"rawliteral(
|
||||||
<style>@import url("styles.css");</style>
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
<center><p>The software for device falls under the <a href="https://www.gnu.org/licenses/gpl-3.0.html" id="license-link">GPL-3.0 license terms</a>. To read the license terms please visit <a href="https://www.gnu.org/licenses/gpl-3.0.html" id="license-link-sec">this page</a>.</p></center>
|
<center><p>The software for device falls under the <a href="https://www.gnu.org/licenses/gpl-3.0.html" id="license-link">GPL-3.0 license terms</a>. To read the license terms please visit <a href="https://www.gnu.org/licenses/gpl-3.0.html" id="license-link-sec">this page</a>.</p></center>
|
||||||
<script src="scripts.js"></script>
|
<script src="scripts.js"></script>
|
||||||
|
|
@ -1380,7 +1423,7 @@ const char license_html[] PROGMEM = R"rawliteral(
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char gtac_html[] PROGMEM = R"rawliteral(
|
const char gtac_html[] PROGMEM = R"rawliteral(
|
||||||
<style>@import url("styles.css");</style>
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
<center><p>To read the General Terms and Conditions, please visit <a href="https://www.prusa3d.com/page/general-terms-and-conditions_231236/" id="gtac-link">this page</a>.</p></center>
|
<center><p>To read the General Terms and Conditions, please visit <a href="https://www.prusa3d.com/page/general-terms-and-conditions_231236/" id="gtac-link">this page</a>.</p></center>
|
||||||
<script src="scripts.js"></script>
|
<script src="scripts.js"></script>
|
||||||
|
|
@ -1391,7 +1434,7 @@ const char gtac_html[] PROGMEM = R"rawliteral(
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char privacypolicy_html[] PROGMEM = R"rawliteral(
|
const char privacypolicy_html[] PROGMEM = R"rawliteral(
|
||||||
<style>@import url("styles.css");</style>
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
<center><p>To read the Privacy Policy, please visit <a href="https://www.prusa3d.com/en/page/privacy-policy_231258/" id="privacy-link">this page</a>.</p></center>
|
<center><p>To read the Privacy Policy, please visit <a href="https://www.prusa3d.com/en/page/privacy-policy_231258/" id="privacy-link">this page</a>.</p></center>
|
||||||
<script src="scripts.js"></script>
|
<script src="scripts.js"></script>
|
||||||
|
|
@ -1402,7 +1445,7 @@ const char privacypolicy_html[] PROGMEM = R"rawliteral(
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char cookies_html[] PROGMEM = R"rawliteral(
|
const char cookies_html[] PROGMEM = R"rawliteral(
|
||||||
<style>@import url("styles.css");</style>
|
<style>@import url("styles.css?v=1.0.0");</style>
|
||||||
<script src="jquery-3.7.0.min.js"></script>
|
<script src="jquery-3.7.0.min.js"></script>
|
||||||
<center><p>To read the Cookie policy, please visit <a href="https://www.prusa3d.com/en/page/privacy-policy_231258/" id="cookies-link">this page</a>.</p></center>
|
<center><p>To read the Cookie policy, please visit <a href="https://www.prusa3d.com/en/page/privacy-policy_231258/" id="cookies-link">this page</a>.</p></center>
|
||||||
<script src="scripts.js"></script>
|
<script src="scripts.js"></script>
|
||||||
|
|
@ -1411,6 +1454,4 @@ const char cookies_html[] PROGMEM = R"rawliteral(
|
||||||
</script>
|
</script>
|
||||||
)rawliteral";
|
)rawliteral";
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _WEB_PAGE_ICONS_H_
|
#pragma once
|
||||||
#define _WEB_PAGE_ICONS_H_
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------ */
|
||||||
const char esp32_cam_logo_svg[] PROGMEM = R"rawliteral(
|
const char esp32_cam_logo_svg[] PROGMEM = R"rawliteral(
|
||||||
|
|
@ -89,7 +88,4 @@ const char favicon_svg[] PROGMEM = R"rawliteral(
|
||||||
</svg>
|
</svg>
|
||||||
)rawliteral";
|
)rawliteral";
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "server.h"
|
#include "WebServer.h"
|
||||||
#include "Certificate.h"
|
#include "Certificate.h"
|
||||||
|
|
||||||
AsyncWebServer server(WEB_SERVER_PORT);
|
AsyncWebServer server(WEB_SERVER_PORT);
|
||||||
|
|
@ -41,27 +41,36 @@ void Server_InitWebServer() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (SystemCamera.GetCameraCaptureSuccess() == false) {
|
if (SystemCamera.GetCameraCaptureSuccess() == false) {
|
||||||
request->send_P(404, "text/plain", "Photo not found!");
|
request->send(404, "text/plain", "Photo not found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SystemCamera.SetPhotoSending(true);
|
SystemCamera.SetPhotoSending(true);
|
||||||
|
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, "Photo size: " + String(SystemCamera.GetPhotoFb()->len) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, "Photo size: " + String(SystemCamera.GetPhotoFb()->len) + " bytes");
|
||||||
|
|
||||||
if (SystemCamera.GetPhotoExifData()->header != NULL) {
|
if (SystemCamera.GetPhotoExifData()->header != NULL) {
|
||||||
/* send photo with exif data */
|
/* send photo with exif data */
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("Send photo with EXIF data"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("Send photo with EXIF data"));
|
||||||
size_t total_len = SystemCamera.GetPhotoExifData()->len + SystemCamera.GetPhotoFb()->len - SystemCamera.GetPhotoExifData()->offset;
|
size_t total_len = SystemCamera.GetPhotoExifData()->len + SystemCamera.GetPhotoFb()->len - SystemCamera.GetPhotoExifData()->offset;
|
||||||
auto response = request->beginResponseStream("image/jpg");
|
auto response = request->beginChunkedResponse("image/jpg", [total_len](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
|
||||||
|
size_t len = 0;
|
||||||
|
if (index < SystemCamera.GetPhotoExifData()->len) {
|
||||||
|
len = min(maxLen, SystemCamera.GetPhotoExifData()->len - index);
|
||||||
|
memcpy(buffer, SystemCamera.GetPhotoExifData()->header + index, len);
|
||||||
|
} else {
|
||||||
|
size_t offset = index - SystemCamera.GetPhotoExifData()->len + SystemCamera.GetPhotoExifData()->offset;
|
||||||
|
len = min(maxLen, SystemCamera.GetPhotoFb()->len - offset);
|
||||||
|
memcpy(buffer, SystemCamera.GetPhotoFb()->buf + offset, len);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
});
|
||||||
response->addHeader("Content-Length", String(total_len));
|
response->addHeader("Content-Length", String(total_len));
|
||||||
response->write(SystemCamera.GetPhotoExifData()->header, SystemCamera.GetPhotoExifData()->len);
|
|
||||||
response->write(&SystemCamera.GetPhotoFb()->buf[SystemCamera.GetPhotoExifData()->offset], SystemCamera.GetPhotoFb()->len - SystemCamera.GetPhotoExifData()->offset);
|
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* send photo without exif data */
|
/* send photo without exif data */
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("Send photo without EXIF data"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("Send photo without EXIF data"));
|
||||||
request->send_P(200, "image/jpg", SystemCamera.GetPhotoFb()->buf, SystemCamera.GetPhotoFb()->len);
|
request->send(200, "image/jpg", SystemCamera.GetPhotoFb()->buf, SystemCamera.GetPhotoFb()->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemCamera.SetPhotoSending(false);
|
SystemCamera.SetPhotoSending(false);
|
||||||
|
|
@ -102,7 +111,7 @@ void Server_InitWebServer_JsonData() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: get json_input"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: get json_input"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, F("text/plain"), Server_GetJsonData().c_str());
|
request->send(200, F("text/plain"), Server_GetJsonData().c_str());
|
||||||
});
|
});
|
||||||
|
|
||||||
/* route for json with wifi networks */
|
/* route for json with wifi networks */
|
||||||
|
|
@ -110,7 +119,7 @@ void Server_InitWebServer_JsonData() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: get json_wifi"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: get json_wifi"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, F("text/plain"), SystemWifiMngt.GetAvailableWifiNetworks().c_str());
|
request->send(200, F("text/plain"), SystemWifiMngt.GetAvailableWifiNetworks().c_str());
|
||||||
});
|
});
|
||||||
|
|
||||||
/* route for san wi-fi networks */
|
/* route for san wi-fi networks */
|
||||||
|
|
@ -118,7 +127,7 @@ void Server_InitWebServer_JsonData() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: scan WI-FI networks"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: scan WI-FI networks"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, F("text/html"), MSG_SCANNING);
|
request->send(200, F("text/html"), MSG_SCANNING);
|
||||||
SystemWifiMngt.ScanWiFiNetwork();
|
SystemWifiMngt.ScanWiFiNetwork();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -150,7 +159,7 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get index.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get index.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", index_html);
|
Server_handleCacheRequest(request, "text/html", index_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -168,7 +177,7 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get scripts.js"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get scripts.js"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, "application/javascript", scripts_js);
|
request->send(200, "application/javascript", scripts_js);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -177,7 +186,7 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_config.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_config.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", page_config_html);
|
Server_handleCacheRequest(request, "text/html", page_config_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -186,7 +195,7 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_wifi.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_wifi.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", page_wifi_html);
|
Server_handleCacheRequest(request, "text/html", page_wifi_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -195,7 +204,7 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_auth.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_auth.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", page_auth_html);
|
Server_handleCacheRequest(request, "text/html", page_auth_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -204,16 +213,25 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_system.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_system.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", page_system_html);
|
Server_handleCacheRequest(request, "text/html", page_system_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* route for temperature web page */
|
||||||
|
server.on("/page_temperature.html", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get page_temperature.html"));
|
||||||
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Server_handleCacheRequest(request, "text/html", page_temperature_html);
|
||||||
|
});
|
||||||
|
|
||||||
/* route to license page */
|
/* route to license page */
|
||||||
server.on("/license.html", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/license.html", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get license.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get license.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", license_html);
|
Server_handleCacheRequest(request, "text/html", license_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -222,7 +240,7 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get gtac.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get gtac.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", gtac_html);
|
Server_handleCacheRequest(request, "text/html", gtac_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -231,7 +249,7 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get privacypolicy.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get privacypolicy.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", privacypolicy_html);
|
Server_handleCacheRequest(request, "text/html", privacypolicy_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -240,7 +258,7 @@ void Server_InitWebServer_WebPages() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get cookie.html"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get cookie.html"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "text/html", cookies_html);
|
Server_handleCacheRequest(request, "text/html", cookies_html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -252,10 +270,29 @@ void Server_InitWebServer_WebPages() {
|
||||||
|
|
||||||
if (true == SystemLog.GetCardDetectedStatus()) {
|
if (true == SystemLog.GetCardDetectedStatus()) {
|
||||||
request->send(SD_MMC, SystemLog.GetFilePath() + SystemLog.GetFileName(), "text/plain");
|
request->send(SD_MMC, SystemLog.GetFilePath() + SystemLog.GetFileName(), "text/plain");
|
||||||
|
//SystemLog.LogOpenFile();
|
||||||
} else {
|
} else {
|
||||||
request->send_P(404, "text/plain", "Micro SD card not found with FAT32 partition!");
|
request->send(404, "text/plain", "Micro SD card not found with FAT32 partition!");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* route to get temperature */
|
||||||
|
server.on("/get_temp", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get get_temp"));
|
||||||
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
request->send(200, "text/plain", String(ExternalTemperatureSensor.GetTemperature()));
|
||||||
|
});
|
||||||
|
|
||||||
|
/* route to get humidity */
|
||||||
|
server.on("/get_hum", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get get_hum"));
|
||||||
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
request->send(200, "text/plain", String(ExternalTemperatureSensor.GetHumidity()));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -269,7 +306,7 @@ void Server_InitWebServer_Icons() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get esp32_cam.svg"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get esp32_cam.svg"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "image/svg+xml", esp32_cam_logo_svg);
|
Server_handleCacheRequest(request, "image/svg+xml", esp32_cam_logo_svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -278,7 +315,7 @@ void Server_InitWebServer_Icons() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get github-icon.svg"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get github-icon.svg"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "image/svg+xml", github_icon_svg);
|
Server_handleCacheRequest(request, "image/svg+xml", github_icon_svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -296,7 +333,7 @@ void Server_InitWebServer_Icons() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get light-icon.svg"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: Get light-icon.svg"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server_handleCacheRequest(request, "image/svg+xml", light_icon_off_svg);
|
Server_handleCacheRequest(request, "image/svg+xml", light_icon_off_svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -403,8 +440,7 @@ void Server_InitWebServer_Actions() {
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
SystemCamera.CapturePhoto();
|
SystemCamera.CapturePhoto();
|
||||||
request->send_P(200, "text/plain", "Take Photo");
|
request->send(200, "text/plain", "Take Photo");
|
||||||
SystemCamera.CaptureReturnFrameBuffer();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* route for send photo to prusa backend */
|
/* route for send photo to prusa backend */
|
||||||
|
|
@ -413,7 +449,7 @@ void Server_InitWebServer_Actions() {
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
Connect.SetSendingIntervalExpired();
|
Connect.SetSendingIntervalExpired();
|
||||||
request->send_P(200, "text/plain", "Send Photo");
|
request->send(200, "text/plain", "Send Photo");
|
||||||
});
|
});
|
||||||
|
|
||||||
/* route for change LED status */
|
/* route for change LED status */
|
||||||
|
|
@ -425,7 +461,53 @@ void Server_InitWebServer_Actions() {
|
||||||
SystemCamera.SetFlashStatus(!SystemCamera.GetFlashStatus());
|
SystemCamera.SetFlashStatus(!SystemCamera.GetFlashStatus());
|
||||||
SystemCamera.SetCameraFlashEnable(false);
|
SystemCamera.SetCameraFlashEnable(false);
|
||||||
|
|
||||||
request->send_P(200, "text/plain", "Change LED status");
|
request->send(200, "text/plain", "Change LED status");
|
||||||
|
});
|
||||||
|
|
||||||
|
/* route for change LED status */
|
||||||
|
server.on("/light", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /light set LED status"));
|
||||||
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (request->hasArg("on")) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("Turning light ON"));
|
||||||
|
SystemCamera.SetFlashStatus(true);
|
||||||
|
SystemCamera.SetCameraFlashEnable(false);
|
||||||
|
request->send(200, "text/plain", "Light ON");
|
||||||
|
|
||||||
|
} else if (request->hasArg("off")) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("Turning light OFF"));
|
||||||
|
SystemCamera.SetFlashStatus(false);
|
||||||
|
SystemCamera.SetCameraFlashEnable(false);
|
||||||
|
request->send(200, "text/plain", "Light OFF");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
request->send(400, "text/plain", "Invalid request");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* route for change FLASH status */
|
||||||
|
server.on("/flash", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /flash set flash status"));
|
||||||
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (request->hasArg("on")) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("Turning flash ON"));
|
||||||
|
SystemCamera.SetCameraFlashEnable(true);
|
||||||
|
SystemCamera.SetFlashStatus(false);
|
||||||
|
request->send(200, "text/plain", "Flash ON");
|
||||||
|
|
||||||
|
} else if (request->hasArg("off")) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("Turning flash OFF"));
|
||||||
|
SystemCamera.SetCameraFlashEnable(false);
|
||||||
|
SystemCamera.SetFlashStatus(false);
|
||||||
|
request->send(200, "text/plain", "Flash OFF");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
request->send(400, "text/plain", "Invalid request");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* reboot MCU */
|
/* reboot MCU */
|
||||||
|
|
@ -433,12 +515,12 @@ void Server_InitWebServer_Actions() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /action_reboo reboot MCU!"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /action_reboo reboot MCU!"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, F("text/html"), MSG_REBOOT_MCU);
|
request->send(200, F("text/html"), MSG_REBOOT_MCU);
|
||||||
delay(100); /* wait for sending data */
|
delay(100); /* wait for sending data */
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* route for change LED status */
|
/* route for change LED status */
|
||||||
server.on("/action_sderase", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/action_sderase", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /action_sderase remove files from SD card"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /action_sderase remove files from SD card"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
|
|
@ -446,7 +528,7 @@ void Server_InitWebServer_Actions() {
|
||||||
|
|
||||||
StartRemoveSdCard = 1;
|
StartRemoveSdCard = 1;
|
||||||
|
|
||||||
request->send_P(200, F("text/plain"), "Starting remove files from SD card");
|
request->send(200, F("text/plain"), "Starting remove files from SD card");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -590,8 +672,16 @@ void Server_InitWebServer_Sets() {
|
||||||
response = true;
|
response = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set saturation */
|
||||||
|
if (request->hasParam("temp_unit")) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("Set temp_unit"));
|
||||||
|
ExternalTemperatureSensor.SetUnit((TemperatureSensorUnit_enum) request->getParam("temp_unit")->value().toInt());
|
||||||
|
response_msg = MSG_SAVE_OK;
|
||||||
|
response = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (true == response) {
|
if (true == response) {
|
||||||
request->send_P(200, F("text/html"), response_msg.c_str());
|
request->send(200, F("text/html"), response_msg.c_str());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -688,20 +778,38 @@ void Server_InitWebServer_Sets() {
|
||||||
response = true;
|
response = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set service AP */
|
||||||
if (request->hasParam("serviceap_enable")) {
|
if (request->hasParam("serviceap_enable")) {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("Set service AP enable"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("Set service AP enable"));
|
||||||
SystemWifiMngt.SetEnableServiceAp(Server_TransfeStringToBool(request->getParam("serviceap_enable")->value()));
|
SystemWifiMngt.SetEnableServiceAp(Server_TransfeStringToBool(request->getParam("serviceap_enable")->value()));
|
||||||
response = true;
|
response = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set timelaps enable */
|
||||||
if (request->hasParam("timelaps_enable")) {
|
if (request->hasParam("timelaps_enable")) {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("Set timelaps enable"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("Set timelaps enable"));
|
||||||
Connect.SetTimeLapsPhotoSaveStatus(Server_TransfeStringToBool(request->getParam("timelaps_enable")->value()));
|
#if (ENABLE_SD_CARD == true)
|
||||||
|
bool val = Server_TransfeStringToBool(request->getParam("timelaps_enable")->value());
|
||||||
|
if ((true == val) && (SystemLog.GetCardDetectedStatus() == true)) {
|
||||||
|
Connect.SetTimeLapsPhotoSaveStatus(val);
|
||||||
|
} else {
|
||||||
|
Connect.SetTimeLapsPhotoSaveStatus(false);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
Connect.SetTimeLapsPhotoSaveStatus(false);
|
||||||
|
#endif
|
||||||
|
response = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set external temperature sensor enable */
|
||||||
|
if (request->hasParam("extsens_enable")) {
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("Set enable ext temperature"));
|
||||||
|
ExternalTemperatureSensor.EnableSensor(Server_TransfeStringToBool(request->getParam("extsens_enable")->value()));
|
||||||
response = true;
|
response = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true == response) {
|
if (true == response) {
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_OK);
|
request->send(200, F("text/html"), MSG_SAVE_OK);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -710,7 +818,7 @@ void Server_InitWebServer_Sets() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /set_token"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /set_token"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_OK);
|
request->send(200, F("text/html"), MSG_SAVE_OK);
|
||||||
|
|
||||||
if (request->hasParam("token")) {
|
if (request->hasParam("token")) {
|
||||||
Connect.SetToken(request->getParam("token")->value());
|
Connect.SetToken(request->getParam("token")->value());
|
||||||
|
|
@ -722,7 +830,7 @@ void Server_InitWebServer_Sets() {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /set_hostname"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: /set_hostname"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_OK);
|
request->send(200, F("text/html"), MSG_SAVE_OK);
|
||||||
|
|
||||||
if (request->hasParam("hostname")) {
|
if (request->hasParam("hostname")) {
|
||||||
Connect.SetPrusaConnectHostname(request->getParam("hostname")->value());
|
Connect.SetPrusaConnectHostname(request->getParam("hostname")->value());
|
||||||
|
|
@ -748,20 +856,25 @@ void Server_InitWebServer_Sets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check min and max length WI-FI ssid and password */
|
/* check min and max length WI-FI ssid and password */
|
||||||
|
#if (WIFI_DISABLE_UNENCRYPTED_STA_PASS_CHECK == false)
|
||||||
if (((TmpPassword.length() > 0) && (TmpSsid.length() > 0)) && ((TmpPassword.length() < EEPROM_ADDR_WIFI_PASSWORD_LENGTH) && (TmpSsid.length() < EEPROM_ADDR_WIFI_SSID_LENGTH))) {
|
if (((TmpPassword.length() > 0) && (TmpSsid.length() > 0)) && ((TmpPassword.length() < EEPROM_ADDR_WIFI_PASSWORD_LENGTH) && (TmpSsid.length() < EEPROM_ADDR_WIFI_SSID_LENGTH))) {
|
||||||
|
#else
|
||||||
|
if ((TmpSsid.length() > 0) && (TmpSsid.length() < EEPROM_ADDR_WIFI_SSID_LENGTH)) {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* send OK response */
|
/* send OK response */
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_OK_WIFI);
|
request->send(200, F("text/html"), MSG_SAVE_OK_WIFI);
|
||||||
|
|
||||||
/* save ssid and password */
|
/* save ssid and password */
|
||||||
SystemWifiMngt.SetStaCredentials(TmpSsid,TmpPassword);
|
SystemWifiMngt.SetStaCredentials(TmpSsid, TmpPassword);
|
||||||
SystemWifiMngt.WiFiStaConnect();
|
SystemWifiMngt.WiFiStaConnect();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_NOTOK);
|
request->send(200, F("text/html"), MSG_SAVE_NOTOK);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* route for set WI-FI static IP address */
|
/* route for set WI-FI static IP address */
|
||||||
server.on("/wifi_net_cfg", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/wifi_net_cfg", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: set WI-FI static IP address"));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WEB server: set WI-FI static IP address"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
|
|
@ -793,18 +906,16 @@ void Server_InitWebServer_Sets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check min and max length network parameters */
|
/* check min and max length network parameters */
|
||||||
if (((tmpIp.length() > 0) && (tmpMask.length() > 0) && (tmpGw.length() > 0) && (tmpDns.length() > 0)) &&
|
if (((tmpIp.length() > 0) && (tmpMask.length() > 0) && (tmpGw.length() > 0) && (tmpDns.length() > 0)) && ((tmpIp.length() <= IPV4_ADDR_MAX_LENGTH) && (tmpMask.length() <= IPV4_ADDR_MAX_LENGTH) && (tmpGw.length() <= IPV4_ADDR_MAX_LENGTH) && (tmpDns.length() <= IPV4_ADDR_MAX_LENGTH))) {
|
||||||
((tmpIp.length() <= IPV4_ADDR_MAX_LENGTH) && (tmpMask.length() <= IPV4_ADDR_MAX_LENGTH) &&
|
|
||||||
(tmpGw.length() <= IPV4_ADDR_MAX_LENGTH) && (tmpDns.length() <= IPV4_ADDR_MAX_LENGTH))) {
|
|
||||||
|
|
||||||
/* save ssid and password */
|
/* save ssid and password */
|
||||||
SystemWifiMngt.SetNetworkConfig(tmpIp, tmpMask, tmpGw, tmpDns);
|
SystemWifiMngt.SetNetworkConfig(tmpIp, tmpMask, tmpGw, tmpDns);
|
||||||
|
|
||||||
/* send OK response */
|
/* send OK response */
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_OK_REBOOT);
|
request->send(200, F("text/html"), MSG_SAVE_OK_REBOOT);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_NOTOK);
|
request->send(200, F("text/html"), MSG_SAVE_NOTOK);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -855,12 +966,12 @@ void Server_InitWebServer_Sets() {
|
||||||
|
|
||||||
/* send OK response */
|
/* send OK response */
|
||||||
if (true == ret) {
|
if (true == ret) {
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_OK);
|
request->send(200, F("text/html"), MSG_SAVE_OK);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String msg = MSG_SAVE_NOTOK;
|
String msg = MSG_SAVE_NOTOK;
|
||||||
msg += " " + ret_msg;
|
msg += " " + ret_msg;
|
||||||
request->send_P(200, F("text/html"), msg.c_str());
|
request->send(200, F("text/html"), msg.c_str());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -869,7 +980,7 @@ void Server_InitWebServer_Sets() {
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("WEB server: /set_firmware_size"));
|
SystemLog.AddEvent(LogLevel_Info, F("WEB server: /set_firmware_size"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_OK);
|
request->send(200, F("text/html"), MSG_SAVE_OK);
|
||||||
|
|
||||||
/* check cfg for flash */
|
/* check cfg for flash */
|
||||||
if (request->hasParam("size")) {
|
if (request->hasParam("size")) {
|
||||||
|
|
@ -888,12 +999,12 @@ void Server_InitWebServer_Sets() {
|
||||||
if (request->hasParam("mdns")) {
|
if (request->hasParam("mdns")) {
|
||||||
String tmp = request->getParam("mdns")->value();
|
String tmp = request->getParam("mdns")->value();
|
||||||
if (tmp.length() < EEPROM_ADDR_MDNS_RECORD_LENGTH) {
|
if (tmp.length() < EEPROM_ADDR_MDNS_RECORD_LENGTH) {
|
||||||
request->send_P(200, F("text/html"), MSG_SAVE_OK_REBOOT);
|
request->send(200, F("text/html"), MSG_SAVE_OK_REBOOT);
|
||||||
SystemWifiMngt.SetMdns(tmp);
|
SystemWifiMngt.SetMdns(tmp);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String msg = "Error save mDNS. Maximum length: " + String(EEPROM_ADDR_MDNS_RECORD_LENGTH);
|
String msg = "Error save mDNS. Maximum length: " + String(EEPROM_ADDR_MDNS_RECORD_LENGTH);
|
||||||
request->send_P(200, F("text/html"), msg.c_str());
|
request->send(200, F("text/html"), msg.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -955,15 +1066,14 @@ void Server_InitWebServer_Update() {
|
||||||
SystemLog.AddEvent(LogLevel_Error, String(SYSTEM_MSG_UPDATE_FAIL));
|
SystemLog.AddEvent(LogLevel_Error, String(SYSTEM_MSG_UPDATE_FAIL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
/* route for start web OTA update from server */
|
/* route for start web OTA update from server */
|
||||||
server.on("/web_ota_update", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/web_ota_update", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("WEB server: /web_ota_update"));
|
SystemLog.AddEvent(LogLevel_Info, F("WEB server: /web_ota_update"));
|
||||||
if (Server_CheckBasicAuth(request) == false)
|
if (Server_CheckBasicAuth(request) == false)
|
||||||
return;
|
return;
|
||||||
request->send_P(200, F("text/html"), MSG_UPDATE_START);
|
request->send(200, F("text/html"), MSG_UPDATE_START);
|
||||||
FirmwareUpdate.Processing = true;
|
FirmwareUpdate.Processing = true;
|
||||||
|
|
||||||
/* check flag */
|
/* check flag */
|
||||||
|
|
@ -984,7 +1094,7 @@ void Server_InitWebServer_Update() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
System_CheckNewVersion();
|
System_CheckNewVersion();
|
||||||
request->send_P(200, F("text/html"), FirmwareUpdate.CheckNewVersionFwStatus.c_str());
|
request->send(200, F("text/html"), FirmwareUpdate.CheckNewVersionFwStatus.c_str());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1024,8 +1134,20 @@ void Server_resume() {
|
||||||
* @param const char* - content type
|
* @param const char* - content type
|
||||||
* @param const char* - data
|
* @param const char* - data
|
||||||
*/
|
*/
|
||||||
void Server_handleCacheRequest(AsyncWebServerRequest* request, const char *contentType, const char *data) {
|
void Server_handleCacheRequest(AsyncWebServerRequest* request, const char* contentType, const char* data) {
|
||||||
AsyncWebServerResponse *response = request->beginResponse_P(200, contentType, data);
|
/*
|
||||||
|
AsyncWebServerResponse* response = request->beginResponse(200, contentType, data);
|
||||||
|
response->addHeader("Cache-Control", "public, max-age=" + String(WEB_CACHE_INTERVAL));
|
||||||
|
request->send(response);
|
||||||
|
*/
|
||||||
|
|
||||||
|
AsyncWebServerResponse* response = request->beginChunkedResponse(contentType, [data](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
|
||||||
|
const char* dataStart = data + index; // current position in data
|
||||||
|
size_t dataLeft = strlen(data) - index; // how many bytes are left to send
|
||||||
|
size_t chunkSize = dataLeft < maxLen ? dataLeft : maxLen; // how many bytes we can send now
|
||||||
|
memcpy(buffer, dataStart, chunkSize); // copy chunk of data to buffer
|
||||||
|
return chunkSize; // return chunk size
|
||||||
|
});
|
||||||
response->addHeader("Cache-Control", "public, max-age=" + String(WEB_CACHE_INTERVAL));
|
response->addHeader("Cache-Control", "public, max-age=" + String(WEB_CACHE_INTERVAL));
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
@ -1115,9 +1237,15 @@ String Server_GetJsonData() {
|
||||||
doc_json["sd_total"] = SystemLog.GetCardSizeMB();
|
doc_json["sd_total"] = SystemLog.GetCardSizeMB();
|
||||||
doc_json["sd_free_p"] = SystemLog.GetFreeSpacePercent();
|
doc_json["sd_free_p"] = SystemLog.GetFreeSpacePercent();
|
||||||
doc_json["sd_used_p"] = SystemLog.GetUsedSpacePercent();
|
doc_json["sd_used_p"] = SystemLog.GetUsedSpacePercent();
|
||||||
|
doc_json["mcu_temp"] = String(McuTemperature.TemperatureCelsius) + " *C";
|
||||||
doc_json["sw_build"] = SW_BUILD;
|
doc_json["sw_build"] = SW_BUILD;
|
||||||
doc_json["sw_ver"] = SW_VERSION;
|
doc_json["sw_ver"] = SW_VERSION;
|
||||||
doc_json["sw_new_ver"] = FirmwareUpdate.NewVersionFw;
|
doc_json["sw_new_ver"] = FirmwareUpdate.NewVersionFw;
|
||||||
|
doc_json["extsens_stat"] = ExternalTemperatureSensor.GetSensorStatus();
|
||||||
|
doc_json["extsen_en"] = ExternalTemperatureSensor.GetUserEnableSensor();
|
||||||
|
doc_json["ext_temp"] = ExternalTemperatureSensor.GetTemperatureString();
|
||||||
|
doc_json["ext_hum"] = ExternalTemperatureSensor.GetHumidityString();
|
||||||
|
doc_json["exttemp_unit"] = ExternalTemperatureSensor.GetTemperatureUnit();
|
||||||
|
|
||||||
serializeJson(doc_json, string_json);
|
serializeJson(doc_json, string_json);
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, string_json);
|
SystemLog.AddEvent(LogLevel_Verbose, string_json);
|
||||||
|
|
@ -1144,8 +1272,8 @@ bool Server_CheckBasicAuth(AsyncWebServerRequest* request) {
|
||||||
@param AsyncWebServerRequest - request
|
@param AsyncWebServerRequest - request
|
||||||
@return void
|
@return void
|
||||||
*/
|
*/
|
||||||
void Server_streamJpg(AsyncWebServerRequest *request) {
|
void Server_streamJpg(AsyncWebServerRequest* request) {
|
||||||
AsyncJpegStreamResponse *response = new AsyncJpegStreamResponse(&SystemCamera, &SystemLog);
|
AsyncJpegStreamResponse* response = new AsyncJpegStreamResponse(&SystemCamera, &SystemLog);
|
||||||
if (!response) {
|
if (!response) {
|
||||||
request->send(501);
|
request->send(501);
|
||||||
return;
|
return;
|
||||||
|
|
@ -10,21 +10,16 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SERVER_H_
|
#pragma once
|
||||||
#define _SERVER_H_
|
|
||||||
|
|
||||||
#include <AsyncEventSource.h>
|
#include <Arduino.h>
|
||||||
#include <AsyncWebSocket.h>
|
#include <WiFi.h>
|
||||||
#include <AsyncWebSynchronization.h>
|
#include <AsyncTCP.h>
|
||||||
#include <ESPAsyncWebSrv.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <esp_task_wdt.h>
|
|
||||||
#include <StringArray.h>
|
|
||||||
#include <WiFiClientSecure.h>
|
|
||||||
#include <HTTPClient.h>
|
|
||||||
#include <EEPROM.h>
|
|
||||||
#include <Update.h>
|
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
#include "micro_sd.h"
|
||||||
|
#include "log.h"
|
||||||
#include "WebPage.h"
|
#include "WebPage.h"
|
||||||
#include "WebPage_Icons.h"
|
#include "WebPage_Icons.h"
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
|
|
@ -33,12 +28,10 @@
|
||||||
#include "cfg.h"
|
#include "cfg.h"
|
||||||
#include "jquery.h"
|
#include "jquery.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "log.h"
|
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "wifi_mngt.h"
|
#include "wifi_mngt.h"
|
||||||
#include "stream.h"
|
#include "WebStream.h"
|
||||||
|
#include "ExternalTemperatureSensor.h"
|
||||||
#include "exif.h"
|
|
||||||
|
|
||||||
extern AsyncWebServer server; ///< global variable for web server
|
extern AsyncWebServer server; ///< global variable for web server
|
||||||
|
|
||||||
|
|
@ -67,6 +60,4 @@ bool Server_TransfeStringToBool(String);
|
||||||
|
|
||||||
String Server_TranslateBoolToString(bool);
|
String Server_TranslateBoolToString(bool);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
#include "stream.h"
|
#include "WebStream.h"
|
||||||
|
|
||||||
#define PART_BOUNDARY "123456789000000000000987654321" ///< Must be unique for each stream
|
#define PART_BOUNDARY "123456789000000000000987654321" ///< Must be unique for each stream
|
||||||
static const char *STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; ///< content type for stream
|
static const char *STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; ///< content type for stream
|
||||||
|
|
@ -226,7 +226,7 @@ size_t AsyncJpegStreamResponse::_content(uint8_t *buffer, size_t maxLen, size_t
|
||||||
char buf[50] = { '\0' };
|
char buf[50] = { '\0' };
|
||||||
camera->StreamSetFrameSize(_frame.fb->len / 1024);
|
camera->StreamSetFrameSize(_frame.fb->len / 1024);
|
||||||
camera->StreamSetFrameFps(fps);
|
camera->StreamSetFrameFps(fps);
|
||||||
//sprintf(buf, "Size: %uKB, Time: %ums (%.1f fps)", _frame.fb->len / 1024, fp, fps);
|
////sprintf(buf, "Size: %uKB, Time: %ums (%.1f fps)", _frame.fb->len / 1024, fp, fps);
|
||||||
sprintf(buf, "Size: %uKB, FPS: %.1f", _frame.fb->len / 1024, fps);
|
sprintf(buf, "Size: %uKB, FPS: %.1f", _frame.fb->len / 1024, fps);
|
||||||
Serial.println(buf);
|
Serial.println(buf);
|
||||||
lastAsyncRequest = end;
|
lastAsyncRequest = end;
|
||||||
|
|
@ -11,17 +11,21 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _STREAM_H_
|
#pragma once
|
||||||
#define _STREAM_H_
|
|
||||||
|
|
||||||
#include "ESPAsyncWebSrv.h"
|
#include <Arduino.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include "WebServer.h"
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
#include "var.h"
|
#include "var.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
|
||||||
|
class Camera;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
camera_fb_t *fb; ///< pointer to frame buffer
|
camera_fb_t *fb; ///< pointer to frame buffer
|
||||||
size_t index; ///< index of frame
|
size_t index; ///< index of frame
|
||||||
|
|
@ -71,5 +75,4 @@ public:
|
||||||
size_t _content(uint8_t *, size_t , size_t );
|
size_t _content(uint8_t *, size_t , size_t );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -6,6 +6,9 @@
|
||||||
@author Miroslav Pivovarsky
|
@author Miroslav Pivovarsky
|
||||||
Contact: miroslav.pivovarsky@gmail.com
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
https://github.com/espressif/esp32-camera
|
||||||
|
|
||||||
|
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
|
@ -19,7 +22,7 @@ Camera SystemCamera(&SystemConfig, &SystemLog, FLASH_GPIO_NUM);
|
||||||
@param uint8_t - flash pin
|
@param uint8_t - flash pin
|
||||||
@return none
|
@return none
|
||||||
*/
|
*/
|
||||||
Camera::Camera(Configuration* i_conf, Logs* i_log, uint8_t i_FlashPin) {
|
Camera::Camera(Configuration* i_conf, Logs* i_log, int8_t i_FlashPin) {
|
||||||
config = i_conf;
|
config = i_conf;
|
||||||
log = i_log;
|
log = i_log;
|
||||||
|
|
||||||
|
|
@ -27,6 +30,20 @@ Camera::Camera(Configuration* i_conf, Logs* i_log, uint8_t i_FlashPin) {
|
||||||
StreamOnOff = false;
|
StreamOnOff = false;
|
||||||
frameBufferSemaphore = xSemaphoreCreateMutex();
|
frameBufferSemaphore = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
|
/* Allocate memory for the frame buffer */
|
||||||
|
FrameBufferDuplicate = (camera_fb_t*)heap_caps_malloc(sizeof(camera_fb_t), MALLOC_CAP_SPIRAM);
|
||||||
|
if (FrameBufferDuplicate != NULL) {
|
||||||
|
memset(FrameBufferDuplicate, 0, sizeof(camera_fb_t));
|
||||||
|
FrameBufferDuplicate->buf = NULL;
|
||||||
|
}
|
||||||
|
/* Allocate memory for the frame buffer */
|
||||||
|
FrameBufferExif = (camera_fb_t*)heap_caps_malloc(sizeof(camera_fb_t), MALLOC_CAP_SPIRAM);
|
||||||
|
if (FrameBufferExif != NULL) {
|
||||||
|
memset(FrameBufferExif, 0, sizeof(camera_fb_t));
|
||||||
|
FrameBufferExif->buf = NULL;
|
||||||
|
}
|
||||||
|
StreamSendingPhoto = false;
|
||||||
|
|
||||||
PhotoExifData.header = NULL;
|
PhotoExifData.header = NULL;
|
||||||
PhotoExifData.len = 0;
|
PhotoExifData.len = 0;
|
||||||
PhotoExifData.offset = 0;
|
PhotoExifData.offset = 0;
|
||||||
|
|
@ -42,13 +59,21 @@ Camera::Camera(Configuration* i_conf, Logs* i_log, uint8_t i_FlashPin) {
|
||||||
void Camera::Init() {
|
void Camera::Init() {
|
||||||
log->AddEvent(LogLevel_Info, F("Init camera lib"));
|
log->AddEvent(LogLevel_Info, F("Init camera lib"));
|
||||||
|
|
||||||
|
#if (true == ENABLE_CAMERA_FLASH)
|
||||||
log->AddEvent(LogLevel_Info, F("Init GPIO"));
|
log->AddEvent(LogLevel_Info, F("Init GPIO"));
|
||||||
ledcSetup(FLASH_PWM_CHANNEL, FLASH_PWM_FREQ, FLASH_PWM_RESOLUTION);
|
#if (true == CAMERA_FLASH_PWM_CTRL)
|
||||||
ledcAttachPin(FLASH_GPIO_NUM, FLASH_PWM_CHANNEL);
|
ledcAttach(FLASH_GPIO_NUM, FLASH_PWM_FREQ, FLASH_PWM_RESOLUTION);
|
||||||
ledcWrite(FLASH_PWM_CHANNEL, FLASH_OFF_STATUS);
|
|
||||||
|
#elif (true == CAMERA_FLASH_DIGITAL_CTRL)
|
||||||
|
pinMode(FLASH_GPIO_NUM, OUTPUT);
|
||||||
|
digitalWrite(FLASH_GPIO_NUM, LOW);
|
||||||
|
#endif
|
||||||
|
SetFlashStatus(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
InitCameraModule();
|
InitCameraModule();
|
||||||
ApplyCameraCfg();
|
ApplyCameraCfg();
|
||||||
|
GetCameraModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,7 +84,9 @@ void Camera::Init() {
|
||||||
void Camera::InitCameraModule() {
|
void Camera::InitCameraModule() {
|
||||||
log->AddEvent(LogLevel_Info, F("Init camera module"));
|
log->AddEvent(LogLevel_Info, F("Init camera module"));
|
||||||
/* Turn-off the 'brownout detector' */
|
/* Turn-off the 'brownout detector' */
|
||||||
|
#if (true == ENABLE_BROWN_OUT_DETECTION)
|
||||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
|
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
|
||||||
|
#endif
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
|
|
||||||
CameraConfig.ledc_channel = LEDC_CHANNEL_0;
|
CameraConfig.ledc_channel = LEDC_CHANNEL_0;
|
||||||
|
|
@ -80,7 +107,7 @@ void Camera::InitCameraModule() {
|
||||||
CameraConfig.pin_sccb_scl = SIOC_GPIO_NUM;
|
CameraConfig.pin_sccb_scl = SIOC_GPIO_NUM;
|
||||||
CameraConfig.pin_pwdn = PWDN_GPIO_NUM;
|
CameraConfig.pin_pwdn = PWDN_GPIO_NUM;
|
||||||
CameraConfig.pin_reset = RESET_GPIO_NUM;
|
CameraConfig.pin_reset = RESET_GPIO_NUM;
|
||||||
CameraConfig.xclk_freq_hz = 16500000; // or 3000000; 16500000; 20000000
|
CameraConfig.xclk_freq_hz = 15000000; // or 3000000; 16500000; 20000000
|
||||||
CameraConfig.pixel_format = PIXFORMAT_JPEG; /* YUV422,GRAYSCALE,RGB565,JPEG */
|
CameraConfig.pixel_format = PIXFORMAT_JPEG; /* YUV422,GRAYSCALE,RGB565,JPEG */
|
||||||
|
|
||||||
/* OV2640
|
/* OV2640
|
||||||
|
|
@ -91,13 +118,21 @@ void Camera::InitCameraModule() {
|
||||||
FRAMESIZE_XGA (1024 x 768)
|
FRAMESIZE_XGA (1024 x 768)
|
||||||
FRAMESIZE_SXGA (1280 x 1024)
|
FRAMESIZE_SXGA (1280 x 1024)
|
||||||
FRAMESIZE_UXGA (1600 x 1200)
|
FRAMESIZE_UXGA (1600 x 1200)
|
||||||
|
|
||||||
|
CAMERA_GRAB_WHEN_EMPTY - Fills buffers when they are empty. Less resources but first 'fb_count' frames might be old
|
||||||
|
CAMERA_GRAB_LATEST - Except when 1 frame buffer is used, queue will always contain the last 'fb_count' frames
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CameraConfig.frame_size = TFrameSize; /* FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA */
|
CameraConfig.frame_size = TFrameSize; /* FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA */
|
||||||
CameraConfig.jpeg_quality = PhotoQuality; /* 10-63 lower number means higher quality */
|
CameraConfig.jpeg_quality = PhotoQuality; /* 10-63 lower number means higher quality */
|
||||||
CameraConfig.fb_count = 1; /* picture frame buffer alocation */
|
CameraConfig.fb_count = 1; /* picture frame buffer alocation */
|
||||||
CameraConfig.grab_mode = CAMERA_GRAB_LATEST; /* CAMERA_GRAB_WHEN_EMPTY or CAMERA_GRAB_LATEST */
|
CameraConfig.grab_mode = CAMERA_GRAB_LATEST; /* CAMERA_GRAB_WHEN_EMPTY or CAMERA_GRAB_LATEST */
|
||||||
|
#if (true == ENABLE_PSRAM)
|
||||||
|
CameraConfig.fb_location = CAMERA_FB_IN_PSRAM; /* CAMERA_FB_IN_PSRAM or CAMERA_FB_IN_DRAM */
|
||||||
|
#else
|
||||||
|
CameraConfig.fb_location = CAMERA_FB_IN_DRAM; /* CAMERA_FB_IN_PSRAM or CAMERA_FB_IN_DRAM */
|
||||||
|
#endif
|
||||||
|
|
||||||
if (CameraConfig.fb_location == CAMERA_FB_IN_DRAM) {
|
if (CameraConfig.fb_location == CAMERA_FB_IN_DRAM) {
|
||||||
log->AddEvent(LogLevel_Verbose, F("Camera frame buffer location: DRAM"));
|
log->AddEvent(LogLevel_Verbose, F("Camera frame buffer location: DRAM"));
|
||||||
} else if (CameraConfig.fb_location == CAMERA_FB_IN_PSRAM) {
|
} else if (CameraConfig.fb_location == CAMERA_FB_IN_PSRAM) {
|
||||||
|
|
@ -108,12 +143,11 @@ void Camera::InitCameraModule() {
|
||||||
|
|
||||||
/* Camera init */
|
/* Camera init */
|
||||||
err = esp_camera_init(&CameraConfig);
|
err = esp_camera_init(&CameraConfig);
|
||||||
|
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
log->AddEvent(LogLevel_Warning, F("Camera init failed. Error: "), String(err, HEX));
|
log->AddEvent(LogLevel_Warning, F("Camera init failed. Error: "), String(err, HEX));
|
||||||
log->AddEvent(LogLevel_Warning, F("Reset ESP32-cam!"));
|
log->AddEvent(LogLevel_Warning, F("Reset ESP32-cam!"));
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -187,6 +221,11 @@ framesize_t Camera::TransformFrameSizeDataType(uint8_t i_data) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Function set photo sending status
|
||||||
|
@param bool i_data - true = on, false = off
|
||||||
|
@return none
|
||||||
|
*/
|
||||||
void Camera::SetPhotoSending(bool i_data) {
|
void Camera::SetPhotoSending(bool i_data) {
|
||||||
PhotoSending = i_data;
|
PhotoSending = i_data;
|
||||||
}
|
}
|
||||||
|
|
@ -197,11 +236,33 @@ void Camera::SetPhotoSending(bool i_data) {
|
||||||
@return none
|
@return none
|
||||||
*/
|
*/
|
||||||
void Camera::SetFlashStatus(bool i_data) {
|
void Camera::SetFlashStatus(bool i_data) {
|
||||||
|
#if (true == ENABLE_CAMERA_FLASH)
|
||||||
|
/* PWM control of the FLASH */
|
||||||
|
#if (true == CAMERA_FLASH_PWM_CTRL)
|
||||||
if (true == i_data) {
|
if (true == i_data) {
|
||||||
ledcWrite(FLASH_PWM_CHANNEL, FLASH_ON_STATUS);
|
ledcWrite(FLASH_GPIO_NUM, FLASH_ON_STATUS);
|
||||||
} else if (false == i_data) {
|
} else if (false == i_data) {
|
||||||
ledcWrite(FLASH_PWM_CHANNEL, FLASH_OFF_STATUS);
|
ledcWrite(FLASH_GPIO_NUM, FLASH_OFF_STATUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Digital control of the FLASH */
|
||||||
|
#elif (true == CAMERA_FLASH_DIGITAL_CTRL)
|
||||||
|
if (true == i_data) {
|
||||||
|
digitalWrite(FLASH_GPIO_NUM, HIGH);
|
||||||
|
} else if (false == i_data) {
|
||||||
|
digitalWrite(FLASH_GPIO_NUM, LOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* rgbLedWrite control of the FLASH */
|
||||||
|
#if (true == CAMERA_FLASH_NEOPIXEL)
|
||||||
|
if (true == i_data) {
|
||||||
|
rgbLedWrite(FLASH_NEOPIXEL_LED_PIN, RGB_BRIGHTNESS, RGB_BRIGHTNESS, RGB_BRIGHTNESS);
|
||||||
|
} else if (false == i_data) {
|
||||||
|
rgbLedWrite(FLASH_NEOPIXEL_LED_PIN, 0, 0, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -210,12 +271,22 @@ void Camera::SetFlashStatus(bool i_data) {
|
||||||
@return bool - true = on, false = off
|
@return bool - true = on, false = off
|
||||||
*/
|
*/
|
||||||
bool Camera::GetFlashStatus() {
|
bool Camera::GetFlashStatus() {
|
||||||
if (ledcRead(FLASH_PWM_CHANNEL) == FLASH_OFF_STATUS) {
|
#if (true == ENABLE_CAMERA_FLASH)
|
||||||
|
#if (true == CAMERA_FLASH_PWM_CTRL)
|
||||||
|
if (ledcRead(FLASH_GPIO_NUM) == FLASH_OFF_STATUS) {
|
||||||
return false;
|
return false;
|
||||||
} else if (ledcRead(FLASH_PWM_CHANNEL) == FLASH_ON_STATUS) {
|
} else if (ledcRead(FLASH_GPIO_NUM) == FLASH_ON_STATUS) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif (true == CAMERA_FLASH_DIGITAL_CTRL)
|
||||||
|
if (digitalRead(FLASH_GPIO_NUM) == LOW) {
|
||||||
|
return false;
|
||||||
|
} else if (digitalRead(FLASH_GPIO_NUM) == HIGH) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,7 +299,7 @@ void Camera::ApplyCameraCfg() {
|
||||||
log->AddEvent(LogLevel_Info, F("Set camera CFG"));
|
log->AddEvent(LogLevel_Info, F("Set camera CFG"));
|
||||||
|
|
||||||
/* sensor configuration */
|
/* sensor configuration */
|
||||||
sensor_t* sensor = esp_camera_sensor_get();
|
sensor = esp_camera_sensor_get();
|
||||||
sensor->set_brightness(sensor, brightness); // -2 to 2
|
sensor->set_brightness(sensor, brightness); // -2 to 2
|
||||||
sensor->set_contrast(sensor, contrast); // -2 to 2
|
sensor->set_contrast(sensor, contrast); // -2 to 2
|
||||||
sensor->set_saturation(sensor, saturation); // -2 to 2
|
sensor->set_saturation(sensor, saturation); // -2 to 2
|
||||||
|
|
@ -268,6 +339,34 @@ void Camera::ReinitCameraModule() {
|
||||||
ApplyCameraCfg();
|
ApplyCameraCfg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Function for get camera model and type
|
||||||
|
@param void
|
||||||
|
@return none
|
||||||
|
*/
|
||||||
|
void Camera::GetCameraModel() {
|
||||||
|
log->AddEvent(LogLevel_Info, F("Get camera model and type"));
|
||||||
|
if (sensor == NULL) {
|
||||||
|
log->AddEvent(LogLevel_Error, F("Camera sensor is NULL"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
camera_sensor_info_t *info = esp_camera_sensor_get_info(&sensor->id);
|
||||||
|
if (info == NULL) {
|
||||||
|
log->AddEvent(LogLevel_Error, F("Camera sensor info is NULL"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraType = (camera_pid_t) sensor->id.PID;
|
||||||
|
CameraName = info->name;
|
||||||
|
log->AddEvent(LogLevel_Info, F("Camera type: "), String(CameraType));
|
||||||
|
log->AddEvent(LogLevel_Info, F("Camera name: "), String(CameraName));
|
||||||
|
log->AddEvent(LogLevel_Info, F("Camera model: "), String(info->model));
|
||||||
|
log->AddEvent(LogLevel_Info, F("Camera PID: "), String(info->pid));
|
||||||
|
log->AddEvent(LogLevel_Info, F("Camera MAX framesize: "), String(info->max_size));
|
||||||
|
log->AddEvent(LogLevel_Info, F("Camera support jpeg: "), String(info->support_jpeg));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Capture Photo and Save it to string array
|
@brief Capture Photo and Save it to string array
|
||||||
@param none
|
@param none
|
||||||
|
|
@ -275,10 +374,13 @@ void Camera::ReinitCameraModule() {
|
||||||
*/
|
*/
|
||||||
void Camera::CapturePhoto() {
|
void Camera::CapturePhoto() {
|
||||||
|
|
||||||
|
/* Check if photo is already sending */
|
||||||
if (true == PhotoSending) {
|
if (true == PhotoSending) {
|
||||||
|
log->AddEvent(LogLevel_Info, F("Sending photo"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if stream is on */
|
||||||
if (false == StreamOnOff) {
|
if (false == StreamOnOff) {
|
||||||
if (!xSemaphoreTake(frameBufferSemaphore, portMAX_DELAY)) {
|
if (!xSemaphoreTake(frameBufferSemaphore, portMAX_DELAY)) {
|
||||||
log->AddEvent(LogLevel_Error, F("Failed to take frame buffer semaphore"));
|
log->AddEvent(LogLevel_Error, F("Failed to take frame buffer semaphore"));
|
||||||
|
|
@ -288,14 +390,19 @@ void Camera::CapturePhoto() {
|
||||||
CameraCaptureSuccess = false;
|
CameraCaptureSuccess = false;
|
||||||
/* check flash, and enable FLASH LED */
|
/* check flash, and enable FLASH LED */
|
||||||
if (true == CameraFlashEnable) {
|
if (true == CameraFlashEnable) {
|
||||||
ledcWrite(FLASH_PWM_CHANNEL, FLASH_ON_STATUS);
|
SetFlashStatus(true);
|
||||||
delay(CameraFlashTime);
|
delay(CameraFlashTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FrameBuffer) {
|
||||||
|
esp_camera_fb_return(FrameBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
/* Capturing a training photo. Without this sequence, the camera will not obtain the current photo but photo from the previous cycle. */
|
/* Capturing a training photo. Without this sequence, the camera will not obtain the current photo but photo from the previous cycle. */
|
||||||
FrameBuffer = esp_camera_fb_get();
|
FrameBuffer = esp_camera_fb_get();
|
||||||
if (FrameBuffer) {
|
if (FrameBuffer) {
|
||||||
esp_camera_fb_return(FrameBuffer);
|
esp_camera_fb_return(FrameBuffer);
|
||||||
|
log->AddEvent(LogLevel_Verbose, F("Camera capture training photo"));
|
||||||
} else {
|
} else {
|
||||||
esp_camera_fb_return(FrameBuffer);
|
esp_camera_fb_return(FrameBuffer);
|
||||||
log->AddEvent(LogLevel_Error, F("Camera capture failed training photo"));
|
log->AddEvent(LogLevel_Error, F("Camera capture failed training photo"));
|
||||||
|
|
@ -308,7 +415,6 @@ void Camera::CapturePhoto() {
|
||||||
do {
|
do {
|
||||||
log->AddEvent(LogLevel_Info, F("Taking photo..."));
|
log->AddEvent(LogLevel_Info, F("Taking photo..."));
|
||||||
|
|
||||||
delay(5); // delay for camera stabilization. test it
|
|
||||||
FrameBuffer = esp_camera_fb_get();
|
FrameBuffer = esp_camera_fb_get();
|
||||||
if (!FrameBuffer) {
|
if (!FrameBuffer) {
|
||||||
CameraCaptureFailedCounter++;
|
CameraCaptureFailedCounter++;
|
||||||
|
|
@ -352,10 +458,16 @@ void Camera::CapturePhoto() {
|
||||||
|
|
||||||
/* Disable flash */
|
/* Disable flash */
|
||||||
if (true == CameraFlashEnable) {
|
if (true == CameraFlashEnable) {
|
||||||
delay(CameraFlashTime);
|
SetFlashStatus(false);
|
||||||
ledcWrite(FLASH_PWM_CHANNEL, FLASH_OFF_STATUS);
|
|
||||||
}
|
}
|
||||||
xSemaphoreGive(frameBufferSemaphore);
|
xSemaphoreGive(frameBufferSemaphore);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Stream is on, set flag for sending photo */
|
||||||
|
if (xSemaphoreTake(frameBufferSemaphore, portMAX_DELAY)) {
|
||||||
|
StreamSendingPhoto = true;
|
||||||
|
xSemaphoreGive(frameBufferSemaphore);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reinit camera module if photo capture failed */
|
/* Reinit camera module if photo capture failed */
|
||||||
|
|
@ -384,7 +496,112 @@ void Camera::CaptureStream(camera_fb_t* i_buf) {
|
||||||
|
|
||||||
/* check if photo is correctly saved */
|
/* check if photo is correctly saved */
|
||||||
} while (!(FrameBuffer->len > 100));
|
} while (!(FrameBuffer->len > 100));
|
||||||
|
|
||||||
|
/* check if the photo is rotated */
|
||||||
|
bool ExifStatus = false;
|
||||||
|
|
||||||
|
#if (true == CAMERA_EXIF_ROTATION_STREAM)
|
||||||
|
if (1 != imageExifRotation) { /* 1 = image rotation 0 degree */
|
||||||
|
/* generate exif header */
|
||||||
|
update_exif_from_cfg(imageExifRotation);
|
||||||
|
get_exif_header(FrameBuffer, &PhotoExifData.header, &PhotoExifData.len);
|
||||||
|
PhotoExifData.offset = get_jpeg_data_offset(FrameBuffer);
|
||||||
|
if (PhotoExifData.header != NULL) {
|
||||||
|
/* memory allocation release */
|
||||||
|
if (FrameBufferExif != NULL) {
|
||||||
|
if (FrameBufferExif->buf != NULL) {
|
||||||
|
free(FrameBufferExif->buf);
|
||||||
|
FrameBufferExif->buf = NULL; /* Set to NULL after freeing */
|
||||||
|
}
|
||||||
|
|
||||||
|
free(FrameBufferExif);
|
||||||
|
FrameBufferExif = NULL; /* Set to NULL after freeing */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for the duplicate frame structure */
|
||||||
|
FrameBufferExif = (camera_fb_t*)heap_caps_malloc(sizeof(camera_fb_t), MALLOC_CAP_SPIRAM);
|
||||||
|
|
||||||
|
/* Calculate the total size of the buffer */
|
||||||
|
size_t totalSize = PhotoExifData.len + FrameBuffer->len - PhotoExifData.offset;
|
||||||
|
|
||||||
|
/* Allocate memory for the image data */
|
||||||
|
FrameBufferExif->buf = (uint8_t*)heap_caps_malloc(totalSize, MALLOC_CAP_SPIRAM);
|
||||||
|
if (FrameBufferExif->buf == NULL) {
|
||||||
|
log->AddEvent(LogLevel_Error, F("Failed to allocate memory for EXIF buffer"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy the EXIF data to the buffer */
|
||||||
|
memcpy(FrameBufferExif->buf, PhotoExifData.header, PhotoExifData.len);
|
||||||
|
|
||||||
|
/* copy the image data to the buffer */
|
||||||
|
memcpy(FrameBufferExif->buf + PhotoExifData.len, FrameBuffer->buf + PhotoExifData.offset, FrameBuffer->len - PhotoExifData.offset);
|
||||||
|
|
||||||
|
/* Set the length of the buffer */
|
||||||
|
FrameBufferExif->len = totalSize;
|
||||||
|
|
||||||
|
*i_buf = *FrameBufferExif;
|
||||||
|
ExifStatus = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* copy the frame buffer to the buffer */
|
||||||
|
*i_buf = *FrameBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* copy the frame buffer to the buffer */
|
||||||
|
*i_buf = *FrameBuffer;
|
||||||
|
}
|
||||||
|
#else
|
||||||
*i_buf = *FrameBuffer;
|
*i_buf = *FrameBuffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* copy the frame buffer to the duplicate frame buffer. For sending photo to Prusa Connect */
|
||||||
|
if (false == StreamSendingPhoto) {
|
||||||
|
/* memory allocation release */
|
||||||
|
if (FrameBufferDuplicate != NULL) {
|
||||||
|
if (FrameBufferDuplicate->buf != NULL) {
|
||||||
|
free(FrameBufferDuplicate->buf);
|
||||||
|
FrameBufferDuplicate->buf = NULL; /* Set to NULL after freeing */
|
||||||
|
}
|
||||||
|
|
||||||
|
free(FrameBufferDuplicate);
|
||||||
|
FrameBufferDuplicate = NULL; /* Set to NULL after freeing */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for the duplicate frame structure */
|
||||||
|
FrameBufferDuplicate = (camera_fb_t*)heap_caps_malloc(sizeof(camera_fb_t), MALLOC_CAP_SPIRAM);
|
||||||
|
|
||||||
|
/* Copy the metadata */
|
||||||
|
if (true == ExifStatus) {
|
||||||
|
memcpy(FrameBufferDuplicate, FrameBufferExif, sizeof(camera_fb_t));
|
||||||
|
} else {
|
||||||
|
memcpy(FrameBufferDuplicate, FrameBuffer, sizeof(camera_fb_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for the image data */
|
||||||
|
if (true == ExifStatus) {
|
||||||
|
FrameBufferDuplicate->buf = (uint8_t*)heap_caps_malloc(FrameBufferExif->len, MALLOC_CAP_SPIRAM);
|
||||||
|
} else {
|
||||||
|
FrameBufferDuplicate->buf = (uint8_t*)heap_caps_malloc(FrameBuffer->len, MALLOC_CAP_SPIRAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if memory allocation was successful */
|
||||||
|
if (!FrameBufferDuplicate->buf) {
|
||||||
|
/* Handle error */
|
||||||
|
free(FrameBufferDuplicate);
|
||||||
|
Serial.println("Failed to allocate memory for the duplicate frame buffer");
|
||||||
|
} else {
|
||||||
|
/* Copy the image data */
|
||||||
|
if (true == ExifStatus) {
|
||||||
|
memcpy(FrameBufferDuplicate->buf, FrameBufferExif->buf, FrameBufferExif->len);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
memcpy(FrameBufferDuplicate->buf, FrameBuffer->buf, FrameBuffer->len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xSemaphoreGive(frameBufferSemaphore);
|
xSemaphoreGive(frameBufferSemaphore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -405,6 +622,9 @@ void Camera::CaptureReturnFrameBuffer() {
|
||||||
*/
|
*/
|
||||||
void Camera::SetStreamStatus(bool i_status) {
|
void Camera::SetStreamStatus(bool i_status) {
|
||||||
StreamOnOff = i_status;
|
StreamOnOff = i_status;
|
||||||
|
if (FrameBuffer) {
|
||||||
|
esp_camera_fb_return(FrameBuffer);
|
||||||
|
}
|
||||||
log->AddEvent(LogLevel_Info, F("Camera video stream: "), String(StreamOnOff));
|
log->AddEvent(LogLevel_Info, F("Camera video stream: "), String(StreamOnOff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -467,6 +687,15 @@ void Camera::StreamClearFrameData() {
|
||||||
StreamAverageSize = 0;
|
StreamAverageSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Set Sending Photo for Stream
|
||||||
|
@param bool - sending photo
|
||||||
|
@return none
|
||||||
|
*/
|
||||||
|
void Camera::StreamSetSendingPhoto(bool i_data) {
|
||||||
|
StreamSendingPhoto = i_data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Get Photo
|
@brief Get Photo
|
||||||
@param none
|
@param none
|
||||||
|
|
@ -489,6 +718,15 @@ camera_fb_t* Camera::GetPhotoFb() {
|
||||||
return FrameBuffer;
|
return FrameBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Get Photo Frame Buffer Duplicate
|
||||||
|
@param none
|
||||||
|
@return camera_fb_t* - photo frame buffer duplicate
|
||||||
|
*/
|
||||||
|
camera_fb_t* Camera::GetPhotoFbDuplicate() {
|
||||||
|
return FrameBufferDuplicate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Get Photo Exif Data
|
@brief Get Photo Exif Data
|
||||||
@param none
|
@param none
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,23 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAMERA_H_
|
#pragma once
|
||||||
#define _CAMERA_H_
|
|
||||||
|
|
||||||
#include "esp_camera.h"
|
#include "esp_camera.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#include "img_converters.h"
|
#include "img_converters.h"
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
|
||||||
|
#include "micro_sd.h"
|
||||||
|
#include "log.h"
|
||||||
#include "cfg.h"
|
#include "cfg.h"
|
||||||
|
|
||||||
#include "exif.h"
|
#include "exif.h"
|
||||||
#include "FS.h"
|
#include "module_templates.h"
|
||||||
#include "SD_MMC.h"
|
|
||||||
|
|
||||||
#include "Camera_cfg.h"
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
#include "var.h"
|
#include "var.h"
|
||||||
#include "log.h"
|
|
||||||
|
class Configuration;
|
||||||
|
|
||||||
struct PhotoExifData_t {
|
struct PhotoExifData_t {
|
||||||
const uint8_t *header;
|
const uint8_t *header;
|
||||||
|
|
@ -59,7 +57,7 @@ private:
|
||||||
bool exposure_ctrl; ///< exposure control
|
bool exposure_ctrl; ///< exposure control
|
||||||
bool CameraFlashEnable; ///< enable/disable camera flash function
|
bool CameraFlashEnable; ///< enable/disable camera flash function
|
||||||
uint16_t CameraFlashTime; ///< camera fash duration time
|
uint16_t CameraFlashTime; ///< camera fash duration time
|
||||||
uint8_t CameraFlashPin; ///< GPIO pin for LED
|
int8_t CameraFlashPin; ///< GPIO pin for LED
|
||||||
framesize_t TFrameSize; ///< framesize_t type for camera module
|
framesize_t TFrameSize; ///< framesize_t type for camera module
|
||||||
uint8_t imageExifRotation; ///< image rotation. 0 degree: value 1, 90 degree: value 6, 180 degree: value 3, 270 degree: value 8
|
uint8_t imageExifRotation; ///< image rotation. 0 degree: value 1, 90 degree: value 6, 180 degree: value 3, 270 degree: value 8
|
||||||
|
|
||||||
|
|
@ -69,13 +67,19 @@ private:
|
||||||
/* OV2640 camera module pinout and cfg*/
|
/* OV2640 camera module pinout and cfg*/
|
||||||
camera_config_t CameraConfig; ///< camera configuration
|
camera_config_t CameraConfig; ///< camera configuration
|
||||||
camera_fb_t *FrameBuffer; ///< frame buffer
|
camera_fb_t *FrameBuffer; ///< frame buffer
|
||||||
|
camera_fb_t *FrameBufferDuplicate; ///< frame buffer duplicate
|
||||||
|
camera_fb_t *FrameBufferExif; ///< frame buffer with exif data
|
||||||
|
sensor_t* sensor; ///< sensor
|
||||||
String Photo; ///< photo in string format
|
String Photo; ///< photo in string format
|
||||||
bool StreamOnOff; ///< stream on/off
|
bool StreamOnOff; ///< stream on/off
|
||||||
|
bool StreamSendingPhoto; ///< sending photo to Prusa Connect during stream
|
||||||
SemaphoreHandle_t frameBufferSemaphore; ///< semaphore for frame buffer
|
SemaphoreHandle_t frameBufferSemaphore; ///< semaphore for frame buffer
|
||||||
float StreamAverageFps; ///< stream average fps
|
float StreamAverageFps; ///< stream average fps
|
||||||
uint16_t StreamAverageSize; ///< stream average size
|
uint16_t StreamAverageSize; ///< stream average size
|
||||||
PhotoExifData_t PhotoExifData; ///< photo exif data
|
PhotoExifData_t PhotoExifData; ///< photo exif data
|
||||||
uint8_t CameraCaptureFailedCounter; ///< camera capture failed counter
|
uint8_t CameraCaptureFailedCounter; ///< camera capture failed counter
|
||||||
|
camera_pid_t CameraType; ///< camera type
|
||||||
|
String CameraName; ///< camera name
|
||||||
|
|
||||||
Configuration *config; ///< pointer to Configuration object
|
Configuration *config; ///< pointer to Configuration object
|
||||||
Logs *log; ///< pointer to Logs object
|
Logs *log; ///< pointer to Logs object
|
||||||
|
|
@ -83,12 +87,13 @@ private:
|
||||||
void InitCameraModule();
|
void InitCameraModule();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Camera(Configuration*, Logs*, uint8_t);
|
Camera(Configuration*, Logs*, int8_t);
|
||||||
~Camera(){};
|
~Camera(){};
|
||||||
void Init();
|
void Init();
|
||||||
void ApplyCameraCfg();
|
void ApplyCameraCfg();
|
||||||
void LoadCameraCfgFromEeprom();
|
void LoadCameraCfgFromEeprom();
|
||||||
void ReinitCameraModule();
|
void ReinitCameraModule();
|
||||||
|
void GetCameraModel();
|
||||||
void CapturePhoto();
|
void CapturePhoto();
|
||||||
void CaptureStream(camera_fb_t *);
|
void CaptureStream(camera_fb_t *);
|
||||||
void CaptureReturnFrameBuffer();
|
void CaptureReturnFrameBuffer();
|
||||||
|
|
@ -101,6 +106,7 @@ public:
|
||||||
uint16_t StreamGetFrameAverageSize();
|
uint16_t StreamGetFrameAverageSize();
|
||||||
float StreamGetFrameAverageFps();
|
float StreamGetFrameAverageFps();
|
||||||
void StreamClearFrameData();
|
void StreamClearFrameData();
|
||||||
|
void StreamSetSendingPhoto(bool);
|
||||||
|
|
||||||
void CopyPhoto(camera_fb_t *);
|
void CopyPhoto(camera_fb_t *);
|
||||||
void CopyPhoto(String*);
|
void CopyPhoto(String*);
|
||||||
|
|
@ -109,6 +115,7 @@ public:
|
||||||
int GetPhotoSize();
|
int GetPhotoSize();
|
||||||
String GetPhoto();
|
String GetPhoto();
|
||||||
camera_fb_t *GetPhotoFb();
|
camera_fb_t *GetPhotoFb();
|
||||||
|
camera_fb_t* GetPhotoFbDuplicate();
|
||||||
PhotoExifData_t * GetPhotoExifData();
|
PhotoExifData_t * GetPhotoExifData();
|
||||||
framesize_t TransformFrameSizeDataType(uint8_t);
|
framesize_t TransformFrameSizeDataType(uint8_t);
|
||||||
void SetPhotoSending(bool);
|
void SetPhotoSending(bool);
|
||||||
|
|
@ -169,6 +176,4 @@ public:
|
||||||
|
|
||||||
extern Camera SystemCamera; ///< Camera object
|
extern Camera SystemCamera; ///< Camera object
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -100,7 +100,7 @@ void Configuration::ReadCfg() {
|
||||||
@return bool - status
|
@return bool - status
|
||||||
*/
|
*/
|
||||||
bool Configuration::CheckFirstMcuStart() {
|
bool Configuration::CheckFirstMcuStart() {
|
||||||
Log->AddEvent(LogLevel_Info, F("Read FirstMcuStart: "));
|
Log->AddEvent(LogLevel_Info, F("Read FirstMcuStart FLAG"));
|
||||||
uint8_t flag = EEPROM.read(EEPROM_ADDR_FIRST_MCU_START_FLAG_START);
|
uint8_t flag = EEPROM.read(EEPROM_ADDR_FIRST_MCU_START_FLAG_START);
|
||||||
|
|
||||||
if (CFG_FIRST_MCU_START_NAK == flag) {
|
if (CFG_FIRST_MCU_START_NAK == flag) {
|
||||||
|
|
@ -175,6 +175,8 @@ void Configuration::DefaultCfg() {
|
||||||
SaveNetworkDns(FACTORY_CFG_NETWORK_STATIC_DNS);
|
SaveNetworkDns(FACTORY_CFG_NETWORK_STATIC_DNS);
|
||||||
SaveCameraImageExifRotation(FACTORY_CFG_IMAGE_EXIF_ROTATION);
|
SaveCameraImageExifRotation(FACTORY_CFG_IMAGE_EXIF_ROTATION);
|
||||||
SaveTimeLapseFunctionStatus(FACTORY_CFG_TIMELAPS_ENABLE);
|
SaveTimeLapseFunctionStatus(FACTORY_CFG_TIMELAPS_ENABLE);
|
||||||
|
SaveExternalTemperatureSensorEnable(FACTORY_CFG_ENABLE_EXT_SENSOR);
|
||||||
|
SaveExternalTemperatureSensorUnit(FACTORY_CFG_EXT_SENSOR_UNIT);
|
||||||
Log->AddEvent(LogLevel_Warning, F("+++++++++++++++++++++++++++"));
|
Log->AddEvent(LogLevel_Warning, F("+++++++++++++++++++++++++++"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,14 +225,15 @@ void Configuration::CheckResetCfg() {
|
||||||
|
|
||||||
/* wait for ungrounded reset pin, and binking led */
|
/* wait for ungrounded reset pin, and binking led */
|
||||||
while (digitalRead(CFG_RESET_PIN) == LOW) {
|
while (digitalRead(CFG_RESET_PIN) == LOW) {
|
||||||
analogWrite(FLASH_GPIO_NUM, 20);
|
digitalWrite(CFG_RESET_LED_PIN, CFG_RESET_LED_LEVEL_ON);
|
||||||
delay(100);
|
delay(100);
|
||||||
analogWrite(FLASH_GPIO_NUM, 0);
|
digitalWrite(CFG_RESET_LED_PIN, !CFG_RESET_LED_LEVEL_ON);
|
||||||
delay(100);
|
delay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* turn off LED, reset cfg, reset MCU */
|
/* turn off LED, reset cfg, reset MCU */
|
||||||
analogWrite(FLASH_GPIO_NUM, 0);
|
digitalWrite(CFG_RESET_LED_PIN, !CFG_RESET_LED_LEVEL_ON);
|
||||||
|
|
||||||
DefaultCfg();
|
DefaultCfg();
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
|
|
||||||
|
|
@ -851,6 +854,26 @@ void Configuration::SaveTimeLapseFunctionStatus(bool i_data) {
|
||||||
SaveBool(EEPROM_ADDR_TIMELAPS_ENABLE_START, i_data);
|
SaveBool(EEPROM_ADDR_TIMELAPS_ENABLE_START, i_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@info Save external temperature sensor enable
|
||||||
|
@param bool - value
|
||||||
|
@return none
|
||||||
|
*/
|
||||||
|
void Configuration::SaveExternalTemperatureSensorEnable(bool i_data) {
|
||||||
|
Log->AddEvent(LogLevel_Verbose, F("Save external temperature sensor enable: "), String(i_data));
|
||||||
|
SaveBool(EEPROM_ADDR_EXT_SENS_ENABLE_START, i_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@info Save external temperature sensor unit
|
||||||
|
@param uint8_t - value
|
||||||
|
@return none
|
||||||
|
*/
|
||||||
|
void Configuration::SaveExternalTemperatureSensorUnit(uint8_t i_data) {
|
||||||
|
Log->AddEvent(LogLevel_Verbose, F("Save external temperature sensor unit: "), String(i_data));
|
||||||
|
SaveUint8(EEPROM_ADDR_EXT_SENS_UNIT_START, i_data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@info load refresh interval from eeprom
|
@info load refresh interval from eeprom
|
||||||
@param none
|
@param none
|
||||||
|
|
@ -1362,4 +1385,37 @@ bool Configuration::LoadTimeLapseFunctionStatus() {
|
||||||
return (bool) ret;
|
return (bool) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load external temperature sensor enable
|
||||||
|
*
|
||||||
|
* @return bool - status
|
||||||
|
*/
|
||||||
|
bool Configuration::LoadExternalTemperatureSensorEnable() {
|
||||||
|
uint8_t ret = EEPROM.read(EEPROM_ADDR_EXT_SENS_ENABLE_START);
|
||||||
|
Log->AddEvent(LogLevel_Info, F("External temperature sensor enable: "), String(ret));
|
||||||
|
|
||||||
|
if (ret == 255) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (bool) ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load external temperature sensor unit
|
||||||
|
*
|
||||||
|
* @return uint8_t - unit
|
||||||
|
*/
|
||||||
|
uint8_t Configuration::LoadExternalTemperatureSensorUnit() {
|
||||||
|
uint8_t ret = EEPROM.read(EEPROM_ADDR_EXT_SENS_UNIT_START);
|
||||||
|
Log->AddEvent(LogLevel_Info, F("External temperature sensor unit: "), String(ret));
|
||||||
|
|
||||||
|
if (ret == 255) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -9,19 +9,20 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CFG_H_
|
#pragma once
|
||||||
#define _CFG_H_
|
|
||||||
#include <WiFi.h>
|
|
||||||
#include <EEPROM.h>
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include <EEPROM.h>
|
||||||
|
#include <Arduino.h>
|
||||||
#include <ArduinoUniqueID.h>
|
#include <ArduinoUniqueID.h>
|
||||||
#include <base64.h>
|
#include <base64.h>
|
||||||
|
|
||||||
#include "mcu_cfg.h"
|
#include "micro_sd.h"
|
||||||
#include "Camera_cfg.h"
|
|
||||||
#include "var.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "log_level.h"
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
#include "module_templates.h"
|
||||||
|
#include "var.h"
|
||||||
|
#include "wifi_mngt.h"
|
||||||
|
|
||||||
class Configuration {
|
class Configuration {
|
||||||
public:
|
public:
|
||||||
|
|
@ -73,6 +74,8 @@ public:
|
||||||
void SaveNetworkDns(String);
|
void SaveNetworkDns(String);
|
||||||
void SaveCameraImageExifRotation(uint8_t);
|
void SaveCameraImageExifRotation(uint8_t);
|
||||||
void SaveTimeLapseFunctionStatus(bool);
|
void SaveTimeLapseFunctionStatus(bool);
|
||||||
|
void SaveExternalTemperatureSensorEnable(bool);
|
||||||
|
void SaveExternalTemperatureSensorUnit(uint8_t);
|
||||||
|
|
||||||
uint8_t LoadRefreshInterval();
|
uint8_t LoadRefreshInterval();
|
||||||
String LoadToken();
|
String LoadToken();
|
||||||
|
|
@ -115,6 +118,8 @@ public:
|
||||||
String LoadNetworkDns();
|
String LoadNetworkDns();
|
||||||
uint8_t LoadCameraImageExifRotation();
|
uint8_t LoadCameraImageExifRotation();
|
||||||
bool LoadTimeLapseFunctionStatus();
|
bool LoadTimeLapseFunctionStatus();
|
||||||
|
bool LoadExternalTemperatureSensorEnable();
|
||||||
|
uint8_t LoadExternalTemperatureSensorUnit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Logs *Log; ///< Pointer to Logs object
|
Logs *Log; ///< Pointer to Logs object
|
||||||
|
|
@ -139,6 +144,4 @@ private:
|
||||||
|
|
||||||
extern Configuration SystemConfig; ///< Configuration object
|
extern Configuration SystemConfig; ///< Configuration object
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
||||||
|
|
@ -126,11 +126,20 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i
|
||||||
|
|
||||||
/* get photo buffer */
|
/* get photo buffer */
|
||||||
bool SendWithExif = false;
|
bool SendWithExif = false;
|
||||||
uint8_t *fbBuf = camera->GetPhotoFb()->buf;
|
uint8_t *fbBuf = NULL;
|
||||||
size_t fbLen = camera->GetPhotoFb()->len;
|
size_t fbLen = 0;
|
||||||
|
if (camera->GetStreamStatus() == true) {
|
||||||
|
/* get duplicate photo buffer from camera */
|
||||||
|
fbBuf = camera->GetPhotoFbDuplicate()->buf;
|
||||||
|
fbLen = camera->GetPhotoFbDuplicate()->len;
|
||||||
|
} else {
|
||||||
|
/* get original photo buffer from camera */
|
||||||
|
fbBuf = camera->GetPhotoFb()->buf;
|
||||||
|
fbLen = camera->GetPhotoFb()->len;
|
||||||
|
}
|
||||||
|
|
||||||
/* sending exif data */
|
/* sending exif data */
|
||||||
if (camera->GetPhotoExifData()->header != NULL) {
|
if ((camera->GetPhotoExifData()->header != NULL) && (camera->GetStreamStatus() == false)) {
|
||||||
SendWithExif = true;
|
SendWithExif = true;
|
||||||
sendet_data += client.write(camera->GetPhotoExifData()->header, camera->GetPhotoExifData()->len);
|
sendet_data += client.write(camera->GetPhotoExifData()->header, camera->GetPhotoExifData()->len);
|
||||||
fbBuf += camera->GetPhotoExifData()->offset;
|
fbBuf += camera->GetPhotoExifData()->offset;
|
||||||
|
|
@ -151,7 +160,6 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.println("\r\n");
|
client.println("\r\n");
|
||||||
client.flush();
|
|
||||||
|
|
||||||
/* log message */
|
/* log message */
|
||||||
if (SendWithExif) {
|
if (SendWithExif) {
|
||||||
|
|
@ -164,15 +172,24 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i
|
||||||
} else if (SendInfo == i_data_type) {
|
} else if (SendInfo == i_data_type) {
|
||||||
log->AddEvent(LogLevel_Verbose, F("Sending info"));
|
log->AddEvent(LogLevel_Verbose, F("Sending info"));
|
||||||
sendet_data = client.print(*i_data);
|
sendet_data = client.print(*i_data);
|
||||||
client.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client.flush();
|
||||||
log->AddEvent(LogLevel_Info, "Send done: " + String(i_data_length) + "/" + String(sendet_data) + " bytes");
|
log->AddEvent(LogLevel_Info, "Send done: " + String(i_data_length) + "/" + String(sendet_data) + " bytes");
|
||||||
esp_task_wdt_reset();
|
|
||||||
|
/* check if all data was sent */
|
||||||
|
if (i_data_length != sendet_data) {
|
||||||
|
BackendReceivedStatus = F("INCOMPLETE DATA SEND TO SERVER!");
|
||||||
|
log->AddEvent(LogLevel_Error, F("ERROR SEND DATA TO SERVER! INCORRECT DATA LENGTH!"));
|
||||||
|
client.stop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//esp_task_wdt_reset();
|
||||||
|
|
||||||
/* read response from server */
|
/* read response from server */
|
||||||
String response = "";
|
String response = "";
|
||||||
String fullResponse = "";
|
String fullResponse = "";
|
||||||
|
delay(10); // wait for response
|
||||||
log->AddEvent(LogLevel_Verbose, F("Response:"));
|
log->AddEvent(LogLevel_Verbose, F("Response:"));
|
||||||
while (client.connected()) {
|
while (client.connected()) {
|
||||||
if (client.available()) {
|
if (client.available()) {
|
||||||
|
|
@ -225,10 +242,12 @@ void PrusaConnect::SendPhotoToBackend() {
|
||||||
String Photo = "";
|
String Photo = "";
|
||||||
size_t total_len = 0;
|
size_t total_len = 0;
|
||||||
|
|
||||||
if (camera->GetPhotoExifData()->header != NULL) {
|
if ((camera->GetPhotoExifData()->header != NULL) && (camera->GetStreamStatus() == false)) {
|
||||||
total_len = camera->GetPhotoExifData()->len + camera->GetPhotoFb()->len - camera->GetPhotoExifData()->offset;
|
total_len = camera->GetPhotoExifData()->len + camera->GetPhotoFb()->len - camera->GetPhotoExifData()->offset;
|
||||||
} else {
|
} else if (camera->GetStreamStatus() == false) {
|
||||||
total_len = camera->GetPhotoFb()->len;
|
total_len = camera->GetPhotoFb()->len;
|
||||||
|
} else {
|
||||||
|
total_len = camera->GetPhotoFbDuplicate()->len;
|
||||||
}
|
}
|
||||||
SendDataToBackend(&Photo, total_len, F("image/jpg"), F("Photo"), HOST_URL_CAM_PATH, SendPhoto);
|
SendDataToBackend(&Photo, total_len, F("image/jpg"), F("Photo"), HOST_URL_CAM_PATH, SendPhoto);
|
||||||
camera->SetPhotoSending(false);
|
camera->SetPhotoSending(false);
|
||||||
|
|
@ -250,6 +269,9 @@ void PrusaConnect::SendInfoToBackend() {
|
||||||
|
|
||||||
JsonObject config = json_data["config"].to<JsonObject>();
|
JsonObject config = json_data["config"].to<JsonObject>();
|
||||||
config["name"] = wifi->GetMdns();
|
config["name"] = wifi->GetMdns();
|
||||||
|
config["firmware"] = SW_VERSION;
|
||||||
|
config["manufacturer"] = F("Prusa");
|
||||||
|
config["model"] = BOARD_NAME;
|
||||||
|
|
||||||
JsonObject resolution = config["resolution"].to<JsonObject>();
|
JsonObject resolution = config["resolution"].to<JsonObject>();
|
||||||
resolution["width"] = SystemCamera.GetFrameSizeWidth();
|
resolution["width"] = SystemCamera.GetFrameSizeWidth();
|
||||||
|
|
@ -294,7 +316,11 @@ void PrusaConnect::TakePictureAndSendToBackend() {
|
||||||
log->AddEvent(LogLevel_Error, F("Error capturing photo. Stop sending to backend!"));
|
log->AddEvent(LogLevel_Error, F("Error capturing photo. Stop sending to backend!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
camera->CaptureReturnFrameBuffer();
|
/* return frame buffer */
|
||||||
|
if (camera->GetStreamStatus() == true) {
|
||||||
|
/* set stream flag for sending photo to false */
|
||||||
|
camera->StreamSetSendingPhoto(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -459,18 +485,30 @@ void PrusaConnect::SetTimeLapsPhotoSaveStatus(bool i_data) {
|
||||||
@return none
|
@return none
|
||||||
*/
|
*/
|
||||||
void PrusaConnect::SavePhotoToSdCard() {
|
void PrusaConnect::SavePhotoToSdCard() {
|
||||||
|
#if (ENABLE_SD_CARD == true)
|
||||||
|
/* check if time laps photo save is enabled */
|
||||||
if (EnableTimelapsPhotoSave == true) {
|
if (EnableTimelapsPhotoSave == true) {
|
||||||
log->AddEvent(LogLevel_Info, F("Save TimeLaps photo to SD card"));
|
log->AddEvent(LogLevel_Info, F("Save TimeLaps photo to SD card"));
|
||||||
|
|
||||||
|
/* check if SD card is detected */
|
||||||
|
if (log->GetCardDetectedStatus() == false) {
|
||||||
|
log->AddEvent(LogLevel_Error, F("SD card not detected!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if folder for time laps photos exists */
|
||||||
if (false == log->CheckDir(SD_MMC, TIMELAPS_PHOTO_FOLDER)) {
|
if (false == log->CheckDir(SD_MMC, TIMELAPS_PHOTO_FOLDER)) {
|
||||||
log->AddEvent(LogLevel_Info, F("Create folder for TimeLaps photos"));
|
log->AddEvent(LogLevel_Info, F("Create folder for TimeLaps photos"));
|
||||||
log->CreateDir(SD_MMC, TIMELAPS_PHOTO_FOLDER);
|
log->CreateDir(SD_MMC, TIMELAPS_PHOTO_FOLDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* create file name */
|
||||||
String FileName = String(TIMELAPS_PHOTO_FOLDER) + "/" + String(TIMELAPS_PHOTO_PREFIX) + "_";
|
String FileName = String(TIMELAPS_PHOTO_FOLDER) + "/" + String(TIMELAPS_PHOTO_PREFIX) + "_";
|
||||||
FileName += log->GetSystemTime();
|
FileName += log->GetSystemTime();
|
||||||
FileName += TIMELAPS_PHOTO_SUFFIX;
|
FileName += TIMELAPS_PHOTO_SUFFIX;
|
||||||
log->AddEvent(LogLevel_Verbose, F("Saving file: "), FileName);
|
log->AddEvent(LogLevel_Verbose, F("Saving file: "), FileName);
|
||||||
|
|
||||||
|
/* save photo to SD card */
|
||||||
if (camera->GetPhotoExifData()->header != NULL) {
|
if (camera->GetPhotoExifData()->header != NULL) {
|
||||||
if (log->WritePicture(FileName, camera->GetPhotoFb()->buf + camera->GetPhotoExifData()->offset, camera->GetPhotoFb()->len - camera->GetPhotoExifData()->offset, camera->GetPhotoExifData()->header, camera->GetPhotoExifData()->len) == true) {
|
if (log->WritePicture(FileName, camera->GetPhotoFb()->buf + camera->GetPhotoExifData()->offset, camera->GetPhotoFb()->len - camera->GetPhotoExifData()->offset, camera->GetPhotoExifData()->header, camera->GetPhotoExifData()->len) == true) {
|
||||||
log->AddEvent(LogLevel_Info, F("Photo saved to SD card. EXIF"));
|
log->AddEvent(LogLevel_Info, F("Photo saved to SD card. EXIF"));
|
||||||
|
|
@ -486,6 +524,7 @@ void PrusaConnect::SavePhotoToSdCard() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,12 @@
|
||||||
|
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#ifndef _PRUSA_CONNECT_H_
|
|
||||||
#define _PRUSA_CONNECT_H_
|
|
||||||
|
|
||||||
#include <WiFiClientSecure.h>
|
#include <WiFiClientSecure.h>
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
#include "Arduino.h"
|
#include <Arduino.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
#include "wifi_mngt.h"
|
#include "wifi_mngt.h"
|
||||||
|
|
@ -25,28 +23,12 @@
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "cfg.h"
|
#include "cfg.h"
|
||||||
#include "Certificate.h"
|
#include "Certificate.h"
|
||||||
#include "server.h"
|
#include "WebServer.h"
|
||||||
|
#include "connect_types.h"
|
||||||
|
|
||||||
class WiFiMngt;
|
class WiFiMngt;
|
||||||
|
class Configuration;
|
||||||
/**
|
class Camera;
|
||||||
* @brief BackendAvailabilitStatus enum
|
|
||||||
* status of backend availability
|
|
||||||
*/
|
|
||||||
enum BackendAvailabilitStatus {
|
|
||||||
WaitForFirstConnection = 0, ///< waiting for first connection to backend
|
|
||||||
BackendAvailable = 1, ///< backend is available
|
|
||||||
BackendUnavailable = 2, ///< backend is unavailable
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief SendDataToBackendType enum
|
|
||||||
* type of data to send to backend
|
|
||||||
*/
|
|
||||||
enum SendDataToBackendType {
|
|
||||||
SendPhoto = 0, ///< send photo to backend
|
|
||||||
SendInfo = 1, ///< send device information to backend
|
|
||||||
};
|
|
||||||
|
|
||||||
class PrusaConnect {
|
class PrusaConnect {
|
||||||
private:
|
private:
|
||||||
|
|
@ -109,4 +91,4 @@ public:
|
||||||
|
|
||||||
extern PrusaConnect Connect; ///< PrusaConnect object
|
extern PrusaConnect Connect; ///< PrusaConnect object
|
||||||
|
|
||||||
#endif
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
@file connect_types.h
|
||||||
|
|
||||||
|
@brief Here are defined types for communication with prusa connect backend
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
@bug: no know bug
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BackendAvailabilitStatus enum
|
||||||
|
* status of backend availability
|
||||||
|
*/
|
||||||
|
enum BackendAvailabilitStatus {
|
||||||
|
WaitForFirstConnection = 0, ///< waiting for first connection to backend
|
||||||
|
BackendAvailable = 1, ///< backend is available
|
||||||
|
BackendUnavailable = 2, ///< backend is unavailable
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SendDataToBackendType enum
|
||||||
|
* type of data to send to backend
|
||||||
|
*/
|
||||||
|
enum SendDataToBackendType {
|
||||||
|
SendPhoto = 0, ///< send photo to backend
|
||||||
|
SendInfo = 1, ///< send device information to backend
|
||||||
|
};
|
||||||
|
|
@ -23,6 +23,8 @@ Logs::Logs() {
|
||||||
LogLevel = LogLevel_Verbose;
|
LogLevel = LogLevel_Verbose;
|
||||||
FileMaxSize = 1024;
|
FileMaxSize = 1024;
|
||||||
NtpTimeSynced = false;
|
NtpTimeSynced = false;
|
||||||
|
LogMsg = "";
|
||||||
|
LogMutex = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,6 +39,8 @@ Logs::Logs(String i_FilePath, String i_FileName) {
|
||||||
LogLevel = LogLevel_Verbose;
|
LogLevel = LogLevel_Verbose;
|
||||||
FileMaxSize = 1024;
|
FileMaxSize = 1024;
|
||||||
NtpTimeSynced = false;
|
NtpTimeSynced = false;
|
||||||
|
LogMsg = "";
|
||||||
|
LogMutex = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -52,6 +56,8 @@ Logs::Logs(LogLevel_enum i_LogLevel, String i_FilePath, String i_FileName) {
|
||||||
LogLevel = i_LogLevel;
|
LogLevel = i_LogLevel;
|
||||||
FileMaxSize = 1024;
|
FileMaxSize = 1024;
|
||||||
NtpTimeSynced = false;
|
NtpTimeSynced = false;
|
||||||
|
LogMsg = "";
|
||||||
|
LogMutex = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -67,6 +73,8 @@ Logs::Logs(String i_FilePath, String i_FileName, uint16_t i_FileSize) {
|
||||||
LogLevel = LogLevel_Verbose;
|
LogLevel = LogLevel_Verbose;
|
||||||
FileMaxSize = i_FileSize;
|
FileMaxSize = i_FileSize;
|
||||||
NtpTimeSynced = false;
|
NtpTimeSynced = false;
|
||||||
|
LogMsg = "";
|
||||||
|
LogMutex = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -83,6 +91,8 @@ Logs::Logs(LogLevel_enum i_LogLevel, String i_FilePath, String i_FileName, uint1
|
||||||
LogLevel = i_LogLevel;
|
LogLevel = i_LogLevel;
|
||||||
FileMaxSize = i_FileSize;
|
FileMaxSize = i_FileSize;
|
||||||
NtpTimeSynced = false;
|
NtpTimeSynced = false;
|
||||||
|
LogMsg = "";
|
||||||
|
LogMutex = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -97,30 +107,66 @@ void Logs::Init() {
|
||||||
Serial.println(F("Init Logs library"));
|
Serial.println(F("Init Logs library"));
|
||||||
|
|
||||||
/* init micro SD card */
|
/* init micro SD card */
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
InitSdCard();
|
InitSdCard();
|
||||||
|
LogFileOpened = OpenFile(&LogFile, FilePath + FileName);
|
||||||
|
|
||||||
if (true == GetCardDetectedStatus()) {
|
if (true == GetCardDetectedStatus()) {
|
||||||
/* check maximum log file size */
|
/* check maximum log file size */
|
||||||
CheckMaxLogFileSize();
|
CheckMaxLogFileSize();
|
||||||
|
|
||||||
/* added first message to log file after start MCU */
|
/* added first message to log file after start MCU */
|
||||||
String msg = F("----------------------------------------------------------------\n");
|
LogMsg = F("----------------------------------------------------------------\n");
|
||||||
msg += F("Start MCU!\nSW Version: ");
|
LogMsg += F("Start MCU!\nSW Version: ");
|
||||||
msg += String(SW_VERSION);
|
LogMsg += String(SW_VERSION);
|
||||||
msg += F(" ,Build: ");
|
LogMsg += F(" ,Build: ");
|
||||||
msg += String(SW_BUILD);
|
LogMsg += String(SW_BUILD);
|
||||||
msg += "\n";
|
LogMsg += "\n";
|
||||||
msg += F("Verbose mode: ");
|
LogMsg += F("Verbose mode: ");
|
||||||
msg += (true == CONSOLE_VERBOSE_DEBUG) ? "true" : "false";
|
LogMsg += (true == CONSOLE_VERBOSE_DEBUG) ? "true" : "false";
|
||||||
msg += "\n";
|
LogMsg += "\n";
|
||||||
msg += F("Log level: ");
|
LogMsg += F("Log level: ");
|
||||||
msg += String(LogLevel);
|
LogMsg += String(LogLevel);
|
||||||
msg += "\n";
|
LogMsg += "\n";
|
||||||
AppendFile(SD_MMC, FilePath + FileName, msg);
|
AppendFile(&LogFile, &LogMsg);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Serial.println(F("Micro-SD card not found! Disable logs"));
|
Serial.println(F("Micro-SD card not found! Disable logs"));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
Serial.println(F("Micro-SD card not enabled! Disable logs to card"));
|
||||||
|
LogFileOpened = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open log file
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Logs::LogOpenFile() {
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
|
LogFileOpened = OpenFile(&LogFile, FilePath + FileName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close log file
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Logs::LogCloseFile() {
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
|
CloseFile(&LogFile);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for check opened log file
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Logs::LogCheckOpenedFile() {
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
|
LogFileOpened = CheckOpenFile(&LogFile);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -141,9 +187,13 @@ void Logs::SetLogLevel(LogLevel_enum level) {
|
||||||
@return none
|
@return none
|
||||||
*/
|
*/
|
||||||
void Logs::AddEvent(LogLevel_enum level, String msg, bool newLine, bool date) {
|
void Logs::AddEvent(LogLevel_enum level, String msg, bool newLine, bool date) {
|
||||||
|
/* mutex for log */
|
||||||
|
xSemaphoreTake(LogMutex, portMAX_DELAY);
|
||||||
|
/* check log level */
|
||||||
if (LogLevel >= level) {
|
if (LogLevel >= level) {
|
||||||
String LogMsg = "";
|
|
||||||
|
|
||||||
|
/* create log message */
|
||||||
|
LogMsg = "";
|
||||||
if (true == date) {
|
if (true == date) {
|
||||||
LogMsg += GetSystemTime();
|
LogMsg += GetSystemTime();
|
||||||
LogMsg += " - ";
|
LogMsg += " - ";
|
||||||
|
|
@ -153,14 +203,28 @@ void Logs::AddEvent(LogLevel_enum level, String msg, bool newLine, bool date) {
|
||||||
LogMsg += "\n";
|
LogMsg += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
AppendFile(SD_MMC, FilePath + FileName, LogMsg);
|
/* print log message to console */
|
||||||
Serial.print(LogMsg);
|
Serial.print(LogMsg);
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
|
/* append log message to log file */
|
||||||
|
if (true == LogFileOpened) {
|
||||||
|
LogFileOpened = AppendFile(&LogFile, &LogMsg);
|
||||||
|
if ((false == LogFileOpened) && (true == GetCardDetectedStatus())){
|
||||||
|
LogCloseFile();
|
||||||
|
LogOpenFile();
|
||||||
|
if (true == LogFileOpened) {
|
||||||
|
LogFileOpened = AppendFile(&LogFile, &LogMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#if (true == CONSOLE_VERBOSE_DEBUG)
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
else {
|
else {
|
||||||
Serial.println(msg);
|
Serial.println(msg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
xSemaphoreGive(LogMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -173,9 +237,14 @@ void Logs::AddEvent(LogLevel_enum level, String msg, bool newLine, bool date) {
|
||||||
@return none
|
@return none
|
||||||
*/
|
*/
|
||||||
void Logs::AddEvent(LogLevel_enum level, const __FlashStringHelper *msg, String parameters, bool newLine, bool date) {
|
void Logs::AddEvent(LogLevel_enum level, const __FlashStringHelper *msg, String parameters, bool newLine, bool date) {
|
||||||
if (LogLevel >= level) {
|
/* mutex for log */
|
||||||
String LogMsg = "";
|
xSemaphoreTake(LogMutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
/* check log level */
|
||||||
|
if (LogLevel >= level) {
|
||||||
|
|
||||||
|
/* create log message */
|
||||||
|
LogMsg = "";
|
||||||
if (true == date) {
|
if (true == date) {
|
||||||
LogMsg += GetSystemTime();
|
LogMsg += GetSystemTime();
|
||||||
LogMsg += " - ";
|
LogMsg += " - ";
|
||||||
|
|
@ -186,14 +255,31 @@ void Logs::AddEvent(LogLevel_enum level, const __FlashStringHelper *msg, String
|
||||||
LogMsg += "\n";
|
LogMsg += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
AppendFile(SD_MMC, FilePath + FileName, LogMsg);
|
/* print log message to console */
|
||||||
Serial.print(LogMsg);
|
Serial.print(LogMsg);
|
||||||
|
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
|
/* append log message to log file */
|
||||||
|
if (true == LogFileOpened) {
|
||||||
|
LogFileOpened = AppendFile(&LogFile, &LogMsg);
|
||||||
|
if ((false == LogFileOpened) && (true == GetCardDetectedStatus())){
|
||||||
|
LogCloseFile();
|
||||||
|
LogOpenFile();
|
||||||
|
if (true == LogFileOpened) {
|
||||||
|
AppendFile(&LogFile, &LogMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#if (true == CONSOLE_VERBOSE_DEBUG)
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
else {
|
else {
|
||||||
Serial.println(msg);
|
Serial.println(msg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* release mutex */
|
||||||
|
xSemaphoreGive(LogMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -275,20 +361,34 @@ bool Logs::GetNtpTimeSynced() {
|
||||||
@return none
|
@return none
|
||||||
*/
|
*/
|
||||||
void Logs::CheckMaxLogFileSize() {
|
void Logs::CheckMaxLogFileSize() {
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
uint32_t FileSize = GetFileSize(SD_MMC, FilePath + FileName);
|
uint32_t FileSize = GetFileSize(SD_MMC, FilePath + FileName);
|
||||||
AddEvent(LogLevel_Verbose, F("Log file size: "), String(FileSize) + " bytes");
|
AddEvent(LogLevel_Verbose, F("Log file size: "), String(FileSize) + "/" + String(LOGS_FILE_MAX_SIZE) + " B");
|
||||||
|
|
||||||
if (FileSize >= LOGS_FILE_MAX_SIZE) {
|
if (FileSize >= LOGS_FILE_MAX_SIZE) {
|
||||||
uint16_t file_count = FileCount(SD_MMC, FilePath, FileName);
|
uint16_t file_count = FileCount(SD_MMC, FilePath, FileName);
|
||||||
AddEvent(LogLevel_Info, F("Maximum log file size. File count: "), String(file_count));
|
AddEvent(LogLevel_Info, F("Maximum log file size. File count: "), String(file_count));
|
||||||
|
LogCloseFile();
|
||||||
RenameFile(SD_MMC, FilePath + FileName, FilePath + FileName + String(file_count));
|
RenameFile(SD_MMC, FilePath + FileName, FilePath + FileName + String(file_count));
|
||||||
|
LogOpenFile();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logs::CheckCardSpace() {
|
void Logs::CheckCardSpace() {
|
||||||
|
#if (true == ENABLE_SD_CARD)
|
||||||
CheckCardUsedStatus();
|
CheckCardUsedStatus();
|
||||||
AddEvent(LogLevel_Verbose, "Card size: " + String(GetCardSizeMB()), + " MB, Used: " + String(GetCardUsedMB()) + " MB, Free: " + String(GetCardUsedMB()) + " MB");
|
AddEvent(LogLevel_Verbose, "Card size: " + String(GetCardSizeMB()), + " MB, Used: " + String(GetCardUsedMB()) + " MB, Free: " + String(GetCardUsedMB()) + " MB");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@info Get log file opened
|
||||||
|
@param none
|
||||||
|
@return bool - log file opened
|
||||||
|
*/
|
||||||
|
bool Logs::GetLogFileOpened() {
|
||||||
|
return LogFileOpened;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -9,29 +9,24 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LOG_H_
|
#pragma once
|
||||||
#define _LOG_H_
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include <Arduino.h>
|
||||||
|
|
||||||
#include "mcu_cfg.h"
|
|
||||||
#include "var.h"
|
|
||||||
#include "micro_sd.h"
|
#include "micro_sd.h"
|
||||||
|
#include "log_level.h"
|
||||||
enum LogLevel_enum {
|
|
||||||
LogLevel_Error = 0, ///< Error
|
|
||||||
LogLevel_Warning = 1, ///< Warning
|
|
||||||
LogLevel_Info = 2, ///< Info
|
|
||||||
LogLevel_Verbose = 3 ///< Verbose
|
|
||||||
};
|
|
||||||
|
|
||||||
class Logs : public MicroSd {
|
class Logs : public MicroSd {
|
||||||
private:
|
private:
|
||||||
LogLevel_enum LogLevel; ///< LogLevel
|
LogLevel_enum LogLevel; ///< LogLevel
|
||||||
String FileName; ///< log File name
|
String FileName; ///< log File name
|
||||||
String FilePath; ///< log file patch
|
String FilePath; ///< log file patch
|
||||||
uint16_t FileMaxSize; ///< log file max size
|
uint16_t FileMaxSize; ///< log file max size
|
||||||
bool NtpTimeSynced; ///< status NTP time sync
|
bool NtpTimeSynced; ///< status NTP time sync
|
||||||
|
String LogMsg; ///< log message
|
||||||
|
File LogFile; ///< log file object
|
||||||
|
bool LogFileOpened; ///< log file opened status
|
||||||
|
SemaphoreHandle_t LogMutex; ///< log mutex
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Logs();
|
Logs();
|
||||||
|
|
@ -42,6 +37,9 @@ public:
|
||||||
~Logs(){};
|
~Logs(){};
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
void LogOpenFile();
|
||||||
|
void LogCloseFile();
|
||||||
|
void LogCheckOpenedFile();
|
||||||
void AddEvent(LogLevel_enum, String, bool = true, bool = true);
|
void AddEvent(LogLevel_enum, String, bool = true, bool = true);
|
||||||
void AddEvent(LogLevel_enum, const __FlashStringHelper*, String, bool = true, bool = true);
|
void AddEvent(LogLevel_enum, const __FlashStringHelper*, String, bool = true, bool = true);
|
||||||
void SetLogLevel(LogLevel_enum);
|
void SetLogLevel(LogLevel_enum);
|
||||||
|
|
@ -56,12 +54,11 @@ public:
|
||||||
bool GetNtpTimeSynced();
|
bool GetNtpTimeSynced();
|
||||||
void CheckMaxLogFileSize();
|
void CheckMaxLogFileSize();
|
||||||
void CheckCardSpace();
|
void CheckCardSpace();
|
||||||
|
bool GetLogFileOpened();
|
||||||
|
|
||||||
String GetSystemTime();
|
String GetSystemTime();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Logs SystemLog; ///< log object
|
extern Logs SystemLog; ///< log object
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum LogLevel_enum {
|
||||||
|
LogLevel_Error = 0, ///< Error
|
||||||
|
LogLevel_Warning = 1, ///< Warning
|
||||||
|
LogLevel_Info = 2, ///< Info
|
||||||
|
LogLevel_Verbose = 3 ///< Verbose
|
||||||
|
};
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
@ -7,14 +7,22 @@
|
||||||
Contact: miroslav.pivovarsky@gmail.com
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MCU_CFG_H_
|
#ifndef _MCU_CFG_H_
|
||||||
#define _MCU_CFG_H_
|
#define _MCU_CFG_H_
|
||||||
|
|
||||||
|
/* ----------------- CAMERA TYPE ---------------*/
|
||||||
|
#define AI_THINKER_ESP32_CAM true
|
||||||
|
#define ESP32_WROVER_DEV false
|
||||||
|
#define CAMERA_MODEL_ESP32_S3_DEV_CAM false
|
||||||
|
#define CAMERA_MODEL_ESP32_S3_EYE_2_2 false
|
||||||
|
#define CAMERA_MODEL_XIAO_ESP32_S3_CAM false
|
||||||
|
#define CAMERA_MODEL_ESP32_S3_CAM false
|
||||||
|
#define ESP32_S3_WROOM_FREENOVE false
|
||||||
|
|
||||||
/* ---------------- BASIC MCU CFG --------------*/
|
/* ---------------- BASIC MCU CFG --------------*/
|
||||||
#define SW_VERSION "1.0.3-rc1" ///< SW version
|
#define SW_VERSION "1.1.2" ///< SW version
|
||||||
#define SW_BUILD __DATE__ " " __TIME__ ///< build number
|
#define SW_BUILD __DATE__ " " __TIME__ ///< build number
|
||||||
#define CONSOLE_VERBOSE_DEBUG false ///< enable/disable verbose debug log level for console
|
#define CONSOLE_VERBOSE_DEBUG false ///< enable/disable verbose debug log level for console
|
||||||
#define DEVICE_HOSTNAME "Prusa-ESP32cam" ///< device hostname
|
#define DEVICE_HOSTNAME "Prusa-ESP32cam" ///< device hostname
|
||||||
|
|
@ -26,17 +34,7 @@
|
||||||
#define REFRESH_INTERVAL_MIN 10 ///< minimum refresh interval for sending photo to prusa connect [s]
|
#define REFRESH_INTERVAL_MIN 10 ///< minimum refresh interval for sending photo to prusa connect [s]
|
||||||
#define REFRESH_INTERVAL_MAX 240 ///< maximum refresh interval for sending photo to prusa connect [s]
|
#define REFRESH_INTERVAL_MAX 240 ///< maximum refresh interval for sending photo to prusa connect [s]
|
||||||
|
|
||||||
/* --------------- FLASH LED CFG ---------------*/
|
|
||||||
#define FLASH_GPIO_NUM 4 ///< GPIO pin for light
|
|
||||||
#define FLASH_OFF_STATUS 0 ///< PWM intensity LED for OFF. 0-2^FLASH_PWM_RESOLUTION = 0-255
|
|
||||||
#define FLASH_ON_STATUS 205 ///< PWM intensity LED for ON. limitation to 80%. 2^FLASH_PWM_RESOLUTION * 0.8% = 204
|
|
||||||
#define FLASH_PWM_FREQ 2000 ///< frequency of pwm [240MHz / (100 prescale * pwm cycles)] = frequency
|
|
||||||
#define FLASH_PWM_CHANNEL 0 ///< channel 0
|
|
||||||
#define FLASH_PWM_RESOLUTION 8 ///< range 1-20bit. 8bit = 0-255 range
|
|
||||||
|
|
||||||
/* -------------- STATUS LED CFG ----------------*/
|
/* -------------- STATUS LED CFG ----------------*/
|
||||||
#define STATUS_LED_GPIO_NUM 33 ///< GPIO pin for status LED
|
|
||||||
#define STATUS_LED_ENABLE true ///< enable/disable status LED
|
|
||||||
#define STATUS_LED_ON_DURATION 100 ///< time for blink status LED when is module in the ON state [ms]
|
#define STATUS_LED_ON_DURATION 100 ///< time for blink status LED when is module in the ON state [ms]
|
||||||
#define STATUS_LED_WIFI_AP 400 ///< time for blink status LED when is module in the AP mode [ms]
|
#define STATUS_LED_WIFI_AP 400 ///< time for blink status LED when is module in the AP mode [ms]
|
||||||
#define STATUS_LED_STA_CONNECTING 800 ///< time for blink status LED when is module connecting to the WiFi network [ms]
|
#define STATUS_LED_STA_CONNECTING 800 ///< time for blink status LED when is module connecting to the WiFi network [ms]
|
||||||
|
|
@ -45,10 +43,10 @@
|
||||||
|
|
||||||
/* ------------------- TASKS --------------------*/
|
/* ------------------- TASKS --------------------*/
|
||||||
#define TASK_SYSTEM 1000 ///< system task interval [ms]
|
#define TASK_SYSTEM 1000 ///< system task interval [ms]
|
||||||
#define TASK_SDCARD 30000 ///< sd card task interval [ms]
|
#define TASK_SDCARD 25000 ///< sd card task interval [ms]
|
||||||
#define TASK_WIFI 30000 ///< wifi reconnect interval. Checking when is signal lost [ms]
|
#define TASK_WIFI 28000 ///< wifi reconnect interval. Checking when is signal lost [ms]
|
||||||
#define TASK_SERIAL_CFG 1000 ///< serial cfg task interval [ms]
|
#define TASK_SERIAL_CFG 1000 ///< serial cfg task interval [ms]
|
||||||
#define TASK_STREAM_TELEMETRY 30000 ///< stream telemetry task interval [ms]
|
#define TASK_SYSTEM_TELEMETRY 30000 ///< stream telemetry task interval [ms]
|
||||||
#define TASK_WIFI_WATCHDOG 20000 ///< wifi watchdog task interval [ms]
|
#define TASK_WIFI_WATCHDOG 20000 ///< wifi watchdog task interval [ms]
|
||||||
#define TASK_PHOTO_SEND 1000 ///< photo send task interval [ms]
|
#define TASK_PHOTO_SEND 1000 ///< photo send task interval [ms]
|
||||||
#define TASK_SDCARD_FILE_REMOVE 30000 ///< sd card file remove task interval [ms]
|
#define TASK_SDCARD_FILE_REMOVE 30000 ///< sd card file remove task interval [ms]
|
||||||
|
|
@ -56,8 +54,8 @@
|
||||||
/* --------------- WEB SERVER CFG --------------*/
|
/* --------------- WEB SERVER CFG --------------*/
|
||||||
#define WEB_SERVER_PORT 80 ///< WEB server port
|
#define WEB_SERVER_PORT 80 ///< WEB server port
|
||||||
#define SERIAL_PORT_SPEED 115200 ///< baud rate
|
#define SERIAL_PORT_SPEED 115200 ///< baud rate
|
||||||
#define WDG_TIMEOUT 40 ///< wdg timeout [second]
|
#define WDG_TIMEOUT 40000 ///< wdg timeout [second]
|
||||||
#define PHOTO_FRAGMENT_SIZE 5120 ///< photo fragmentation size [bytes]
|
#define PHOTO_FRAGMENT_SIZE 2048 ///< photo fragmentation size [bytes]
|
||||||
#define LOOP_DELAY 100 ///< loop delay [ms]
|
#define LOOP_DELAY 100 ///< loop delay [ms]
|
||||||
#define WIFI_CLIENT_WAIT_CON false ///< wait for connecting to WiFi network
|
#define WIFI_CLIENT_WAIT_CON false ///< wait for connecting to WiFi network
|
||||||
#define WEB_CACHE_INTERVAL 86400 ///< cache interval for browser [s] 86400s = 24h
|
#define WEB_CACHE_INTERVAL 86400 ///< cache interval for browser [s] 86400s = 24h
|
||||||
|
|
@ -65,17 +63,15 @@
|
||||||
/* --------------- OTA UPDATE CFG --------------*/
|
/* --------------- OTA UPDATE CFG --------------*/
|
||||||
#define OTA_UPDATE_API_SERVER "api.github.com" ///< OTA update server URL
|
#define OTA_UPDATE_API_SERVER "api.github.com" ///< OTA update server URL
|
||||||
#define OTA_UPDATE_API_URL F("/repos/prusa3d/Prusa-Firmware-ESP32-Cam/releases/latest") ///< path to file with OTA update
|
#define OTA_UPDATE_API_URL F("/repos/prusa3d/Prusa-Firmware-ESP32-Cam/releases/latest") ///< path to file with OTA update
|
||||||
#define OTA_UPDATE_FW_FILE PSTR("ESP32_PrusaConnectCam.ino.bin") ///< OTA update firmware file name
|
|
||||||
|
|
||||||
/* ---------- RESET CFG CONFIGURATION ----------*/
|
/* ---------- RESET CFG CONFIGURATION ----------*/
|
||||||
#define CFG_RESET_PIN 12 ///< GPIO 16 is for reset CFG to default
|
|
||||||
#define CFG_RESET_TIME_WAIT 10000 ///< wait to 10 000 ms = 10s for reset cfg during grounded CFG_RESET_PIN
|
#define CFG_RESET_TIME_WAIT 10000 ///< wait to 10 000 ms = 10s for reset cfg during grounded CFG_RESET_PIN
|
||||||
#define CFG_RESET_LOOP_DELAY 100 ///< delay in the loop for reset cfg
|
#define CFG_RESET_LOOP_DELAY 100 ///< delay in the loop for reset cfg
|
||||||
|
|
||||||
/* ---------------- MicroSD Logs ----------------*/
|
/* ---------------- MicroSD Logs ----------------*/
|
||||||
#define LOGS_FILE_NAME "SysLog.log" ///< syslog file name
|
#define LOGS_FILE_NAME "SysLog.log" ///< syslog file name
|
||||||
#define LOGS_FILE_PATH "/" ///< directory for log files
|
#define LOGS_FILE_PATH "/" ///< directory for log files
|
||||||
#define LOGS_FILE_MAX_SIZE 512 ///< maximum file size in the [kb]
|
#define LOGS_FILE_MAX_SIZE 1024 ///< maximum file size in the [kb]
|
||||||
#define FILE_REMOVE_MAX_COUNT 5 ///< maximum count for remove files from sd card
|
#define FILE_REMOVE_MAX_COUNT 5 ///< maximum count for remove files from sd card
|
||||||
|
|
||||||
/* ---------------- AP MODE CFG ----------------*/
|
/* ---------------- AP MODE CFG ----------------*/
|
||||||
|
|
@ -94,6 +90,7 @@
|
||||||
|
|
||||||
/* ----------------- WiFi CFG -------------------*/
|
/* ----------------- WiFi CFG -------------------*/
|
||||||
#define WIFI_STA_WDG_TIMEOUT 60000 ///< STA watchdog timeout [ms]
|
#define WIFI_STA_WDG_TIMEOUT 60000 ///< STA watchdog timeout [ms]
|
||||||
|
#define WIFI_DISABLE_UNENCRYPTED_STA_PASS_CHECK false ///< enable/disable WEP/WPA/WPA2/... encryption for STA mode . for the wifi network without encryption set to false
|
||||||
|
|
||||||
/* ----------------- NTP CFG --------------------*/
|
/* ----------------- NTP CFG --------------------*/
|
||||||
#define NTP_SERVER_1 "pool.ntp.org" ///< NTP server
|
#define NTP_SERVER_1 "pool.ntp.org" ///< NTP server
|
||||||
|
|
@ -105,9 +102,10 @@
|
||||||
#define CAMERA_MAKE "OmniVision" ///< Camera make string
|
#define CAMERA_MAKE "OmniVision" ///< Camera make string
|
||||||
#define CAMERA_MODEL "OV2640" ///< Camera model string
|
#define CAMERA_MODEL "OV2640" ///< Camera model string
|
||||||
#define CAMERA_SOFTWARE "Prusa ESP32-cam" ///< Camera software string
|
#define CAMERA_SOFTWARE "Prusa ESP32-cam" ///< Camera software string
|
||||||
|
#define CAMERA_EXIF_ROTATION_STREAM false ///< enable camera exif rotation for stream
|
||||||
|
|
||||||
/* ---------------- TIMELAPS CFG ----------------*/
|
/* ---------------- TIMELAPS CFG ----------------*/
|
||||||
#define TIMELAPS_PHOTO_FOLDER "/timelaps" ///< folder for timelaps photos
|
#define TIMELAPS_PHOTO_FOLDER "/timelapse" ///< folder for timelaps photos
|
||||||
#define TIMELAPS_PHOTO_PREFIX "photo" ///< photo name for timelaps
|
#define TIMELAPS_PHOTO_PREFIX "photo" ///< photo name for timelaps
|
||||||
#define TIMELAPS_PHOTO_SUFFIX ".jpg" ///< photo file type for timelaps
|
#define TIMELAPS_PHOTO_SUFFIX ".jpg" ///< photo file type for timelaps
|
||||||
|
|
||||||
|
|
@ -148,6 +146,8 @@
|
||||||
#define FACTORY_CFG_NETWORK_STATIC_DNS F("255.255.255.255") ///< Static DNS
|
#define FACTORY_CFG_NETWORK_STATIC_DNS F("255.255.255.255") ///< Static DNS
|
||||||
#define FACTORY_CFG_IMAGE_EXIF_ROTATION 1 ///< Image rotation 1 - 0°, 6 - 90°, 3 - 180°, 8 - 270°
|
#define FACTORY_CFG_IMAGE_EXIF_ROTATION 1 ///< Image rotation 1 - 0°, 6 - 90°, 3 - 180°, 8 - 270°
|
||||||
#define FACTORY_CFG_TIMELAPS_ENABLE 0 ///< enable timelaps functionality
|
#define FACTORY_CFG_TIMELAPS_ENABLE 0 ///< enable timelaps functionality
|
||||||
|
#define FACTORY_CFG_ENABLE_EXT_SENSOR 0 ///< enable DHT22 sensor
|
||||||
|
#define FACTORY_CFG_EXT_SENSOR_UNIT 0 ///< 0 = celsius, 1 = fahrenheit
|
||||||
|
|
||||||
/* ---------------- CFG FLAGS ------------------*/
|
/* ---------------- CFG FLAGS ------------------*/
|
||||||
#define CFG_WIFI_SETTINGS_SAVED 0x0A ///< flag saved config
|
#define CFG_WIFI_SETTINGS_SAVED 0x0A ///< flag saved config
|
||||||
|
|
@ -286,6 +286,12 @@
|
||||||
#define EEPROM_ADDR_TIMELAPS_ENABLE_START (EEPROM_ADDR_IMAGE_ROTATION_START + EEPROM_ADDR_IMAGE_ROTATION_LENGTH)
|
#define EEPROM_ADDR_TIMELAPS_ENABLE_START (EEPROM_ADDR_IMAGE_ROTATION_START + EEPROM_ADDR_IMAGE_ROTATION_LENGTH)
|
||||||
#define EEPROM_ADDR_TIMELAPS_ENABLE_LENGTH 1
|
#define EEPROM_ADDR_TIMELAPS_ENABLE_LENGTH 1
|
||||||
|
|
||||||
|
#define EEPROM_ADDR_EXT_SENS_ENABLE_START (EEPROM_ADDR_TIMELAPS_ENABLE_START + EEPROM_ADDR_TIMELAPS_ENABLE_LENGTH)
|
||||||
|
#define EEPROM_ADDR_EXT_SENS_ENABLE_LENGTH 1
|
||||||
|
|
||||||
|
#define EEPROM_ADDR_EXT_SENS_UNIT_START (EEPROM_ADDR_EXT_SENS_ENABLE_START + EEPROM_ADDR_EXT_SENS_ENABLE_LENGTH)
|
||||||
|
#define EEPROM_ADDR_EXT_SENS_UNIT_LENGTH 1
|
||||||
|
|
||||||
#define EEPROM_SIZE (EEPROM_ADDR_REFRESH_INTERVAL_LENGTH + EEPROM_ADDR_FINGERPRINT_LENGTH + EEPROM_ADDR_TOKEN_LENGTH + \
|
#define EEPROM_SIZE (EEPROM_ADDR_REFRESH_INTERVAL_LENGTH + EEPROM_ADDR_FINGERPRINT_LENGTH + EEPROM_ADDR_TOKEN_LENGTH + \
|
||||||
EEPROM_ADDR_FRAMESIZE_LENGTH + EEPROM_ADDR_BRIGHTNESS_LENGTH + EEPROM_ADDR_CONTRAST_LENGTH + \
|
EEPROM_ADDR_FRAMESIZE_LENGTH + EEPROM_ADDR_BRIGHTNESS_LENGTH + EEPROM_ADDR_CONTRAST_LENGTH + \
|
||||||
EEPROM_ADDR_SATURATION_LENGTH + EEPROM_ADDR_HMIRROR_LENGTH + EEPROM_ADDR_VFLIP_LENGTH + \
|
EEPROM_ADDR_SATURATION_LENGTH + EEPROM_ADDR_HMIRROR_LENGTH + EEPROM_ADDR_VFLIP_LENGTH + \
|
||||||
|
|
@ -300,7 +306,8 @@
|
||||||
EEPROM_ADDR_AEC_VALUE_LENGTH + EEPROM_ADDR_GAIN_CTRL_LENGTH + EEPROM_ADDR_AGC_GAIN_LENGTH + EEPROM_ADDR_LOG_LEVEL_LENGTH + \
|
EEPROM_ADDR_AEC_VALUE_LENGTH + EEPROM_ADDR_GAIN_CTRL_LENGTH + EEPROM_ADDR_AGC_GAIN_LENGTH + EEPROM_ADDR_LOG_LEVEL_LENGTH + \
|
||||||
EEPROM_ADDR_HOSTNAME_LENGTH + EEPROM_ADDR_SERVICE_AP_ENABLE_LENGTH + EEPROM_ADDR_NETWORK_IP_METHOD_LENGTH +\
|
EEPROM_ADDR_HOSTNAME_LENGTH + EEPROM_ADDR_SERVICE_AP_ENABLE_LENGTH + EEPROM_ADDR_NETWORK_IP_METHOD_LENGTH +\
|
||||||
EEPROM_ADDR_NETWORK_STATIC_IP_LENGTH + EEPROM_ADDR_NETWORK_STATIC_MASK_LENGTH + EEPROM_ADDR_NETWORK_STATIC_GATEWAY_LENGTH + \
|
EEPROM_ADDR_NETWORK_STATIC_IP_LENGTH + EEPROM_ADDR_NETWORK_STATIC_MASK_LENGTH + EEPROM_ADDR_NETWORK_STATIC_GATEWAY_LENGTH + \
|
||||||
EEPROM_ADDR_NETWORK_STATIC_DNS_LENGTH + EEPROM_ADDR_IMAGE_ROTATION_LENGTH + EEPROM_ADDR_TIMELAPS_ENABLE_LENGTH) ///< how many bits do we need for eeprom memory
|
EEPROM_ADDR_NETWORK_STATIC_DNS_LENGTH + EEPROM_ADDR_IMAGE_ROTATION_LENGTH + EEPROM_ADDR_TIMELAPS_ENABLE_LENGTH + \
|
||||||
|
EEPROM_ADDR_EXT_SENS_ENABLE_LENGTH + EEPROM_ADDR_EXT_SENS_UNIT_LENGTH) ///< how many bits do we need for eeprom memory
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
MicroSd::MicroSd() {
|
MicroSd::MicroSd() {
|
||||||
CardDetected = false;
|
CardDetected = false;
|
||||||
DetectAfterBoot = false;
|
DetectAfterBoot = false;
|
||||||
|
sdCardMutex = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -35,6 +36,73 @@ void MicroSd::ReinitCard() {
|
||||||
InitSdCard();
|
InitSdCard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open file
|
||||||
|
*
|
||||||
|
* @param i_file - file
|
||||||
|
* @param i_path - path and file name
|
||||||
|
* @return true
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
bool MicroSd::OpenFile(File *i_file, String i_path) {
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if (true == CardDetected) {
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
Serial.println("Opening file: " + i_path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (SD_MMC.cardType() == CARD_NONE) {
|
||||||
|
Serial.println("No SD card detected");
|
||||||
|
CardDetected = false;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
*i_file = SD_MMC.open(i_path.c_str(), FILE_APPEND);
|
||||||
|
if (!*i_file) {
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
Serial.println("Failed to open file");
|
||||||
|
#endif
|
||||||
|
CardDetected = false;
|
||||||
|
} else {
|
||||||
|
status = true;
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
Serial.println("File opened");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close file
|
||||||
|
*
|
||||||
|
* @param i_file - file
|
||||||
|
*/
|
||||||
|
void MicroSd::CloseFile(File *i_file) {
|
||||||
|
if (*i_file) {
|
||||||
|
i_file->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if file is opened
|
||||||
|
*
|
||||||
|
* @param i_file - file
|
||||||
|
* @return true
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
bool MicroSd::CheckOpenFile(File *i_file) {
|
||||||
|
if (!*i_file) {
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
Serial.println(F("File not opened!"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Init SD card. And check, if is SD card inserted
|
@brief Init SD card. And check, if is SD card inserted
|
||||||
@param none
|
@param none
|
||||||
|
|
@ -46,11 +114,13 @@ void MicroSd::InitSdCard() {
|
||||||
|
|
||||||
/* set SD card to 1-line/1-bit mode. GPIO 4 is used for LED and for microSD card. But communication is slower. */
|
/* set SD card to 1-line/1-bit mode. GPIO 4 is used for LED and for microSD card. But communication is slower. */
|
||||||
/* https://github.com/espressif/arduino-esp32/blob/master/libraries/SD_MMC/src/SD_MMC.h */
|
/* https://github.com/espressif/arduino-esp32/blob/master/libraries/SD_MMC/src/SD_MMC.h */
|
||||||
|
|
||||||
|
SD_MMC.setPins(SD_PIN_CLK, SD_PIN_CMD, SD_PIN_DATA0);
|
||||||
|
|
||||||
if (!SD_MMC.begin("/sdcard", true)) {
|
if (!SD_MMC.begin("/sdcard", true)) {
|
||||||
Serial.println(F("SD Card Mount Failed"));
|
Serial.println(F("SD Card Mount Failed"));
|
||||||
CardDetected = false;
|
CardDetected = false;
|
||||||
CardSizeMB = 0;
|
CardSizeMB = 0;
|
||||||
//DetectAfterBoot = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,20 +130,19 @@ void MicroSd::InitSdCard() {
|
||||||
Serial.println(F("No SD_MMC card attached"));
|
Serial.println(F("No SD_MMC card attached"));
|
||||||
CardDetected = false;
|
CardDetected = false;
|
||||||
CardSizeMB = 0;
|
CardSizeMB = 0;
|
||||||
//DetectAfterBoot = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print card type */
|
/* print card type */
|
||||||
Serial.print(F("Found card. Card Type: "));
|
Serial.print(F("Found card. Card Type: "));
|
||||||
if (cardType == CARD_MMC) {
|
if (cardType == CARD_MMC) {
|
||||||
Serial.print(F("MMC"));
|
Serial.println(F("MMC"));
|
||||||
} else if (cardType == CARD_SD) {
|
} else if (cardType == CARD_SD) {
|
||||||
Serial.print(F("SDSC"));
|
Serial.println(F("SDSC"));
|
||||||
} else if (cardType == CARD_SDHC) {
|
} else if (cardType == CARD_SDHC) {
|
||||||
Serial.print(F("SDHC"));
|
Serial.println(F("SDHC"));
|
||||||
} else {
|
} else {
|
||||||
Serial.print(F("UNKNOWN"));
|
Serial.println(F("UNKNOWN"));
|
||||||
}
|
}
|
||||||
|
|
||||||
CardDetected = true;
|
CardDetected = true;
|
||||||
|
|
@ -281,6 +350,70 @@ bool MicroSd::AppendFile(fs::FS &fs, String path, String message) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Added text to end of file
|
||||||
|
@param File - file
|
||||||
|
@param String - message
|
||||||
|
@return bool - status
|
||||||
|
*/
|
||||||
|
bool MicroSd::AppendFile(File *i_file, String *i_msg) {
|
||||||
|
/* take mutex */
|
||||||
|
xSemaphoreTake(sdCardMutex, portMAX_DELAY);
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
/* check if card is corrupted */
|
||||||
|
if (false == isCardCorrupted()) {
|
||||||
|
xSemaphoreGive(sdCardMutex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if card is detected */
|
||||||
|
if (true == CardDetected) {
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
Serial.printf("Appending to file:");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check if file is opened */
|
||||||
|
if (!*i_file) {
|
||||||
|
Serial.println("File not opened");
|
||||||
|
CardDetected = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* write to file */
|
||||||
|
if (i_file->print(i_msg->c_str())) {
|
||||||
|
if (*i_file) {
|
||||||
|
i_file->flush();
|
||||||
|
|
||||||
|
/* check if write was OK */
|
||||||
|
if (!i_file->getWriteError()) {
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
Serial.println("Write OK");
|
||||||
|
#endif
|
||||||
|
status = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Serial.println(F("Failed write to file"));
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println(F("File not opened!"));
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println(F("Failed write to file!"));
|
||||||
|
|
||||||
|
}
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
Serial.println((status == true) ? "Message appended" : "Append Failed");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* give mutex */
|
||||||
|
xSemaphoreGive(sdCardMutex);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Rename file on the SD card
|
@brief Rename file on the SD card
|
||||||
@param fs::FS - card
|
@param fs::FS - card
|
||||||
|
|
@ -465,6 +598,51 @@ void MicroSd::CheckCardUsedStatus() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function to check if card is corrupted
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
bool MicroSd::isCardCorrupted() {
|
||||||
|
bool ret = true;
|
||||||
|
if (true == CardDetected) {
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
//Serial.println(F("Checking card..."));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check card size */
|
||||||
|
uint64_t use = SD_MMC.usedBytes();
|
||||||
|
uint64_t size = 0;
|
||||||
|
if (use != 0) {
|
||||||
|
size = SD_MMC.cardSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (true == CONSOLE_VERBOSE_DEBUG)
|
||||||
|
Serial.printf("Card size: %llu, Used: %llu\n", size, use);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check space on the card */
|
||||||
|
if (size == use) {
|
||||||
|
Serial.println(F("No space left on device!"));
|
||||||
|
CardDetected = false;
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check another error */
|
||||||
|
if ((size <= 0 ) || (size == 0) || (use <= 0) || (use == 0)) {
|
||||||
|
Serial.println(F("No card detected!"));
|
||||||
|
CardDetected = false;
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Write picture to the SD card
|
@brief Write picture to the SD card
|
||||||
@param fs::FS - card
|
@param fs::FS - card
|
||||||
|
|
|
||||||
|
|
@ -21,26 +21,28 @@
|
||||||
D1 4
|
D1 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MICRO_SD_H_
|
#pragma once
|
||||||
#define _MICRO_SD_H_
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include <Arduino.h>
|
||||||
#include "FS.h"
|
#include <FS.h>
|
||||||
#include "SD_MMC.h"
|
#include <SD_MMC.h>
|
||||||
|
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
|
#include "module_templates.h"
|
||||||
#include "var.h"
|
#include "var.h"
|
||||||
|
|
||||||
class MicroSd {
|
class MicroSd {
|
||||||
private:
|
private:
|
||||||
bool CardDetected; ///< Card detected status
|
bool CardDetected; ///< Card detected status
|
||||||
bool DetectAfterBoot; ///< Card detect after boot
|
bool DetectAfterBoot; ///< Card detect after boot
|
||||||
uint32_t CardSizeMB; ///< Card size
|
uint32_t CardSizeMB; ///< Card size
|
||||||
uint32_t CardTotalMB; ///< Card total size
|
uint32_t CardTotalMB; ///< Card total size
|
||||||
uint32_t CardUsedMB; ///< Card used size
|
uint32_t CardUsedMB; ///< Card used size
|
||||||
uint32_t CardFreeMB; ///< Card free size
|
uint32_t CardFreeMB; ///< Card free size
|
||||||
uint8_t FreeSpacePercent; ///< Free space in percent
|
uint8_t FreeSpacePercent; ///< Free space in percent
|
||||||
uint8_t UsedSpacePercent; ///< Used space in percent
|
uint8_t UsedSpacePercent; ///< Used space in percent
|
||||||
|
File file; ///< File object
|
||||||
|
SemaphoreHandle_t sdCardMutex; ///< Mutex for SD card
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MicroSd();
|
MicroSd();
|
||||||
|
|
@ -48,6 +50,9 @@ public:
|
||||||
|
|
||||||
void InitSdCard();
|
void InitSdCard();
|
||||||
void ReinitCard();
|
void ReinitCard();
|
||||||
|
bool OpenFile(File*, String);
|
||||||
|
void CloseFile(File*);
|
||||||
|
bool CheckOpenFile(File*);
|
||||||
|
|
||||||
void ListDir(fs::FS &, String, uint8_t);
|
void ListDir(fs::FS &, String, uint8_t);
|
||||||
bool CheckDir(fs::FS &, String);
|
bool CheckDir(fs::FS &, String);
|
||||||
|
|
@ -56,6 +61,7 @@ public:
|
||||||
void ReadFileConsole(fs::FS &, String);
|
void ReadFileConsole(fs::FS &, String);
|
||||||
bool WriteFile(fs::FS &, String, String);
|
bool WriteFile(fs::FS &, String, String);
|
||||||
bool AppendFile(fs::FS &, String, String);
|
bool AppendFile(fs::FS &, String, String);
|
||||||
|
bool AppendFile(File*, String*);
|
||||||
bool RenameFile(fs::FS &, String, String);
|
bool RenameFile(fs::FS &, String, String);
|
||||||
bool DeleteFile(fs::FS &, String);
|
bool DeleteFile(fs::FS &, String);
|
||||||
uint32_t GetFileSize(fs::FS &, String);
|
uint32_t GetFileSize(fs::FS &, String);
|
||||||
|
|
@ -67,6 +73,7 @@ public:
|
||||||
bool WritePicture(String, uint8_t *, size_t, const uint8_t *, size_t);
|
bool WritePicture(String, uint8_t *, size_t, const uint8_t *, size_t);
|
||||||
|
|
||||||
void CheckCardUsedStatus();
|
void CheckCardUsedStatus();
|
||||||
|
bool isCardCorrupted();
|
||||||
|
|
||||||
bool GetCardDetectedStatus();
|
bool GetCardDetectedStatus();
|
||||||
bool GetCardDetectAfterBoot();
|
bool GetCardDetectAfterBoot();
|
||||||
|
|
@ -79,6 +86,4 @@ public:
|
||||||
uint8_t GetUsedSpacePercent();
|
uint8_t GetUsedSpacePercent();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
@file module_AI_Thinker_ESP32-CAM.h
|
||||||
|
|
||||||
|
@brief Definition of the AI Thinker ESP32-CAM module
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
https://docs.ai-thinker.com/en/esp32-cam
|
||||||
|
|
||||||
|
|
||||||
|
Board configuration in the arduino IDE 2.3.2
|
||||||
|
Tools -> Board -> ESP32 Arduino -> AI Thinker ESP32
|
||||||
|
Tools -> CPU Frequency -> 240MHz (WiFi/BT)
|
||||||
|
Tools -> Core debug level -> None
|
||||||
|
Tools -> Flash frequency -> 80MHz
|
||||||
|
Tools -> Flash Mode -> DIO
|
||||||
|
Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
||||||
|
|
||||||
|
@bug: no know bug
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
|
#ifdef AI_THINKER_ESP32_CAM
|
||||||
|
|
||||||
|
/* --------------- CAMERA CFG -------------------*/
|
||||||
|
#define PWDN_GPIO_NUM 32 ///< Power down control pin
|
||||||
|
#define RESET_GPIO_NUM -1 ///< Reset control pin
|
||||||
|
#define XCLK_GPIO_NUM 0 ///< External clock pin
|
||||||
|
#define SIOD_GPIO_NUM 26 ///< SCCB: SI/O data pin
|
||||||
|
#define SIOC_GPIO_NUM 27 ///< SCCB: SI/O control pin
|
||||||
|
#define Y9_GPIO_NUM 35 ///< SCCB: Y9 pin
|
||||||
|
#define Y8_GPIO_NUM 34 ///< SCCB: Y8 pin
|
||||||
|
#define Y7_GPIO_NUM 39 ///< SCCB: Y7 pin
|
||||||
|
#define Y6_GPIO_NUM 36 ///< SCCB: Y6 pin
|
||||||
|
#define Y5_GPIO_NUM 21 ///< SCCB: Y5 pin
|
||||||
|
#define Y4_GPIO_NUM 19 ///< SCCB: Y4 pin
|
||||||
|
#define Y3_GPIO_NUM 18 ///< SCCB: Y3 pin
|
||||||
|
#define Y2_GPIO_NUM 5 ///< SCCB: Y2 pin
|
||||||
|
#define VSYNC_GPIO_NUM 25 ///< Vertical sync pin
|
||||||
|
#define HREF_GPIO_NUM 23 ///< Line sync pin
|
||||||
|
#define PCLK_GPIO_NUM 22 ///< Pixel clock pin
|
||||||
|
|
||||||
|
/* ------------------ MCU CFG ------------------*/
|
||||||
|
#define BOARD_NAME F("AI Thinker ESP32-CAM") ///< Board name
|
||||||
|
#define ENABLE_BROWN_OUT_DETECTION true ///< Enable brown out detection
|
||||||
|
#define ENABLE_PSRAM true ///< Enable PSRAM
|
||||||
|
|
||||||
|
/* --------------- OTA UPDATE CFG --------------*/
|
||||||
|
#define OTA_UPDATE_FW_FILE PSTR("ESP32_PrusaConnectCam.ino.bin") ///< OTA update firmware file name
|
||||||
|
#define FW_STATUS_LED_PIN 4 ///< GPIO pin for status FW update LED
|
||||||
|
#define FW_STATUS_LED_LEVEL_ON HIGH ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* --------------- FLASH LED CFG ---------------*/
|
||||||
|
#define ENABLE_CAMERA_FLASH true ///< Enable camera flash function
|
||||||
|
#define CAMERA_FLASH_DIGITAL_CTRL false ///< Enable camera flash digital control
|
||||||
|
#define CAMERA_FLASH_PWM_CTRL true ///< Enable camera flash PWM control
|
||||||
|
#define CAMERA_FLASH_NEOPIXEL false ///< Enable camera flash NeoPixel control
|
||||||
|
#define FLASH_GPIO_NUM 4 ///< Flash control pin
|
||||||
|
#define FLASH_NEOPIXEL_LED_PIN -1 ///< External flash control pin. RGB LED NeoPixel
|
||||||
|
#define FLASH_OFF_STATUS 0 ///< PWM intensity LED for OFF. 0-2^FLASH_PWM_RESOLUTION = 0-255
|
||||||
|
#define FLASH_ON_STATUS 205 ///< PWM intensity LED for ON. limitation to 80%. 2^FLASH_PWM_RESOLUTION * 0.8% = 204
|
||||||
|
#define FLASH_PWM_FREQ 2000 ///< frequency of pwm [240MHz / (100 prescale * pwm cycles)] = frequency
|
||||||
|
#define FLASH_PWM_CHANNEL 0 ///< channel 0
|
||||||
|
#define FLASH_PWM_RESOLUTION 8 ///< range 1-20bit. 8bit = 0-255 range
|
||||||
|
|
||||||
|
/* --------------- SD CARD CFG ---------------*/
|
||||||
|
#define ENABLE_SD_CARD true ///< Enable SD card function
|
||||||
|
#define SD_PIN_CLK 14 ///< GPIO pin for SD card clock
|
||||||
|
#define SD_PIN_CMD 15 ///< GPIO pin for SD card command
|
||||||
|
#define SD_PIN_DATA0 2 ///< GPIO pin for SD card data 0
|
||||||
|
|
||||||
|
/* ---------- RESET CFG CONFIGURATION ----------*/
|
||||||
|
#define CFG_RESET_PIN 12 ///< GPIO 12 is for reset CFG to default
|
||||||
|
#define CFG_RESET_LED_PIN 4 ///< GPIO for indication of reset CFG
|
||||||
|
#define CFG_RESET_LED_LEVEL_ON HIGH ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- STATUS LED CFG ----------------*/
|
||||||
|
#define STATUS_LED_ENABLE true ///< enable/disable status LED
|
||||||
|
#define STATUS_LED_GPIO_NUM 33 ///< GPIO pin for status LED
|
||||||
|
#define STATUS_LED_OFF_PIN_LEVEL LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- DHT SENSOR CFG ----------------*/
|
||||||
|
#define DHT_SENSOR_ENABLE true ///< enable/disable DHT sensor
|
||||||
|
#define DHT_SENSOR_PIN 13 ///< GPIO pin for DHT sensor
|
||||||
|
|
||||||
|
#endif // AI_THINKER_ESP32_CAM
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
/**
|
||||||
|
@file module_ESP32-S3-CAM.h
|
||||||
|
|
||||||
|
@brief Definition of the diymore esp32-s3-cam module
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
Board configuration in the arduino IDE 2.3.2
|
||||||
|
Tools -> Board -> ESP32 Arduino -> ESP32S3 Dev Module
|
||||||
|
Tools -> USB CDC on BOOT -> Disable
|
||||||
|
Tools -> CPU Frequency -> 240MHz (WiFi/BT)
|
||||||
|
Tools -> Core debug level -> None
|
||||||
|
Tools -> USB DFU on BOOT -> Disable
|
||||||
|
Tools -> Erase all Flash Before Sketch Upload -> Disable (first flash, new board = enable. otherwise = disable)
|
||||||
|
Tools -> Events Run On -> Core 1
|
||||||
|
Tools -> Flash Mode -> DIO 80MHz
|
||||||
|
Tools -> Flash Size -> 16MB
|
||||||
|
Tools -> Jtag Adapter -> Disable
|
||||||
|
Tools -> Arduino Runs On -> Core 1
|
||||||
|
Tools -> USB Firmware MSC On Boot -> Disable
|
||||||
|
Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
||||||
|
Tools -> PSRAM -> OPI PSRAM
|
||||||
|
Tools -> Upload Mode -> UART0 / Hardware CDC
|
||||||
|
Tools -> Upload Speed -> 921600
|
||||||
|
Tools -> USB Mode -> Hardware CDC and JTAG
|
||||||
|
Tools -> Zigbee mode -> Disable
|
||||||
|
|
||||||
|
@bug:
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
|
#ifdef CAMERA_MODEL_ESP32_S3_CAM
|
||||||
|
|
||||||
|
/* --------------- CAMERA CFG -------------------*/
|
||||||
|
#define PWDN_GPIO_NUM -1 ///< Power down control pin
|
||||||
|
#define RESET_GPIO_NUM -1 ///< Reset control pin
|
||||||
|
#define XCLK_GPIO_NUM 15 ///< External clock pin
|
||||||
|
#define SIOD_GPIO_NUM 4 ///< SCCB: SI/O data pin
|
||||||
|
#define SIOC_GPIO_NUM 5 ///< SCCB: SI/O control pin
|
||||||
|
#define Y9_GPIO_NUM 16 ///< SCCB: Y9 pin
|
||||||
|
#define Y8_GPIO_NUM 17 ///< SCCB: Y8 pin
|
||||||
|
#define Y7_GPIO_NUM 18 ///< SCCB: Y7 pin
|
||||||
|
#define Y6_GPIO_NUM 12 ///< SCCB: Y6 pin
|
||||||
|
#define Y5_GPIO_NUM 10 ///< SCCB: Y5 pin
|
||||||
|
#define Y4_GPIO_NUM 8 ///< SCCB: Y4 pin
|
||||||
|
#define Y3_GPIO_NUM 9 ///< SCCB: Y3 pin
|
||||||
|
#define Y2_GPIO_NUM 11 ///< SCCB: Y2 pin
|
||||||
|
#define VSYNC_GPIO_NUM 6 ///< Vertical sync pin
|
||||||
|
#define HREF_GPIO_NUM 7 ///< Line sync pin
|
||||||
|
#define PCLK_GPIO_NUM 13 ///< Pixel clock pin
|
||||||
|
|
||||||
|
/* ------------------ MCU CFG ------------------*/
|
||||||
|
#define BOARD_NAME F("ESP32-S3-CAM") ///< Board name
|
||||||
|
#define ENABLE_BROWN_OUT_DETECTION false ///< Enable brown out detection
|
||||||
|
#define ENABLE_PSRAM true ///< Enable PSRAM
|
||||||
|
|
||||||
|
/* --------------- OTA UPDATE CFG --------------*/
|
||||||
|
#define OTA_UPDATE_FW_FILE PSTR("esp32-s3-cam.bin") ///< OTA update firmware file name
|
||||||
|
#define FW_STATUS_LED_PIN 2 ///< GPIO pin for status FW update LED
|
||||||
|
#define FW_STATUS_LED_LEVEL_ON HIGH ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* --------------- FLASH LED CFG ---------------*/
|
||||||
|
#define ENABLE_CAMERA_FLASH true ///< Enable camera flash function
|
||||||
|
#define CAMERA_FLASH_DIGITAL_CTRL true ///< Enable camera flash digital control
|
||||||
|
#define CAMERA_FLASH_PWM_CTRL false ///< Enable camera flash PWM control
|
||||||
|
#define CAMERA_FLASH_NEOPIXEL true ///< Enable camera flash NeoPixel control
|
||||||
|
#define FLASH_GPIO_NUM 47 ///< Flash control pin.
|
||||||
|
#define FLASH_NEOPIXEL_LED_PIN 48 ///< External flash control pin. RGB LED NeoPixel
|
||||||
|
#define FLASH_OFF_STATUS LOW ///< value for turn off flash
|
||||||
|
#define FLASH_ON_STATUS HIGH ///< value for turn on flash
|
||||||
|
//#define FLASH_PWM_FREQ 2000 ///< frequency of pwm [240MHz / (100 prescale * pwm cycles)] = frequency
|
||||||
|
//#define FLASH_PWM_CHANNEL 0 ///< channel 0
|
||||||
|
//#define FLASH_PWM_RESOLUTION 8 ///< range 1-20bit. 8bit = 0-255 range
|
||||||
|
|
||||||
|
/* --------------- SD CARD CFG ---------------*/
|
||||||
|
#define ENABLE_SD_CARD true ///< Enable SD card function
|
||||||
|
#define SD_PIN_CLK 39 ///< GPIO pin for SD card clock
|
||||||
|
#define SD_PIN_CMD 38 ///< GPIO pin for SD card command
|
||||||
|
#define SD_PIN_DATA0 40 ///< GPIO pin for SD card data 0
|
||||||
|
|
||||||
|
/* ---------- RESET CFG CONFIGURATION ----------*/
|
||||||
|
#define CFG_RESET_PIN 14 ///< GPIO 16 is for reset CFG to default
|
||||||
|
#define CFG_RESET_LED_PIN 2 ///< GPIO for indication of reset CFG
|
||||||
|
#define CFG_RESET_LED_LEVEL_ON HIGH ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- STATUS LED CFG ----------------*/
|
||||||
|
#define STATUS_LED_ENABLE true ///< enable/disable status LED
|
||||||
|
#define STATUS_LED_GPIO_NUM 2 ///< GPIO pin for status LED
|
||||||
|
#define STATUS_LED_OFF_PIN_LEVEL HIGH ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- DHT SENSOR CFG ----------------*/
|
||||||
|
#define DHT_SENSOR_ENABLE true ///< enable/disable DHT sensor
|
||||||
|
#define DHT_SENSOR_PIN 20 ///< GPIO pin for DHT sensor
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
@file module_ESP32-S3-EYE_2_2.h
|
||||||
|
|
||||||
|
@brief Definition of the ESP32-S3 EYE 2.2 module
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
Board configuration in the arduino IDE 2.3.2
|
||||||
|
Tools -> Board -> ESP32 Arduino -> ESP32S3 Dev Module
|
||||||
|
Tools -> USB CDC on BOOT -> Enabled
|
||||||
|
Tools -> CPU Frequency -> 240MHz (WiFi/BT)
|
||||||
|
Tools -> Core debug level -> None
|
||||||
|
Tools -> USB DFU on BOOT -> Disable
|
||||||
|
Tools -> Erase all Flash Before Sketch Upload -> Disable (first flash, new board = enable. otherwise = disable)
|
||||||
|
Tools -> Events Run On -> Core 0
|
||||||
|
Tools -> Flash Mode -> DIO 80MHz
|
||||||
|
Tools -> Flash Size -> 8MB
|
||||||
|
Tools -> Jtag Adapter -> Disable
|
||||||
|
Tools -> Arduino Runs On -> Core 0
|
||||||
|
Tools -> USB Firmware MSC On Boot -> Disable
|
||||||
|
Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
||||||
|
Tools -> PSRAM -> OPI PSRAM
|
||||||
|
Tools -> Upload Mode -> USB-OTG CDC (TinyUSB)
|
||||||
|
Tools -> Upload Speed -> 921600
|
||||||
|
Tools -> USB Mode -> Hardware CDC and JTAG
|
||||||
|
Tools -> Zigbee mode -> Disable
|
||||||
|
|
||||||
|
https://github.com/espressif/esp-who/blob/master/docs/en/get-started/ESP32-S3-EYE_Getting_Started_Guide.md
|
||||||
|
|
||||||
|
@bug: Currently SW don't work with this DEV board
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
|
#ifdef CAMERA_MODEL_ESP32_S3_EYE_2_2
|
||||||
|
|
||||||
|
/* --------------- CAMERA CFG -------------------*/
|
||||||
|
#define PWDN_GPIO_NUM -1 ///< Power down control pin
|
||||||
|
#define RESET_GPIO_NUM -1 ///< Reset control pin
|
||||||
|
#define SIOD_GPIO_NUM 4 ///< SCCB: SI/O data pin
|
||||||
|
#define SIOC_GPIO_NUM 5 ///< SCCB: SI/O control pin
|
||||||
|
#define Y2_GPIO_NUM 11 ///< SCCB: Y2 pin
|
||||||
|
#define Y3_GPIO_NUM 9 ///< SCCB: Y3 pin
|
||||||
|
#define Y4_GPIO_NUM 8 ///< SCCB: Y4 pin
|
||||||
|
#define Y5_GPIO_NUM 10 ///< SCCB: Y5 pin
|
||||||
|
#define Y6_GPIO_NUM 12 ///< SCCB: Y6 pin
|
||||||
|
#define Y7_GPIO_NUM 18 ///< SCCB: Y7 pin
|
||||||
|
#define Y8_GPIO_NUM 17 ///< SCCB: Y8 pin
|
||||||
|
#define Y9_GPIO_NUM 16 ///< SCCB: Y9 pin
|
||||||
|
#define VSYNC_GPIO_NUM 6 ///< Vertical sync pin
|
||||||
|
#define HREF_GPIO_NUM 7 ///< Line sync pin
|
||||||
|
#define PCLK_GPIO_NUM 13 ///< Pixel clock pin
|
||||||
|
#define XCLK_GPIO_NUM 15 ///< External clock pin
|
||||||
|
|
||||||
|
/* ------------------ MCU CFG ------------------*/
|
||||||
|
#define BOARD_NAME F("ESP32-S3-EYE_2.2") ///< Board name
|
||||||
|
#define ENABLE_BROWN_OUT_DETECTION false ///< Enable brown out detection
|
||||||
|
#define ENABLE_PSRAM true ///< Enable PSRAM
|
||||||
|
|
||||||
|
/* --------------- OTA UPDATE CFG --------------*/
|
||||||
|
#define OTA_UPDATE_FW_FILE PSTR("ESP32S3_EYE22.bin") ///< OTA update firmware file name
|
||||||
|
#define FW_STATUS_LED_PIN 3 ///< GPIO pin for status FW update LED
|
||||||
|
#define FW_STATUS_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* --------------- FLASH LED CFG ---------------*/
|
||||||
|
#define ENABLE_CAMERA_FLASH true ///< Enable camera flash function
|
||||||
|
#define CAMERA_FLASH_DIGITAL_CTRL true ///< Enable camera flash digital control
|
||||||
|
#define CAMERA_FLASH_PWM_CTRL false ///< Enable camera flash PWM control
|
||||||
|
#define CAMERA_FLASH_NEOPIXEL false ///< Enable camera flash NeoPixel control
|
||||||
|
#define FLASH_GPIO_NUM 48 ///< Flash control pin. This is pin for enable LCD backlight
|
||||||
|
#define FLASH_NEOPIXEL_LED_PIN -1 ///< External flash control pin. RGB LED NeoPixel
|
||||||
|
#define FLASH_OFF_STATUS LOW ///< Value for turn off flash
|
||||||
|
#define FLASH_ON_STATUS HIGH ///< Value for turn on flash
|
||||||
|
//#define FLASH_PWM_FREQ 2000 ///< frequency of pwm [240MHz / (100 prescale * pwm cycles)] = frequency
|
||||||
|
//#define FLASH_PWM_CHANNEL 0 ///< channel 0
|
||||||
|
//#define FLASH_PWM_RESOLUTION 8 ///< range 1-20bit. 8bit = 0-255 range
|
||||||
|
|
||||||
|
/* --------------- SD CARD CFG ---------------*/
|
||||||
|
#define ENABLE_SD_CARD true ///< Enable SD card function
|
||||||
|
#define SD_PIN_CLK 39 ///< GPIO pin for SD card clock
|
||||||
|
#define SD_PIN_CMD 38 ///< GPIO pin for SD card command
|
||||||
|
#define SD_PIN_DATA0 40 ///< GPIO pin for SD card data 0
|
||||||
|
|
||||||
|
/* ---------- RESET CFG CONFIGURATION ----------*/
|
||||||
|
#define CFG_RESET_PIN 1 ///< GPIO 1 is for reset CFG to default. This is button UP+`
|
||||||
|
#define CFG_RESET_LED_PIN 3 ///< GPIO for indication of reset CFG
|
||||||
|
#define CFG_RESET_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- STATUS LED CFG ----------------*/
|
||||||
|
#define STATUS_LED_ENABLE true ///< enable/disable status LED
|
||||||
|
#define STATUS_LED_GPIO_NUM 3 ///< GPIO pin for status LED
|
||||||
|
#define STATUS_LED_OFF_PIN_LEVEL HIGH ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- DHT SENSOR CFG ----------------*/
|
||||||
|
#define DHT_SENSOR_ENABLE true ///< enable/disable DHT sensor
|
||||||
|
#define DHT_SENSOR_PIN 46 ///< GPIO pin for DHT sensor
|
||||||
|
|
||||||
|
#endif // CAMERA_MODEL_ESP32_S3_EYE_2_2
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
@file module_ESP32-S3_Wroom_Freenove.h
|
||||||
|
|
||||||
|
@brief Definition of the ESP32-S3 Wroom FreeNove board
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
Board configuration in the arduino IDE 2.3.2
|
||||||
|
Tools -> Board -> ESP32 Arduino -> ESP32S3 Dev Module
|
||||||
|
Tools -> USB CDC on BOOT -> Disabled
|
||||||
|
Tools -> CPU Frequency -> 240MHz (WiFi/BT)
|
||||||
|
Tools -> Core debug level -> None
|
||||||
|
Tools -> USB DFU on BOOT -> Disable
|
||||||
|
Tools -> Erase all Flash Before Sketch Upload -> Disable (first flash, new board = enable. otherwise = disable)
|
||||||
|
Tools -> Events Run On -> Core 0
|
||||||
|
Tools -> Flash Mode -> QIO 80MHz
|
||||||
|
Tools -> Flash Size -> 8MB
|
||||||
|
Tools -> Jtag Adapter -> Disable
|
||||||
|
Tools -> Arduino Runs On -> Core 0
|
||||||
|
Tools -> USB Firmware MSC On Boot -> Disable
|
||||||
|
Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
||||||
|
Tools -> PSRAM -> OPI PSRAM
|
||||||
|
Tools -> Upload Mode -> UART0 / Hardware CDC
|
||||||
|
Tools -> Upload Speed -> 921600
|
||||||
|
Tools -> USB Mode -> Hardware CDC and JTAG
|
||||||
|
Tools -> Zigbee mode -> Disable
|
||||||
|
|
||||||
|
https://freenove.com/fnk0085
|
||||||
|
|
||||||
|
@bug: no know bug
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
|
#ifdef ESP32_S3_WROOM_FREENOVE
|
||||||
|
|
||||||
|
/* --------------- CAMERA CFG -------------------*/
|
||||||
|
#define PWDN_GPIO_NUM -1 ///< Power down control pin
|
||||||
|
#define RESET_GPIO_NUM -1 ///< Reset control pin
|
||||||
|
#define SIOD_GPIO_NUM 4 ///< SCCB: SI/O data pin
|
||||||
|
#define SIOC_GPIO_NUM 5 ///< SCCB: SI/O control pin
|
||||||
|
#define Y2_GPIO_NUM 11 ///< SCCB: Y2 pin
|
||||||
|
#define Y3_GPIO_NUM 9 ///< SCCB: Y3 pin
|
||||||
|
#define Y4_GPIO_NUM 8 ///< SCCB: Y4 pin
|
||||||
|
#define Y5_GPIO_NUM 10 ///< SCCB: Y5 pin
|
||||||
|
#define Y6_GPIO_NUM 12 ///< SCCB: Y6 pin
|
||||||
|
#define Y7_GPIO_NUM 18 ///< SCCB: Y7 pin
|
||||||
|
#define Y8_GPIO_NUM 17 ///< SCCB: Y8 pin
|
||||||
|
#define Y9_GPIO_NUM 16 ///< SCCB: Y9 pin
|
||||||
|
#define VSYNC_GPIO_NUM 6 ///< Vertical sync pin
|
||||||
|
#define HREF_GPIO_NUM 7 ///< Line sync pin
|
||||||
|
#define PCLK_GPIO_NUM 13 ///< Pixel clock pin
|
||||||
|
#define XCLK_GPIO_NUM 15 ///< External clock pin
|
||||||
|
|
||||||
|
/* ------------------ MCU CFG ------------------*/
|
||||||
|
#define BOARD_NAME F("ESP32-S3 WROOM Freenove") ///< Board name
|
||||||
|
#define ENABLE_BROWN_OUT_DETECTION false ///< Enable brown out detection
|
||||||
|
#define ENABLE_PSRAM true ///< Enable PSRAM
|
||||||
|
|
||||||
|
/* --------------- OTA UPDATE CFG --------------*/
|
||||||
|
#define OTA_UPDATE_FW_FILE PSTR("ESP32-S3-WROOM_FREENOVE.bin") ///< OTA update firmware file name
|
||||||
|
#define FW_STATUS_LED_PIN 2 ///< GPIO pin for status FW update LED
|
||||||
|
#define FW_STATUS_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* --------------- FLASH LED CFG ---------------*/
|
||||||
|
#define ENABLE_CAMERA_FLASH true ///< Enable camera flash function
|
||||||
|
#define CAMERA_FLASH_DIGITAL_CTRL true ///< Enable camera flash digital control
|
||||||
|
#define CAMERA_FLASH_PWM_CTRL false ///< Enable camera flash PWM control
|
||||||
|
#define CAMERA_FLASH_NEOPIXEL true ///< Enable camera flash NeoPixel control
|
||||||
|
#define FLASH_GPIO_NUM 14 ///< Flash control pin
|
||||||
|
#define FLASH_NEOPIXEL_LED_PIN 48 ///< External flash control pin. RGB LED NeoPixel
|
||||||
|
#define FLASH_OFF_STATUS 0 ///< PWM intensity LED for OFF. 0-2^FLASH_PWM_RESOLUTION = 0-255
|
||||||
|
#define FLASH_ON_STATUS 205 ///< PWM intensity LED for ON. limitation to 80%. 2^FLASH_PWM_RESOLUTION * 0.8% = 204
|
||||||
|
#define FLASH_PWM_FREQ 2000 ///< frequency of pwm [240MHz / (100 prescale * pwm cycles)] = frequency
|
||||||
|
#define FLASH_PWM_CHANNEL 0 ///< channel 0
|
||||||
|
#define FLASH_PWM_RESOLUTION 8 ///< range 1-20bit. 8bit = 0-255 range
|
||||||
|
|
||||||
|
/* --------------- SD CARD CFG ---------------*/
|
||||||
|
#define ENABLE_SD_CARD true ///< Enable SD card function
|
||||||
|
#define SD_PIN_CLK 39 ///< GPIO pin for SD card clock
|
||||||
|
#define SD_PIN_CMD 38 ///< GPIO pin for SD card command
|
||||||
|
#define SD_PIN_DATA0 40 ///< GPIO pin for SD card data 0
|
||||||
|
|
||||||
|
/* ---------- RESET CFG CONFIGURATION ----------*/
|
||||||
|
#define CFG_RESET_PIN 21 ///< GPIO 12 is for reset CFG to default
|
||||||
|
#define CFG_RESET_LED_PIN 2 ///< GPIO for indication of reset CFG
|
||||||
|
#define CFG_RESET_LED_LEVEL_ON HIGH ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- STATUS LED CFG ----------------*/
|
||||||
|
#define STATUS_LED_ENABLE false ///< enable/disable status LED
|
||||||
|
#define STATUS_LED_GPIO_NUM 2 ///< GPIO pin for status LED
|
||||||
|
#define STATUS_LED_OFF_PIN_LEVEL LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- DHT SENSOR CFG ----------------*/
|
||||||
|
#define DHT_SENSOR_ENABLE false ///< enable/disable DHT sensor
|
||||||
|
#define DHT_SENSOR_PIN 47 ///< GPIO pin for DHT sensor
|
||||||
|
|
||||||
|
#endif // AI_THINKER_ESP32_CAM
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
@file module_ESP32-WROVER-DEV.h
|
||||||
|
|
||||||
|
@brief Definition of the ESP32-WROVER-DEV
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
https://github.com/Freenove/Freenove_ESP32_WROVER_Board
|
||||||
|
|
||||||
|
Board configuration in the arduino IDE 2.3.2
|
||||||
|
Tools -> Board -> ESP32 Arduino -> ESP32 Wrover Module
|
||||||
|
Tools -> CPU Frequency -> 240MHz (WiFi/BT)
|
||||||
|
Tools -> Core debug level -> None
|
||||||
|
Tools -> Flash frequency -> 80MHz
|
||||||
|
Tools -> Flash Mode -> DIO
|
||||||
|
Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
||||||
|
|
||||||
|
@bug: no know bug
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
|
#ifdef ESP32_WROVER_DEV
|
||||||
|
|
||||||
|
/* --------------- CAMERA CFG -------------------*/
|
||||||
|
#define PWDN_GPIO_NUM -1 ///< Power down control pin
|
||||||
|
#define RESET_GPIO_NUM -1 ///< Reset control pin
|
||||||
|
#define XCLK_GPIO_NUM 21 ///< External clock pin
|
||||||
|
#define SIOD_GPIO_NUM 26 ///< SCCB: SI/O data pin
|
||||||
|
#define SIOC_GPIO_NUM 27 ///< SCCB: SI/O control pin
|
||||||
|
#define Y9_GPIO_NUM 35 ///< SCCB: Y9 pin
|
||||||
|
#define Y8_GPIO_NUM 34 ///< SCCB: Y8 pin
|
||||||
|
#define Y7_GPIO_NUM 39 ///< SCCB: Y7 pin
|
||||||
|
#define Y6_GPIO_NUM 36 ///< SCCB: Y6 pin
|
||||||
|
#define Y5_GPIO_NUM 19 ///< SCCB: Y5 pin
|
||||||
|
#define Y4_GPIO_NUM 18 ///< SCCB: Y4 pin
|
||||||
|
#define Y3_GPIO_NUM 5 ///< SCCB: Y3 pin
|
||||||
|
#define Y2_GPIO_NUM 4 ///< SCCB: Y2 pin
|
||||||
|
#define VSYNC_GPIO_NUM 25 ///< Vertical sync pin
|
||||||
|
#define HREF_GPIO_NUM 23 ///< Line sync pin
|
||||||
|
#define PCLK_GPIO_NUM 22 ///< Pixel clock pin
|
||||||
|
|
||||||
|
/* ------------------ MCU CFG ------------------*/
|
||||||
|
#define BOARD_NAME F("ESP32-WROVER-DEV") ///< Board name
|
||||||
|
#define ENABLE_BROWN_OUT_DETECTION true ///< Enable brown out detection
|
||||||
|
#define ENABLE_PSRAM true ///< Enable PSRAM
|
||||||
|
|
||||||
|
/* --------------- OTA UPDATE CFG --------------*/
|
||||||
|
#define OTA_UPDATE_FW_FILE PSTR("ESP32_WROVERDEV.bin") ///< OTA update firmware file name
|
||||||
|
#define FW_STATUS_LED_PIN 2 ///< GPIO pin for status FW update LED
|
||||||
|
#define FW_STATUS_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* --------------- FLASH LED CFG ---------------*/
|
||||||
|
#define ENABLE_CAMERA_FLASH true ///< Enable camera flash function
|
||||||
|
#define CAMERA_FLASH_DIGITAL_CTRL true ///< Enable camera flash digital control
|
||||||
|
#define CAMERA_FLASH_PWM_CTRL false ///< Enable camera flash PWM control
|
||||||
|
#define CAMERA_FLASH_NEOPIXEL false ///< Enable camera flash NeoPixel control
|
||||||
|
#define FLASH_GPIO_NUM 14 ///< Flash control pin
|
||||||
|
#define FLASH_NEOPIXEL_LED_PIN -1 ///< External flash control pin. RGB LED NeoPixel
|
||||||
|
#define FLASH_OFF_STATUS LOW ///< value for flash OFF
|
||||||
|
#define FLASH_ON_STATUS HIGH ///< value for flash ON
|
||||||
|
//#define FLASH_PWM_FREQ 2000 ///< frequency of pwm [240MHz / (100 prescale * pwm cycles)] = frequency
|
||||||
|
//#define FLASH_PWM_CHANNEL 0 ///< channel 0
|
||||||
|
//#define FLASH_PWM_RESOLUTION 8 ///< range 1-20bit. 8bit = 0-255 range
|
||||||
|
|
||||||
|
/* --------------- SD CARD CFG ---------------*/
|
||||||
|
#define ENABLE_SD_CARD false ///< Enable SD card function
|
||||||
|
#define SD_PIN_CLK -1 ///< GPIO pin for SD card clock
|
||||||
|
#define SD_PIN_CMD -1 ///< GPIO pin for SD card command
|
||||||
|
#define SD_PIN_DATA0 -1 ///< GPIO pin for SD card data 0
|
||||||
|
|
||||||
|
/* ---------- RESET CFG CONFIGURATION ----------*/
|
||||||
|
#define CFG_RESET_PIN 12 ///< GPIO 12 is for reset CFG to default
|
||||||
|
#define CFG_RESET_LED_PIN 2 ///< GPIO for indication of reset CFG
|
||||||
|
#define CFG_RESET_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- STATUS LED CFG ----------------*/
|
||||||
|
#define STATUS_LED_ENABLE true ///< enable/disable status LED
|
||||||
|
#define STATUS_LED_GPIO_NUM 2 ///< GPIO pin for status LED
|
||||||
|
#define STATUS_LED_OFF_PIN_LEVEL HIGH ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- DHT SENSOR CFG ----------------*/
|
||||||
|
#define DHT_SENSOR_ENABLE true ///< enable/disable DHT sensor
|
||||||
|
#define DHT_SENSOR_PIN 46 ///< GPIO pin for DHT sensor
|
||||||
|
|
||||||
|
#endif // ESP32_WROVER_DEV
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
/**
|
||||||
|
@file module_ESP32-S3-DEV-CAM.h
|
||||||
|
|
||||||
|
@brief Definition of the ESP32-S3 DEV CAM module
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
Board configuration in the arduino IDE 2.3.2
|
||||||
|
Tools -> Board -> ESP32 Arduino -> ESP32S3 Dev Module
|
||||||
|
Tools -> USB CDC on BOOT -> Enabled
|
||||||
|
Tools -> CPU Frequency -> 160MHz (WiFi/BT)
|
||||||
|
Tools -> Core debug level -> None
|
||||||
|
Tools -> USB DFU on BOOT -> Disable
|
||||||
|
Tools -> Events Run On -> Core 0
|
||||||
|
Tools -> Flash Mode -> DIO 80MHz
|
||||||
|
Tools -> Flash Size -> 16MB
|
||||||
|
Tools -> Jtag Adapter -> Disable
|
||||||
|
Tools -> Arduino Runs On -> Core 0
|
||||||
|
Tools -> USB Firmware MSC On Boot -> Disable
|
||||||
|
Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
||||||
|
Tools -> PSRAM -> OPI PSRAM
|
||||||
|
Tools -> Upload Mode -> USB-OTG CDC (TinyUSB)
|
||||||
|
Tools -> Upload Speed -> 921600
|
||||||
|
Tools -> USB Mode -> Hardware CDC & JTAG
|
||||||
|
Tools -> Zigbee mode -> Disable
|
||||||
|
|
||||||
|
Right USB-C connector is for programming and serial monitor
|
||||||
|
|
||||||
|
@bug: Currently SW don't work with this DEV board. WiFi and MicroSD is not working
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
|
#ifdef CAMERA_MODEL_ESP32_S3_DEV_CAM
|
||||||
|
|
||||||
|
/* --------------- CAMERA CFG -------------------*/
|
||||||
|
#define PWDN_GPIO_NUM -1 ///< Power down control pin
|
||||||
|
#define RESET_GPIO_NUM -1 ///< Reset control pin
|
||||||
|
#define XCLK_GPIO_NUM 10 ///< External clock pin
|
||||||
|
#define SIOD_GPIO_NUM 21 ///< SCCB: SI/O data pin
|
||||||
|
#define SIOC_GPIO_NUM 14 ///< SCCB: SI/O control pin
|
||||||
|
#define Y9_GPIO_NUM 11 ///< SCCB: Y9 pin
|
||||||
|
#define Y8_GPIO_NUM 9 ///< SCCB: Y8 pin
|
||||||
|
#define Y7_GPIO_NUM 8 ///< SCCB: Y7 pin
|
||||||
|
#define Y6_GPIO_NUM 6 ///< SCCB: Y6 pin
|
||||||
|
#define Y5_GPIO_NUM 4 ///< SCCB: Y5 pin
|
||||||
|
#define Y4_GPIO_NUM 2 ///< SCCB: Y4 pin
|
||||||
|
#define Y3_GPIO_NUM 3 ///< SCCB: Y3 pin
|
||||||
|
#define Y2_GPIO_NUM 5 ///< SCCB: Y2 pin
|
||||||
|
#define VSYNC_GPIO_NUM 13 ///< Vertical sync pin
|
||||||
|
#define HREF_GPIO_NUM 12 ///< Line sync pin
|
||||||
|
#define PCLK_GPIO_NUM 7 ///< Pixel clock pin
|
||||||
|
|
||||||
|
/* ------------------ MCU CFG ------------------*/
|
||||||
|
#define BOARD_NAME F("ESP32-S3 DEV CAM") ///< Board name
|
||||||
|
#define ENABLE_BROWN_OUT_DETECTION false ///< Enable brown out detection
|
||||||
|
#define ENABLE_PSRAM true ///< Enable PSRAM
|
||||||
|
|
||||||
|
/* --------------- OTA UPDATE CFG --------------*/
|
||||||
|
#define OTA_UPDATE_FW_FILE PSTR("ESP32S3_DEV_CAM.bin") ///< OTA update firmware file name
|
||||||
|
#define FW_STATUS_LED_PIN 34 ///< GPIO pin for status FW update LED
|
||||||
|
#define FW_STATUS_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* --------------- FLASH LED CFG ---------------*/
|
||||||
|
#define ENABLE_CAMERA_FLASH false ///< Enable camera flash function
|
||||||
|
#define CAMERA_FLASH_DIGITAL_CTRL false ///< Enable camera flash digital control
|
||||||
|
#define CAMERA_FLASH_PWM_CTRL false ///< Enable camera flash PWM control
|
||||||
|
#define CAMERA_FLASH_NEOPIXEL false ///< Enable camera flash NeoPixel control
|
||||||
|
#define FLASH_GPIO_NUM -1 ///< Flash control pin
|
||||||
|
#define FLASH_OFF_STATUS 0 ///< PWM intensity LED for OFF. 0-2^FLASH_PWM_RESOLUTION = 0-255
|
||||||
|
#define FLASH_ON_STATUS 205 ///< PWM intensity LED for ON. limitation to 80%. 2^FLASH_PWM_RESOLUTION * 0.8% = 204
|
||||||
|
#define FLASH_PWM_FREQ 2000 ///< frequency of pwm [240MHz / (100 prescale * pwm cycles)] = frequency
|
||||||
|
#define FLASH_PWM_CHANNEL 0 ///< channel 0
|
||||||
|
#define FLASH_PWM_RESOLUTION 8 ///< range 1-20bit. 8bit = 0-255 range
|
||||||
|
|
||||||
|
/* --------------- SD CARD CFG ---------------*/
|
||||||
|
#define ENABLE_SD_CARD true ///< Enable SD card function
|
||||||
|
#define SD_PIN_CLK 42 ///< GPIO pin for SD card clock
|
||||||
|
#define SD_PIN_CMD 39 ///< GPIO pin for SD card command
|
||||||
|
#define SD_PIN_DATA0 41 ///< GPIO pin for SD card data 0
|
||||||
|
|
||||||
|
/* ---------- RESET CFG CONFIGURATION ----------*/
|
||||||
|
#define CFG_RESET_PIN 2 ///< GPIO 16 is for reset CFG to default
|
||||||
|
#define CFG_RESET_LED_PIN 34 ///< GPIO for indication of reset CFG
|
||||||
|
#define CFG_RESET_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- STATUS LED CFG ----------------*/
|
||||||
|
#define STATUS_LED_ENABLE true ///< enable/disable status LED
|
||||||
|
#define STATUS_LED_GPIO_NUM 34 ///< GPIO pin for status LED
|
||||||
|
#define STATUS_LED_OFF_PIN_LEVEL LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
#endif // CAMERA_MODEL_ESP32_S3_DEV_CAM
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
/**
|
||||||
|
@file module_XIAO_ESP32-S3-cam.h
|
||||||
|
|
||||||
|
@brief Definition of the XIAO ESP32-S3 sense cam
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
https://www.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html
|
||||||
|
https://wiki.seeedstudio.com/xiao_esp32s3_getting_started/
|
||||||
|
https://github.com/limengdu/SeeedStudio-XIAO-ESP32S3-Sense-camera
|
||||||
|
https://github.com/Seeed-Studio/XIAO_Series
|
||||||
|
|
||||||
|
|
||||||
|
Board configuration in the arduino IDE 2.3.2
|
||||||
|
Tools -> Board -> ESP32 Arduino -> XIAO_ESP32S3
|
||||||
|
Tools -> USB CDC on BOOT -> Enabled
|
||||||
|
Tools -> CPU Frequency -> 160MHz (WiFi)
|
||||||
|
Tools -> Core debug level -> None
|
||||||
|
Tools -> USB DFU on BOOT -> Disable
|
||||||
|
Tools -> Erase all Flash Before Sketch Upload -> Disable (first flash, new board = enable. otherwise = disable)
|
||||||
|
Tools -> Events Run On -> Core 1
|
||||||
|
Tools -> Flash Mode -> QIO 80MHz
|
||||||
|
Tools -> Flash Size -> 8MB
|
||||||
|
Tools -> Jtag Adapter -> Disable
|
||||||
|
Tools -> Arduino Runs On -> Core 1
|
||||||
|
Tools -> USB Firmware MSC On Boot -> Disable
|
||||||
|
Tools -> Partition scheme -> 3MB APP/1.5MB SPIFFS
|
||||||
|
Tools -> PSRAM -> OPI PSRAM
|
||||||
|
Tools -> Upload Mode -> UART0 / Hardware CDC
|
||||||
|
Tools -> Upload Speed -> 921600
|
||||||
|
Tools -> USB Mode -> Hardware CDC and JTAG
|
||||||
|
|
||||||
|
@bug:
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
|
#ifdef CAMERA_MODEL_XIAO_ESP32_S3_CAM
|
||||||
|
|
||||||
|
/* --------------- CAMERA CFG -------------------*/
|
||||||
|
#define PWDN_GPIO_NUM -1 ///< Power down control pin
|
||||||
|
#define RESET_GPIO_NUM -1 ///< Reset control pin
|
||||||
|
#define SIOD_GPIO_NUM 40 ///< SCCB: SI/O data pin
|
||||||
|
#define SIOC_GPIO_NUM 39 ///< SCCB: SI/O control pin
|
||||||
|
#define Y2_GPIO_NUM 15 ///< SCCB: Y2 pin
|
||||||
|
#define Y3_GPIO_NUM 17 ///< SCCB: Y3 pin
|
||||||
|
#define Y4_GPIO_NUM 18 ///< SCCB: Y4 pin
|
||||||
|
#define Y5_GPIO_NUM 16 ///< SCCB: Y5 pin
|
||||||
|
#define Y6_GPIO_NUM 14 ///< SCCB: Y6 pin
|
||||||
|
#define Y7_GPIO_NUM 12 ///< SCCB: Y7 pin
|
||||||
|
#define Y8_GPIO_NUM 11 ///< SCCB: Y8 pin
|
||||||
|
#define Y9_GPIO_NUM 48 ///< SCCB: Y9 pin
|
||||||
|
#define VSYNC_GPIO_NUM 38 ///< Vertical sync pin
|
||||||
|
#define HREF_GPIO_NUM 47 ///< Line sync pin
|
||||||
|
#define PCLK_GPIO_NUM 13 ///< Pixel clock pin
|
||||||
|
#define XCLK_GPIO_NUM 10 ///< External clock pin
|
||||||
|
|
||||||
|
/* ------------------ MCU CFG ------------------*/
|
||||||
|
#define BOARD_NAME F("XIAO ESP32-S3 Sense cam") ///< Board name
|
||||||
|
#define ENABLE_BROWN_OUT_DETECTION false ///< Enable brown out detection
|
||||||
|
#define ENABLE_PSRAM true ///< Enable PSRAM
|
||||||
|
|
||||||
|
/* --------------- OTA UPDATE CFG --------------*/
|
||||||
|
#define OTA_UPDATE_FW_FILE PSTR("XIAO_ESP32S3.bin") ///< OTA update firmware file name
|
||||||
|
#define FW_STATUS_LED_PIN 21 ///< GPIO pin for status FW update LED
|
||||||
|
#define FW_STATUS_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* --------------- FLASH LED CFG ---------------*/
|
||||||
|
#define ENABLE_CAMERA_FLASH true ///< Enable camera flash function
|
||||||
|
#define CAMERA_FLASH_DIGITAL_CTRL true ///< Enable camera flash digital control
|
||||||
|
#define CAMERA_FLASH_PWM_CTRL false ///< Enable camera flash PWM control
|
||||||
|
#define CAMERA_FLASH_NEOPIXEL false ///< Enable camera flash NeoPixel control
|
||||||
|
#define FLASH_GPIO_NUM 4 ///< Flash control pin.
|
||||||
|
#define FLASH_NEOPIXEL_LED_PIN -1 ///< External flash control pin. RGB LED NeoPixel
|
||||||
|
#define FLASH_OFF_STATUS LOW ///< value for flash OFF
|
||||||
|
#define FLASH_ON_STATUS HIGH ///< value for flash ON
|
||||||
|
//#define FLASH_PWM_FREQ 2000 ///< frequency of pwm [240MHz / (100 prescale * pwm cycles)] = frequency
|
||||||
|
//#define FLASH_PWM_CHANNEL 0 ///< channel 0
|
||||||
|
//#define FLASH_PWM_RESOLUTION 8 ///< range 1-20bit. 8bit = 0-255 range
|
||||||
|
|
||||||
|
/* --------------- SD CARD CFG ---------------*/
|
||||||
|
#define ENABLE_SD_CARD true ///< Enable SD card function
|
||||||
|
#define SD_PIN_CLK 7 ///< GPIO pin for SD card clock
|
||||||
|
#define SD_PIN_CMD 9 ///< GPIO pin for SD card command
|
||||||
|
#define SD_PIN_DATA0 8 ///< GPIO pin for SD card data 0
|
||||||
|
|
||||||
|
/* ---------- RESET CFG CONFIGURATION ----------*/
|
||||||
|
#define CFG_RESET_PIN 2 ///< GPIO 1 is for reset CFG to default. This is button UP+`
|
||||||
|
#define CFG_RESET_LED_PIN 21 ///< GPIO for indication of reset CFG
|
||||||
|
#define CFG_RESET_LED_LEVEL_ON LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- STATUS LED CFG ----------------*/
|
||||||
|
#define STATUS_LED_ENABLE true ///< enable/disable status LED
|
||||||
|
#define STATUS_LED_GPIO_NUM 21 ///< GPIO pin for status LED
|
||||||
|
#define STATUS_LED_OFF_PIN_LEVEL LOW ///< GPIO pin level for status LED ON
|
||||||
|
|
||||||
|
/* -------------- DHT SENSOR CFG ----------------*/
|
||||||
|
#define DHT_SENSOR_ENABLE true ///< enable/disable DHT sensor
|
||||||
|
#define DHT_SENSOR_PIN 1 ///< GPIO pin for DHT sensor
|
||||||
|
|
||||||
|
#endif // CAMERA_MODEL_XIAO_ESP32_S3_CAM
|
||||||
|
/* EOF */
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
@file module_templates.h
|
||||||
|
|
||||||
|
@brief Definition of the module templates
|
||||||
|
|
||||||
|
@author Miroslav Pivovarsky
|
||||||
|
Contact: miroslav.pivovarsky@gmail.com
|
||||||
|
|
||||||
|
@bug: no know bug
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
|
#if ((AI_THINKER_ESP32_CAM + ESP32_WROVER_DEV + CAMERA_MODEL_ESP32_S3_DEV_CAM + CAMERA_MODEL_ESP32_S3_EYE_2_2 + CAMERA_MODEL_XIAO_ESP32_S3_CAM + CAMERA_MODEL_ESP32_S3_CAM + ESP32_S3_WROOM_FREENOVE) != 1)
|
||||||
|
#error "Exactly one camera model must be defined as true."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (true == AI_THINKER_ESP32_CAM)
|
||||||
|
#include "module_AI_Thinker_ESP32-CAM.h"
|
||||||
|
|
||||||
|
#elif (true == ESP32_WROVER_DEV)
|
||||||
|
#include "module_ESP32-WROVER-DEV.h"
|
||||||
|
|
||||||
|
#elif (true == CAMERA_MODEL_ESP32_S3_DEV_CAM)
|
||||||
|
#include "module_ESP32_S3_DEV_CAM.h"
|
||||||
|
|
||||||
|
#elif (true == CAMERA_MODEL_ESP32_S3_EYE_2_2)
|
||||||
|
#include "module_ESP32-S3-EYE_2_2.h"
|
||||||
|
|
||||||
|
#elif (true == CAMERA_MODEL_XIAO_ESP32_S3_CAM)
|
||||||
|
#include "module_XIAO_ESP32-S3-cam.h"
|
||||||
|
|
||||||
|
#elif (true == CAMERA_MODEL_ESP32_S3_CAM)
|
||||||
|
#include "module_ESP32-S3-CAM.h"
|
||||||
|
|
||||||
|
#elif (true == ESP32_S3_WROOM_FREENOVE)
|
||||||
|
#include "module_ESP32-S3_Wroom_Freenove.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "No module selected"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
@ -139,7 +139,15 @@ String lastTwoChars = command.substring(command.length() - 2);
|
||||||
} else if (command.startsWith("setlight") && command.endsWith(";")) {
|
} else if (command.startsWith("setlight") && command.endsWith(";")) {
|
||||||
cam->SetCameraFlashEnable(false);
|
cam->SetCameraFlashEnable(false);
|
||||||
cam->SetFlashStatus(!cam->GetFlashStatus());
|
cam->SetFlashStatus(!cam->GetFlashStatus());
|
||||||
log->AddEvent(LogLevel_Warning, "--> Console set LIGHT: " + String(cam->GetFlashStatus()));
|
log->AddEvent(LogLevel_Warning, "--> Console set LIGHT: " + String(cam->GetFlashStatus()));
|
||||||
|
|
||||||
|
} else if (command.startsWith("loglevel:") && command.endsWith(";")) {
|
||||||
|
uint8_t level = command.substring(9, command.length() -1).toInt();
|
||||||
|
log->AddEvent(LogLevel_Info, F("--> Console set log level: "), String(level));
|
||||||
|
if ((level >= LogLevel_Error) && (level <= LogLevel_Verbose)) {
|
||||||
|
config->SaveLogLevel((LogLevel_enum) level);
|
||||||
|
log->SetLogLevel((LogLevel_enum) level);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (command.startsWith("mcureboot") && command.endsWith(";")) {
|
} else if (command.startsWith("mcureboot") && command.endsWith(";")) {
|
||||||
log->AddEvent(LogLevel_Warning, F("--> Reboot MCU!"));
|
log->AddEvent(LogLevel_Warning, F("--> Reboot MCU!"));
|
||||||
|
|
@ -186,6 +194,7 @@ void SerialCfg::PrintAvailableCommands() {
|
||||||
Serial.println(F("photoquality:QUALITY; - set photo quality. 10-63 lower number means higher quality "));
|
Serial.println(F("photoquality:QUALITY; - set photo quality. 10-63 lower number means higher quality "));
|
||||||
Serial.println(F("setflash; - enable/disable LED flash"));
|
Serial.println(F("setflash; - enable/disable LED flash"));
|
||||||
Serial.println(F("setlight; - enable/disable LED light"));
|
Serial.println(F("setlight; - enable/disable LED light"));
|
||||||
|
Serial.println(F("loglevel:LEVEL; - set log level. 0=Error, 1=Warning, 2=Info, 3=Verbose"));
|
||||||
Serial.println(F("mcureboot; - reboot MCU"));
|
Serial.println(F("mcureboot; - reboot MCU"));
|
||||||
Serial.println(F("commandslist; - print available commands"));
|
Serial.println(F("commandslist; - print available commands"));
|
||||||
Serial.println(F("-----------------------------------"));
|
Serial.println(F("-----------------------------------"));
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,9 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SERIAL_CFG_H
|
#pragma once
|
||||||
#define _SERIAL_CFG_H
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include <Arduino.h>
|
||||||
|
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
#include "var.h"
|
#include "var.h"
|
||||||
|
|
@ -48,6 +47,4 @@ public:
|
||||||
|
|
||||||
extern SerialCfg SystemSerialCfg; ///< SerialCfg object
|
extern SerialCfg SystemSerialCfg; ///< SerialCfg object
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -45,7 +45,7 @@ sys_led::sys_led(uint8_t i_pin, uint32_t i_on_duration, Logs *i_log) {
|
||||||
*/
|
*/
|
||||||
void sys_led::init() {
|
void sys_led::init() {
|
||||||
pinMode(pin, OUTPUT);
|
pinMode(pin, OUTPUT);
|
||||||
digitalWrite(pin, LOW);
|
digitalWrite(pin, STATUS_LED_OFF_PIN_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -91,7 +91,7 @@ void sys_led::setTimer(uint32_t i_time) {
|
||||||
uint32_t sys_led::getTimer() {
|
uint32_t sys_led::getTimer() {
|
||||||
uint32_t tmp = 0;
|
uint32_t tmp = 0;
|
||||||
|
|
||||||
if (digitalRead(pin) == LOW) {
|
if (digitalRead(pin) == STATUS_LED_OFF_PIN_LEVEL) {
|
||||||
tmp = ledOnDuration;
|
tmp = ledOnDuration;
|
||||||
} else {
|
} else {
|
||||||
tmp = time;
|
tmp = time;
|
||||||
|
|
|
||||||
|
|
@ -9,35 +9,34 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_LED_H_
|
#pragma once
|
||||||
#define _SYS_LED_H_
|
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
#include "arduino.h"
|
|
||||||
|
class Logs;
|
||||||
|
|
||||||
class sys_led {
|
class sys_led {
|
||||||
private:
|
private:
|
||||||
uint8_t pin; ///< pin number for system LED
|
uint8_t pin; ///< pin number for system LED
|
||||||
uint32_t time; ///< speed blinking time system LED
|
uint32_t time; ///< speed blinking time system LED
|
||||||
uint32_t ledOnDuration; ///< duration of LED on
|
uint32_t ledOnDuration; ///< duration of LED on
|
||||||
Logs *log; ///< pointer to log class
|
Logs *log; ///< pointer to log class
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sys_led(uint8_t, uint32_t);
|
sys_led(uint8_t, uint32_t);
|
||||||
sys_led(uint8_t, uint32_t, Logs *);
|
sys_led(uint8_t, uint32_t, Logs *);
|
||||||
~sys_led(){};
|
~sys_led(){};
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void toggle();
|
void toggle();
|
||||||
void set(bool);
|
void set(bool);
|
||||||
bool get();
|
bool get();
|
||||||
void setTimer(uint32_t);
|
void setTimer(uint32_t);
|
||||||
uint32_t getTimer();
|
uint32_t getTimer();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern sys_led system_led;
|
extern sys_led system_led;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -18,6 +18,9 @@
|
||||||
*/
|
*/
|
||||||
void System_Init() {
|
void System_Init() {
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("Init system lib"));
|
SystemLog.AddEvent(LogLevel_Info, F("Init system lib"));
|
||||||
|
SystemLog.AddEvent(LogLevel_Info, "SW Version: " + String(SW_VERSION) + " Build: " + String(SW_BUILD));
|
||||||
|
SystemLog.AddEvent(LogLevel_Info, "Board name: " + String(BOARD_NAME));
|
||||||
|
|
||||||
/* show last reset status */
|
/* show last reset status */
|
||||||
String reason_simple = System_printMcuResetReasonSimple();
|
String reason_simple = System_printMcuResetReasonSimple();
|
||||||
SystemLog.AddEvent(LogLevel_Warning, "CPU reset reason: " + reason_simple);
|
SystemLog.AddEvent(LogLevel_Warning, "CPU reset reason: " + reason_simple);
|
||||||
|
|
@ -28,10 +31,12 @@ void System_Init() {
|
||||||
SystemLog.AddEvent(LogLevel_Warning, "CPU1 reset reason: " + reason_core1);
|
SystemLog.AddEvent(LogLevel_Warning, "CPU1 reset reason: " + reason_core1);
|
||||||
|
|
||||||
SystemLog.AddEvent(LogLevel_Info, "MCU Temperature: " + String(temperatureRead()) + " *C");
|
SystemLog.AddEvent(LogLevel_Info, "MCU Temperature: " + String(temperatureRead()) + " *C");
|
||||||
SystemLog.AddEvent(LogLevel_Info, "Internal Total heap: " + String(ESP.getHeapSize()) + " ,internal Free Heap: " + String(ESP.getFreeHeap()));
|
SystemLog.AddEvent(LogLevel_Info, "Internal Total heap: " + String(ESP.getHeapSize()) + " B, Internal Free Heap: " + String(ESP.getFreeHeap()));
|
||||||
SystemLog.AddEvent(LogLevel_Info, "SPIRam Total heap: " + String(ESP.getPsramSize()) + " ,SPIRam Free Heap: " + String(ESP.getFreePsram()));
|
SystemLog.AddEvent(LogLevel_Info, "PSRAM Total heap: " + String(ESP.getPsramSize()) + " B, PSRAM Free Heap: " + String(ESP.getFreePsram()));
|
||||||
SystemLog.AddEvent(LogLevel_Info, "ChipRevision: " + String(ESP.getChipRevision()) + " ,Cpu Freq: " + String(ESP.getCpuFreqMHz()) + " ,SDK Version: " + String(ESP.getSdkVersion()));
|
SystemLog.AddEvent(LogLevel_Info, "Chip model: " + String(ESP.getChipModel()) + ", ChipRevision: " + String(ESP.getChipRevision()) + ", Cpu Freq: " + String(ESP.getCpuFreqMHz()));
|
||||||
SystemLog.AddEvent(LogLevel_Info, "Flash Size: " + String(ESP.getFlashChipSize()) + " ,Flash Speed " + String(ESP.getFlashChipSpeed()));
|
SystemLog.AddEvent(LogLevel_Info, "SDK Version: " + String(ESP.getSdkVersion()) + ", Core Version: " + String(ESP.getCoreVersion()));
|
||||||
|
SystemLog.AddEvent(LogLevel_Info, "Flash Size: " + String(ESP.getFlashChipSize()) + ", Flash Speed " + String(ESP.getFlashChipSpeed()) + ", Flash Mode: " + String(ESP.getFlashChipMode()));
|
||||||
|
|
||||||
System_CheckIfPsramIsUsed();
|
System_CheckIfPsramIsUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,9 +54,11 @@ void System_LoadCfg() {
|
||||||
@param none
|
@param none
|
||||||
@return none
|
@return none
|
||||||
*/
|
*/
|
||||||
void System_CheckIfPsramIsUsed() {
|
bool System_CheckIfPsramIsUsed() {
|
||||||
|
bool ret = false;
|
||||||
if (psramFound()) {
|
if (psramFound()) {
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("PSRAM is used."));
|
SystemLog.AddEvent(LogLevel_Info, F("PSRAM is used."));
|
||||||
|
ret = true;
|
||||||
void *ptr = malloc(100);
|
void *ptr = malloc(100);
|
||||||
|
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
|
|
@ -67,6 +74,8 @@ void System_CheckIfPsramIsUsed() {
|
||||||
} else {
|
} else {
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("PSRAM is not used."));
|
SystemLog.AddEvent(LogLevel_Info, F("PSRAM is not used."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -78,12 +87,13 @@ void System_UpdateInit() {
|
||||||
Update.onProgress([](int progress, size_t total) {
|
Update.onProgress([](int progress, size_t total) {
|
||||||
/* update from file */
|
/* update from file */
|
||||||
SystemCamera.SetFlashStatus(true);
|
SystemCamera.SetFlashStatus(true);
|
||||||
|
digitalWrite(FW_STATUS_LED_PIN, FW_STATUS_LED_LEVEL_ON);
|
||||||
uint8_t updateProgress = (progress * 100) / FirmwareUpdate.FirmwareSize;
|
uint8_t updateProgress = (progress * 100) / FirmwareUpdate.FirmwareSize;
|
||||||
SystemLog.AddEvent(LogLevel_Info, "Updating: " + String(FirmwareUpdate.FirmwareSize) + "/" + String(progress) + " -> " + String(updateProgress) + "%");
|
SystemLog.AddEvent(LogLevel_Info, "Updating: " + String(FirmwareUpdate.FirmwareSize) + "/" + String(progress) + " -> " + String(updateProgress) + "%");
|
||||||
FirmwareUpdate.PercentProcess = updateProgress;
|
FirmwareUpdate.PercentProcess = updateProgress;
|
||||||
FirmwareUpdate.TransferedBytes = progress;
|
FirmwareUpdate.TransferedBytes = progress;
|
||||||
delay(10);
|
delay(10);
|
||||||
SystemCamera.SetFlashStatus(false);
|
digitalWrite(FW_STATUS_LED_PIN, !FW_STATUS_LED_LEVEL_ON);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,7 +262,7 @@ bool System_OtaUpdateStart() {
|
||||||
/* mcu configuration */
|
/* mcu configuration */
|
||||||
httpUpdate.rebootOnUpdate(false);
|
httpUpdate.rebootOnUpdate(false);
|
||||||
FirmwareUpdate.UpdatingStatus = SYSTEM_MSG_UPDATE_PROCESS;
|
FirmwareUpdate.UpdatingStatus = SYSTEM_MSG_UPDATE_PROCESS;
|
||||||
httpUpdate.setLedPin(4, HIGH);
|
httpUpdate.setLedPin(FW_STATUS_LED_PIN, FW_STATUS_LED_LEVEL_ON);
|
||||||
|
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("Start OTA update URL: "), FirmwareUpdate.OtaUpdateFwUrl + ";");
|
SystemLog.AddEvent(LogLevel_Info, F("Start OTA update URL: "), FirmwareUpdate.OtaUpdateFwUrl + ";");
|
||||||
|
|
||||||
|
|
@ -445,13 +455,11 @@ void System_TaskWifiManagement(void *pvParameters) {
|
||||||
while (1) {
|
while (1) {
|
||||||
/* wifi management. Enable/disable AP_STA mode and STA mode*/
|
/* wifi management. Enable/disable AP_STA mode and STA mode*/
|
||||||
SystemWifiMngt.WifiManagement();
|
SystemWifiMngt.WifiManagement();
|
||||||
|
McuTemperature.TemperatureCelsius = temperatureRead();
|
||||||
|
|
||||||
/* wifi reconnect after signal lost */
|
/* wifi reconnect after signal lost */
|
||||||
SystemWifiMngt.WiFiReconnect();
|
SystemWifiMngt.WiFiReconnect();
|
||||||
SystemLog.AddEvent(LogLevel_Info, "Free RAM: " + String(ESP.getFreeHeap()) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, F("WiFiManagement task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
SystemLog.AddEvent(LogLevel_Info, "Free SPIRAM: " + String(ESP.getFreePsram()) + " bytes");
|
|
||||||
SystemLog.AddEvent(LogLevel_Info, "Temperature: " + String(temperatureRead()) + " *C");
|
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WiFiManagement task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WiFi status: "), String(WiFi.status()));
|
SystemLog.AddEvent(LogLevel_Verbose, F("WiFi status: "), String(WiFi.status()));
|
||||||
|
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
|
|
@ -476,7 +484,7 @@ void System_TaskMain(void *pvParameters) {
|
||||||
/* for ota update */
|
/* for ota update */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
System_Main();
|
System_Main();
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("System task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, F("System task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
|
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
@ -518,7 +526,7 @@ void System_TaskCaptureAndSendPhoto(void *pvParameters) {
|
||||||
Connect.IncreaseSendingIntervalCounter();
|
Connect.IncreaseSendingIntervalCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("Photo processing task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, F("Photo processing task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
|
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
@ -542,7 +550,9 @@ void System_TaskSdCardCheck(void *pvParameters) {
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
/* check micro SD card */
|
/* check micro SD card */
|
||||||
if ((true == SystemLog.GetCardDetectAfterBoot()) && (false == SystemLog.GetCardDetectedStatus())) {
|
if ((true == SystemLog.GetCardDetectAfterBoot()) && (false == SystemLog.GetCardDetectedStatus())) {
|
||||||
|
SystemLog.LogCloseFile();
|
||||||
SystemLog.ReinitCard();
|
SystemLog.ReinitCard();
|
||||||
|
SystemLog.LogOpenFile();
|
||||||
SystemLog.AddEvent(LogLevel_Warning, F("Reinit micro SD card done!"));
|
SystemLog.AddEvent(LogLevel_Warning, F("Reinit micro SD card done!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,7 +568,17 @@ void System_TaskSdCardCheck(void *pvParameters) {
|
||||||
SystemLog.CheckMaxLogFileSize();
|
SystemLog.CheckMaxLogFileSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("MicroSdCard task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
/* check if log file is opened */
|
||||||
|
if (true == SystemLog.GetCardDetectedStatus()) {
|
||||||
|
SystemLog.LogCheckOpenedFile();
|
||||||
|
if (false == SystemLog.GetLogFileOpened()) {
|
||||||
|
SystemLog.LogOpenFile();
|
||||||
|
SystemLog.AddEvent(LogLevel_Warning, F("Log file is not opened!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemLog.AddEvent(LogLevel_Info, "CardStatus: " + String(SystemLog.GetCardDetectedStatus()) + " FileStatus: " + String(SystemLog.GetLogFileOpened()));
|
||||||
|
SystemLog.AddEvent(LogLevel_Verbose, F("MicroSdCard task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
|
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
@ -581,7 +601,7 @@ void System_TaskSerialCfg(void *pvParameters) {
|
||||||
while (1) {
|
while (1) {
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
SystemSerialCfg.ProcessIncommingData();
|
SystemSerialCfg.ProcessIncommingData();
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("SerialCfg task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, F("SerialCfg task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
|
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
@ -592,30 +612,36 @@ void System_TaskSerialCfg(void *pvParameters) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function for stream telemetry task
|
* @brief Function for system telemetry task
|
||||||
*
|
*
|
||||||
* @param void *pvParameters
|
* @param void *pvParameters
|
||||||
* @return none
|
* @return none
|
||||||
*/
|
*/
|
||||||
void System_TaskStreamTelemetry(void *pvParameters) {
|
void System_TaskSystemTelemetry(void *pvParameters) {
|
||||||
SystemLog.AddEvent(LogLevel_Info, F("StreamTelemetry task. core: "), String(xPortGetCoreID()));
|
SystemLog.AddEvent(LogLevel_Info, F("SystemTelemetry task. core: "), String(xPortGetCoreID()));
|
||||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("StreamTelemetry task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, F("SystemTelemetry task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
if (SystemCamera.GetStreamStatus()) {
|
if (SystemCamera.GetStreamStatus()) {
|
||||||
char buf[80] = { '\0' };
|
char buf[80] = { '\0' };
|
||||||
sprintf(buf, "Stream, average data in %dsec. FPS: %.1f, Size: %uKB", (TASK_STREAM_TELEMETRY / SECOND_TO_MILISECOND), SystemCamera.StreamGetFrameAverageFps(), SystemCamera.StreamGetFrameAverageSize());
|
sprintf(buf, "Stream, average data in %dsec. FPS: %.1f, Size: %uKB", (TASK_SYSTEM_TELEMETRY / SECOND_TO_MILISECOND), SystemCamera.StreamGetFrameAverageFps(), SystemCamera.StreamGetFrameAverageSize());
|
||||||
SystemLog.AddEvent(LogLevel_Info, buf);
|
SystemLog.AddEvent(LogLevel_Info, buf);
|
||||||
SystemCamera.StreamClearFrameData();
|
SystemCamera.StreamClearFrameData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemLog.AddEvent(LogLevel_Info, "Free RAM: " + String(ESP.getFreeHeap()) + " B" + ", Min: " + String(ESP.getMinFreeHeap()));
|
||||||
|
SystemLog.AddEvent(LogLevel_Info, "Free PSRAM: " + String(ESP.getFreePsram()) + " B" + ", Min: " + String(ESP.getMinFreePsram()));
|
||||||
|
SystemLog.AddEvent(LogLevel_Info, "MCU Temperature: " + String(McuTemperature.TemperatureCelsius) + " *C");
|
||||||
|
|
||||||
|
ExternalTemperatureSensor.ReadSensorData();
|
||||||
|
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
||||||
/* next start task */
|
/* next start task */
|
||||||
vTaskDelayUntil(&xLastWakeTime, TASK_STREAM_TELEMETRY / portTICK_PERIOD_MS);
|
vTaskDelayUntil(&xLastWakeTime, TASK_SYSTEM_TELEMETRY / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -633,7 +659,7 @@ void System_TaskSysLed(void *pvParameters) {
|
||||||
system_led.toggle();
|
system_led.toggle();
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("SystemLed task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, F("SystemLed task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
|
|
||||||
/* next start task */
|
/* next start task */
|
||||||
vTaskDelayUntil(&xLastWakeTime, system_led.getTimer() / portTICK_PERIOD_MS);
|
vTaskDelayUntil(&xLastWakeTime, system_led.getTimer() / portTICK_PERIOD_MS);
|
||||||
|
|
@ -653,7 +679,7 @@ void System_TaskWiFiWatchdog(void *pvParameters) {
|
||||||
while (1) {
|
while (1) {
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
SystemWifiMngt.WiFiWatchdog();
|
SystemWifiMngt.WiFiWatchdog();
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("WiFiWatchdog task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, F("WiFiWatchdog task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
|
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
@ -693,7 +719,7 @@ void System_TaskSdCardRemove(void *pvParameters) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemLog.AddEvent(LogLevel_Verbose, F("MicroSdCard task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + " bytes");
|
SystemLog.AddEvent(LogLevel_Verbose, F("MicroSdCard task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
|
||||||
|
|
||||||
/* reset wdg */
|
/* reset wdg */
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
|
||||||
|
|
@ -9,20 +9,26 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYSTEM_H_
|
#pragma once
|
||||||
#define _SYSTEM_H_
|
|
||||||
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <Update.h>
|
#include <Update.h>
|
||||||
#include "Arduino.h"
|
#include <Arduino.h>
|
||||||
#include <WiFiClientSecure.h>
|
#include <WiFiClientSecure.h>
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#include <HTTPUpdate.h>
|
#include <HTTPUpdate.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
#include "esp32/rom/rtc.h"
|
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
|
#include "esp32/rom/rtc.h"
|
||||||
|
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
|
#include "esp32s3/rom/rtc.h"
|
||||||
|
#else
|
||||||
|
#error "Unsupported chip target"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
#include "var.h"
|
#include "var.h"
|
||||||
#include "cfg.h"
|
#include "cfg.h"
|
||||||
|
|
@ -32,6 +38,7 @@
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "serial_cfg.h"
|
#include "serial_cfg.h"
|
||||||
#include "sys_led.h"
|
#include "sys_led.h"
|
||||||
|
#include "ExternalTemperatureSensor.h"
|
||||||
|
|
||||||
#define SYSTEM_MSG_UPDATE_DONE F("FW update successfully done! Please reboot the MCU.")
|
#define SYSTEM_MSG_UPDATE_DONE F("FW update successfully done! Please reboot the MCU.")
|
||||||
#define SYSTEM_MSG_UPDATE_FAIL F("FW update failed! Please reboot MCU, and try again.")
|
#define SYSTEM_MSG_UPDATE_FAIL F("FW update failed! Please reboot MCU, and try again.")
|
||||||
|
|
@ -40,7 +47,7 @@
|
||||||
|
|
||||||
void System_Init();
|
void System_Init();
|
||||||
void System_LoadCfg();
|
void System_LoadCfg();
|
||||||
void System_CheckIfPsramIsUsed();
|
bool System_CheckIfPsramIsUsed();
|
||||||
void System_Main();
|
void System_Main();
|
||||||
void System_UpdateInit();
|
void System_UpdateInit();
|
||||||
|
|
||||||
|
|
@ -60,10 +67,9 @@ void System_TaskMain(void *);
|
||||||
void System_TaskCaptureAndSendPhoto(void *);
|
void System_TaskCaptureAndSendPhoto(void *);
|
||||||
void System_TaskSdCardCheck(void *);
|
void System_TaskSdCardCheck(void *);
|
||||||
void System_TaskSerialCfg(void *);
|
void System_TaskSerialCfg(void *);
|
||||||
void System_TaskStreamTelemetry(void *);
|
void System_TaskSystemTelemetry(void *);
|
||||||
void System_TaskSysLed(void *);
|
void System_TaskSysLed(void *);
|
||||||
void System_TaskWiFiWatchdog(void *);
|
void System_TaskWiFiWatchdog(void *);
|
||||||
void System_TaskSdCardRemove(void *);
|
void System_TaskSdCardRemove(void *);
|
||||||
|
|
||||||
#endif
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -13,13 +13,14 @@
|
||||||
|
|
||||||
WebBasicAuth_struct WebBasicAuth = { false, "", "" };
|
WebBasicAuth_struct WebBasicAuth = { false, "", "" };
|
||||||
struct FirmwareUpdate_struct FirmwareUpdate = { "Ready", false, 0, 0, 0, false, false, "", "", "", false };
|
struct FirmwareUpdate_struct FirmwareUpdate = { "Ready", false, 0, 0, 0, false, false, "", "", "", false };
|
||||||
|
struct McuTemperature_struct McuTemperature = {0.0};
|
||||||
|
|
||||||
TaskHandle_t Task_CapturePhotoAndSend;
|
TaskHandle_t Task_CapturePhotoAndSend;
|
||||||
TaskHandle_t Task_WiFiManagement;
|
TaskHandle_t Task_WiFiManagement;
|
||||||
TaskHandle_t Task_SystemMain;
|
TaskHandle_t Task_SystemMain;
|
||||||
TaskHandle_t Task_SdCardCheck;
|
TaskHandle_t Task_SdCardCheck;
|
||||||
TaskHandle_t Task_SerialCfg;
|
TaskHandle_t Task_SerialCfg;
|
||||||
TaskHandle_t Task_StreamTelemetry;
|
TaskHandle_t Task_SystemTelemetry;
|
||||||
TaskHandle_t Task_SysLed;
|
TaskHandle_t Task_SysLed;
|
||||||
TaskHandle_t Task_WiFiWatchdog;
|
TaskHandle_t Task_WiFiWatchdog;
|
||||||
//TaskHandle_t Task_SdCardFileRemove;
|
//TaskHandle_t Task_SdCardFileRemove;
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,9 @@
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _VARIABLE_H_
|
#pragma once
|
||||||
#define _VARIABLE_H_
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include <Arduino.h>
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
|
|
||||||
struct WebBasicAuth_struct {
|
struct WebBasicAuth_struct {
|
||||||
|
|
@ -37,15 +36,20 @@ struct FirmwareUpdate_struct {
|
||||||
bool OtaUpdateFwAvailable; ///< flag for available new FW version
|
bool OtaUpdateFwAvailable; ///< flag for available new FW version
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct McuTemperature_struct {
|
||||||
|
float TemperatureCelsius; ///< MCU temperature
|
||||||
|
};
|
||||||
|
|
||||||
extern struct WebBasicAuth_struct WebBasicAuth; ///< structure with configuration for basic auth
|
extern struct WebBasicAuth_struct WebBasicAuth; ///< structure with configuration for basic auth
|
||||||
extern struct FirmwareUpdate_struct FirmwareUpdate; ///< firmware update status and process
|
extern struct FirmwareUpdate_struct FirmwareUpdate; ///< firmware update status and process
|
||||||
|
extern struct McuTemperature_struct McuTemperature; ///< MCU temperature
|
||||||
|
|
||||||
extern TaskHandle_t Task_CapturePhotoAndSend; ///< task handle for capture photo and send
|
extern TaskHandle_t Task_CapturePhotoAndSend; ///< task handle for capture photo and send
|
||||||
extern TaskHandle_t Task_WiFiManagement; ///< task handle for wifi management
|
extern TaskHandle_t Task_WiFiManagement; ///< task handle for wifi management
|
||||||
extern TaskHandle_t Task_SystemMain; ///< task handle for system main
|
extern TaskHandle_t Task_SystemMain; ///< task handle for system main
|
||||||
extern TaskHandle_t Task_SdCardCheck; ///< task handle for sd card check
|
extern TaskHandle_t Task_SdCardCheck; ///< task handle for sd card check
|
||||||
extern TaskHandle_t Task_SerialCfg; ///< task handle for serial configuration
|
extern TaskHandle_t Task_SerialCfg; ///< task handle for serial configuration
|
||||||
extern TaskHandle_t Task_StreamTelemetry; ///< task handle for stream telemetry
|
extern TaskHandle_t Task_SystemTelemetry; ///< task handle for system telemetry
|
||||||
extern TaskHandle_t Task_SysLed; ///< task handle for system led
|
extern TaskHandle_t Task_SysLed; ///< task handle for system led
|
||||||
extern TaskHandle_t Task_WiFiWatchdog; ///< task handle for wifi watchdog
|
extern TaskHandle_t Task_WiFiWatchdog; ///< task handle for wifi watchdog
|
||||||
//extern TaskHandle_t Task_SdCardFileRemove; ///< task handle for remove file from sd card
|
//extern TaskHandle_t Task_SdCardFileRemove; ///< task handle for remove file from sd card
|
||||||
|
|
@ -53,6 +57,4 @@ extern TaskHandle_t Task_WiFiWatchdog; ///< task handle for wifi w
|
||||||
extern uint8_t StartRemoveSdCard;
|
extern uint8_t StartRemoveSdCard;
|
||||||
extern uint32_t SdCardRemoveTime;
|
extern uint32_t SdCardRemoveTime;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
@ -61,7 +61,6 @@ void WiFiMngt::LoadCfgFromEeprom() {
|
||||||
void WiFiMngt::Init() {
|
void WiFiMngt::Init() {
|
||||||
/* check WI-FI mode */
|
/* check WI-FI mode */
|
||||||
system_led.setTimer(STATUS_LED_WIFI_AP);
|
system_led.setTimer(STATUS_LED_WIFI_AP);
|
||||||
log->AddEvent(LogLevel_Info, "WiFi MAC: " + WiFi.macAddress());
|
|
||||||
|
|
||||||
/* Set Wi-Fi networks */
|
/* Set Wi-Fi networks */
|
||||||
SetWifiEvents();
|
SetWifiEvents();
|
||||||
|
|
@ -93,6 +92,7 @@ void WiFiMngt::Init() {
|
||||||
} else {
|
} else {
|
||||||
log->AddEvent(LogLevel_Info, F("STA IP Method: DHCP"));
|
log->AddEvent(LogLevel_Info, F("STA IP Method: DHCP"));
|
||||||
}
|
}
|
||||||
|
log->AddEvent(LogLevel_Info, "WiFi MAC: " + WiFi.macAddress());
|
||||||
|
|
||||||
esp_wifi_set_ps(WIFI_PS_NONE);
|
esp_wifi_set_ps(WIFI_PS_NONE);
|
||||||
WiFi.setHostname(DEVICE_HOSTNAME);
|
WiFi.setHostname(DEVICE_HOSTNAME);
|
||||||
|
|
@ -230,12 +230,24 @@ void WiFiMngt::WiFiStaConnect() {
|
||||||
if (config->CheckActifeWifiCfgFlag() == true) {
|
if (config->CheckActifeWifiCfgFlag() == true) {
|
||||||
system_led.setTimer(STATUS_LED_STA_CONNECTING);
|
system_led.setTimer(STATUS_LED_STA_CONNECTING);
|
||||||
if (false == WiFiStaMultipleNetwork) {
|
if (false == WiFiStaMultipleNetwork) {
|
||||||
|
|
||||||
|
#if (WIFI_DISABLE_UNENCRYPTED_STA_PASS_CHECK == true)
|
||||||
|
if (WifiPassword == "") {
|
||||||
|
WiFi.begin(WifiSsid);
|
||||||
|
log->AddEvent(LogLevel_Info, F("Connecting to STA SSID without password"));
|
||||||
|
} else {
|
||||||
|
WiFi.begin(WifiSsid, WifiPassword);
|
||||||
|
}
|
||||||
|
#else
|
||||||
WiFi.begin(WifiSsid, WifiPassword);
|
WiFi.begin(WifiSsid, WifiPassword);
|
||||||
|
#endif
|
||||||
|
|
||||||
log->AddEvent(LogLevel_Info, F("Connecting to STA SSID"));
|
log->AddEvent(LogLevel_Info, F("Connecting to STA SSID"));
|
||||||
} else if (true == WiFiStaMultipleNetwork) {
|
} else if (true == WiFiStaMultipleNetwork) {
|
||||||
WiFi.begin(WifiSsid, WifiPassword, 0, WiFiStaNetworkBssid);
|
WiFi.begin(WifiSsid, WifiPassword, 0, WiFiStaNetworkBssid);
|
||||||
log->AddEvent(LogLevel_Info, F("Connecting to STA BSSID"));
|
log->AddEvent(LogLevel_Info, F("Connecting to STA BSSID"));
|
||||||
}
|
}
|
||||||
|
WiFi.setSleep(false);
|
||||||
WiFi.setAutoReconnect(true);
|
WiFi.setAutoReconnect(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -303,8 +315,10 @@ uint8_t WiFiMngt::ScanWifiNetwork(String ssid) {
|
||||||
WifiScanJson = "";
|
WifiScanJson = "";
|
||||||
|
|
||||||
/* make json with each found WI-FI networks */
|
/* make json with each found WI-FI networks */
|
||||||
if (n == 0) {
|
if (n <= 0) {
|
||||||
log->AddEvent(LogLevel_Info, F("No networks found!"));
|
log->AddEvent(LogLevel_Info, "No networks found! [" + String(n) + "]");
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log->AddEvent(LogLevel_Info, String(n) + " networks found");
|
log->AddEvent(LogLevel_Info, String(n) + " networks found");
|
||||||
log->AddEvent(LogLevel_Info, F("Nr | SSID | RSSI | CH | BSSID | Encryption"));
|
log->AddEvent(LogLevel_Info, F("Nr | SSID | RSSI | CH | BSSID | Encryption"));
|
||||||
|
|
@ -332,7 +346,7 @@ uint8_t WiFiMngt::ScanWifiNetwork(String ssid) {
|
||||||
|
|
||||||
// Print SSID and RSSI for each network found
|
// Print SSID and RSSI for each network found
|
||||||
char formattedString[100] = { '\0' };
|
char formattedString[100] = { '\0' };
|
||||||
sprintf(formattedString, "%2d | %-32.32s | %4d | %2d | %-17s | %s", i + 1,
|
sprintf(formattedString, "%2d | %-32.32s | %4ld | %2ld | %-17s | %s", i + 1,
|
||||||
WiFi.SSID(i).c_str(), WiFi.RSSI(i), WiFi.channel(i), WiFi.BSSIDstr(i).c_str(), TranslateWiFiEncrypion(WiFi.encryptionType(i)).c_str());
|
WiFi.SSID(i).c_str(), WiFi.RSSI(i), WiFi.channel(i), WiFi.BSSIDstr(i).c_str(), TranslateWiFiEncrypion(WiFi.encryptionType(i)).c_str());
|
||||||
log->AddEvent(LogLevel_Info, formattedString);
|
log->AddEvent(LogLevel_Info, formattedString);
|
||||||
}
|
}
|
||||||
|
|
@ -344,7 +358,7 @@ uint8_t WiFiMngt::ScanWifiNetwork(String ssid) {
|
||||||
log->AddEvent(LogLevel_Verbose, WifiScanJson);
|
log->AddEvent(LogLevel_Verbose, WifiScanJson);
|
||||||
|
|
||||||
/* print status */
|
/* print status */
|
||||||
if (1 <= ret) {
|
if (ret >= 1) {
|
||||||
log->AddEvent(LogLevel_Info, "SSID: " + ssid + " found, " + String(ret) + "x");
|
log->AddEvent(LogLevel_Info, "SSID: " + ssid + " found, " + String(ret) + "x");
|
||||||
if (1 < ret) {
|
if (1 < ret) {
|
||||||
memcpy(WiFiStaNetworkBssid, bssid, 6);
|
memcpy(WiFiStaNetworkBssid, bssid, 6);
|
||||||
|
|
@ -353,8 +367,10 @@ uint8_t WiFiMngt::ScanWifiNetwork(String ssid) {
|
||||||
sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", WiFiStaNetworkBssid[0], WiFiStaNetworkBssid[1], WiFiStaNetworkBssid[2], WiFiStaNetworkBssid[3], WiFiStaNetworkBssid[4], WiFiStaNetworkBssid[5]);
|
sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", WiFiStaNetworkBssid[0], WiFiStaNetworkBssid[1], WiFiStaNetworkBssid[2], WiFiStaNetworkBssid[3], WiFiStaNetworkBssid[4], WiFiStaNetworkBssid[5]);
|
||||||
log->AddEvent(LogLevel_Info, "WiFi roaming found! Connecting to " + String(mac) + " -> " + String(bestSignal) + "dBm, " + String(WiFiStaMultipleNetwork));
|
log->AddEvent(LogLevel_Info, "WiFi roaming found! Connecting to " + String(mac) + " -> " + String(bestSignal) + "dBm, " + String(WiFiStaMultipleNetwork));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log->AddEvent(LogLevel_Info, "SSID: " + ssid + " not found");
|
log->AddEvent(LogLevel_Info, "SSID: " + ssid + " not found");
|
||||||
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -404,15 +420,19 @@ void WiFiMngt::WiFiWatchdog() {
|
||||||
|
|
||||||
/* when is enabled wifi configuration, and is not connected to wifi network, and is available at least one wifi network */
|
/* when is enabled wifi configuration, and is not connected to wifi network, and is available at least one wifi network */
|
||||||
if ((true == config->CheckActifeWifiCfgFlag()) && (WL_CONNECTED != WiFi.status()) && (true == GetFirstConnection())) {
|
if ((true == config->CheckActifeWifiCfgFlag()) && (WL_CONNECTED != WiFi.status()) && (true == GetFirstConnection())) {
|
||||||
log->AddEvent(LogLevel_Warning, F("WiFi WDG. STA connection lost."));
|
log->AddEvent(LogLevel_Warning, "WiFi WDG. STA connection lost. " + String(StartStaWdg));
|
||||||
unsigned long currentMillis = millis();
|
unsigned long currentMillis = millis();
|
||||||
|
log->AddEvent(LogLevel_Verbose, "Time: " + String(currentMillis - TaskWdg_previousMillis) + "/" + String(WIFI_STA_WDG_TIMEOUT));
|
||||||
|
|
||||||
if (false == StartStaWdg) {
|
if (false == StartStaWdg) {
|
||||||
if (ScanWifiNetwork(WifiSsid) >= 1) {
|
if (ScanWifiNetwork(WifiSsid) >= 1) {
|
||||||
StartStaWdg = true;
|
|
||||||
TaskWdg_previousMillis = currentMillis;
|
|
||||||
log->AddEvent(LogLevel_Warning, F("WiFi STA connection lost. Start watchdog timer!"));
|
log->AddEvent(LogLevel_Warning, F("WiFi STA connection lost. Start watchdog timer!"));
|
||||||
|
} else {
|
||||||
|
log->AddEvent(LogLevel_Warning, F("WiFi STA connection lost. No available network!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StartStaWdg = true;
|
||||||
|
TaskWdg_previousMillis = currentMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((true == StartStaWdg) && (currentMillis - TaskWdg_previousMillis >= WIFI_STA_WDG_TIMEOUT)) {
|
if ((true == StartStaWdg) && (currentMillis - TaskWdg_previousMillis >= WIFI_STA_WDG_TIMEOUT)) {
|
||||||
|
|
@ -420,10 +440,12 @@ void WiFiMngt::WiFiWatchdog() {
|
||||||
/* restart MCU, or disconnect and connect to WiFi again ? From my point of view, and testing, restart MCU is better */
|
/* restart MCU, or disconnect and connect to WiFi again ? From my point of view, and testing, restart MCU is better */
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (true == StartStaWdg) {
|
} else if (true == StartStaWdg) {
|
||||||
log->AddEvent(LogLevel_Info, F("WiFi STA connection OK. Stop watchdog timer!"));
|
log->AddEvent(LogLevel_Info, F("WiFi WDG. WiFi STA connection OK. Stop watchdog timer!"));
|
||||||
StartStaWdg = false;
|
StartStaWdg = false;
|
||||||
TaskWdg_previousMillis = millis();
|
TaskWdg_previousMillis = millis();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -491,6 +513,15 @@ String WiFiMngt::TranslateTxPower(wifi_power_t data) {
|
||||||
case WIFI_POWER_19_5dBm:
|
case WIFI_POWER_19_5dBm:
|
||||||
ret = F("19.5dBm");
|
ret = F("19.5dBm");
|
||||||
break;
|
break;
|
||||||
|
case WIFI_POWER_20dBm:
|
||||||
|
ret = F("20dBm");
|
||||||
|
break;
|
||||||
|
case WIFI_POWER_20_5dBm:
|
||||||
|
ret = F("20.5dBm");
|
||||||
|
break;
|
||||||
|
case WIFI_POWER_21dBm:
|
||||||
|
ret = F("21dBm");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -794,6 +825,7 @@ void WiFiMngt::SetEnableServiceAp(bool i_data) {
|
||||||
*/
|
*/
|
||||||
void WiFiMngt::ConnectToSta() {
|
void WiFiMngt::ConnectToSta() {
|
||||||
config->SaveWifiCfgFlag(CFG_WIFI_SETTINGS_SAVED);
|
config->SaveWifiCfgFlag(CFG_WIFI_SETTINGS_SAVED);
|
||||||
|
WiFiStaConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,14 @@
|
||||||
|
|
||||||
@bug: no know bug
|
@bug: no know bug
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#ifndef _WIFI_MNGT_H_
|
|
||||||
#define _WIFI_MNGT_H_
|
|
||||||
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include "Arduino.h"
|
#include <Arduino.h>
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
#include "esp32-hal-cpu.h"
|
#include <esp32-hal-cpu.h>
|
||||||
|
|
||||||
#include "mcu_cfg.h"
|
#include "mcu_cfg.h"
|
||||||
#include "var.h"
|
#include "var.h"
|
||||||
|
|
@ -143,6 +141,4 @@ public:
|
||||||
|
|
||||||
extern WiFiMngt SystemWifiMngt; ///< global variable for wifi management
|
extern WiFiMngt SystemWifiMngt; ///< global variable for wifi management
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
366
README.md
|
|
@ -1,92 +1,75 @@
|
||||||
# PrusaConnect ESP32-CAM
|
# PrusaConnect ESP32-CAM
|
||||||
|
|
||||||
This repository includes source code and firmware releases for the ESP32-cam module programmed in the Arduino IDE
|
This repository includes source code and firmware releases for the **ESP32-cam** module programmed in the **Arduino IDE**. Currently, several versions of boards built on **ESP32/ESP32S3** processors with a camera chip are supported. You can find a list of supported boards below. Additionally, for each supported board, there is a guide on how to upload the firmware, how to compile code for it, some basic information and a list of known issues for this particular board.
|
||||||
|
|
||||||
This project uses other libraries. It is necessary to install them in the Arduino IDE.
|
This project uses other libraries. It is necessary to install them in the Arduino IDE:
|
||||||
- App [Arduino IDE 2.3.2](https://www.arduino.cc/en/software)
|
- App [Arduino IDE 2.3.4](https://www.arduino.cc/en/software)
|
||||||
- MCU support [ESP32 2.0.16](https://github.com/espressif/arduino-esp32)
|
- MCU support [arduino-ESP32 3.1.0](https://github.com/espressif/arduino-esp32)
|
||||||
- Library [ESPAsyncWebSrv 1.2.7](https://github.com/dvarrel/ESPAsyncWebSrv)
|
- ~~Library [ESPAsyncWebSrv 1.2.7](https://github.com/dvarrel/ESPAsyncWebSrv)~~ To version **1.0.3-rc1**
|
||||||
- Library [AsyncTCP 1.1.4](https://github.com/dvarrel/AsyncTCP)
|
- ~~Library [AsyncTCP 1.1.4](https://github.com/dvarrel/AsyncTCP)~~ To version **1.0.3-rc1**
|
||||||
- Library [ArduinoJson 7.0.4](https://github.com/bblanchon/ArduinoJson)
|
- Library [AsyncTCP 3.3.1](https://github.com/mathieucarbou/AsyncTCP)
|
||||||
|
- Library [ESPAsyncWebServer 3.4.5](https://github.com/mathieucarbou/ESPAsyncWebServer)
|
||||||
|
- Library [ArduinoJson 7.3.0](https://github.com/bblanchon/ArduinoJson)
|
||||||
- Library [UniqueID 1.3.0](https://github.com/ricaun/ArduinoUniqueID)
|
- Library [UniqueID 1.3.0](https://github.com/ricaun/ArduinoUniqueID)
|
||||||
|
- Library [DHTnew 0.5.2](https://github.com/RobTillaart/DHTNew)
|
||||||
|
|
||||||
What we need for functionality
|
What we need for functionality:
|
||||||
- ESP32-CAM AI-thinker board with OV2640 camera module [ here ](#esp32)
|
- Supported versions of boards built on **ESP32/ESP32-S3** processors with a camera [here](#supported_boards)
|
||||||
- Module board version [here](#different_mcu)
|
|
||||||
- Install the necessary libraries in the Arduino IDE [ here ](#arduino_lib)
|
|
||||||
- Arduino IDE configuration [ here ](#arduino_cfg)
|
|
||||||
- How to flash binary files to ESP32-cam board from Linux/MAC/Windows [ here ](#flash_fw)
|
- How to flash binary files to ESP32-cam board from Linux/MAC/Windows [ here ](#flash_fw)
|
||||||
- How to connect ESP32-cam to Prusa Connect [here](#prusa_connect)
|
- How to flash using Chrome [here](#browser_flash)
|
||||||
|
- How to compile software in the Arduino IDE [here](#arduino_lib)
|
||||||
|
- How to connect camera board to Prusa Connect [here](#prusa_connect)
|
||||||
- Service AP [here](#service_ap)
|
- Service AP [here](#service_ap)
|
||||||
- How to reset the configuration to factory settings [here](#factory_cfg)
|
- How to reset the configuration to factory settings [here](#factory_cfg)
|
||||||
- Status LED [ here ](#status_led)
|
- Status LED [ here ](#status_led)
|
||||||
- Schematic main board is [here](#schematic)
|
|
||||||
- Issue with FLASH LED on the main board [here](#led_issue)
|
|
||||||
- External WiFi antenna [here](#ext_wifi)
|
|
||||||
- Power supply [here](#power_supply)
|
|
||||||
- Debug logs [here](#logs)
|
- Debug logs [here](#logs)
|
||||||
- Serial console configuration [here](#serial_cfg)
|
- Serial console configuration [here](#serial_cfg)
|
||||||
|
- WEB API [here](#rest)
|
||||||
- Video stream [here](#stream)
|
- Video stream [here](#stream)
|
||||||
- Manual camera focus [here](#man_focus)
|
- Manual camera focus [here](#man_focus)
|
||||||
|
- External temperature sensor DHT22/DHT11 [here](#ext_temp)
|
||||||
- Potential issue [here](#issue)
|
- Potential issue [here](#issue)
|
||||||
|
|
||||||
<a name="esp32"></a>
|
<a name="supported_boards"></a>
|
||||||
## ESP32-CAM AI-thinker board
|
## Supported boards
|
||||||
It's a few dollars board with **ESP32** MCU and Camera. It's necessary to buy a board with **camera module OV2640**. The board is sold without a programmer by default. It is possible to program it using the FTDI USB to UART converter, or purchase an official programmer for the board. We recommend purchasing an official programmer. It can save a lot of trouble with connecting and programming the board. There are currently [2 different board versions](#different_mcu), but only one is compatible with the official programmer.
|
|
||||||
|
|
||||||
<img src="doc/esp32-cam.jpg" width=30% height=30%>
|
| Board name | Support | Stream | Micro SD | FLASH LED | FW update | DHT22/DHT11 | Documentation |
|
||||||
|
|---------------------------|-------------|--------|----------|-----------|-----------|-------------|---------------------------------------------------|
|
||||||
|
| Ai-Thinker ESP32-cam | Full | Yes | Yes | Board/Ext | Yes | Yes | [ here ](doc/AI_Thinker-ESP32-cam/README.md) |
|
||||||
|
| ESP32-S3-EYE 2.2 | Full | Yes | Yes | External | Yes | Yes | [ here ](doc/ESP32-S3-EYE-22/README.md) |
|
||||||
|
| Freenove ESP32-Wrover cam | Full | Yes | No | External | Yes | Yes | [ here ](doc/ESP32-Wrover-dev/README.md) |
|
||||||
|
| Freenove ESP32-S3-Wroom | Full | Yes | Yes | Board/Ext | Yes | Yes | [ here ](doc/Freenove%20ESP32-S3-Wroom/README.md) |
|
||||||
|
| ESP32-S3-DEV-CAM | in Progress | | | External | | | [ here ](doc/ESP32-S3-DEV-CAM/README.md) |
|
||||||
|
| Seeed Studio XIAO ESP32S3 | Full | Yes | Yes | External | Yes | Yes | [ here ](doc/XIAO_ESP32S3/README.md) |
|
||||||
|
| ESP32-S3-CAM | Full | Yes | Yes | Board/Ext | Yes | Yes | [ here ](doc/ESP32-S3-CAM/README.md) |
|
||||||
|
|
||||||
In the following picture, we can see the **ESP32-CAM** board and the programator for the board.
|
The compiled firmware for each supported board is published with every release.
|
||||||
|
|
||||||
<img src="doc/esp32_and_prog.jpg" width=30% height=30%>
|
<a name="flash_fw"></a>
|
||||||
|
## How to flash binary files to ESP32-cam board from Linux/MAC/Windows
|
||||||
|
|
||||||
It's necessary to use a camera version **OV2640**. If using a different camera, modification of the camera's pinout can be needed, or some camera settings may not work correctly. We recommend to use a camera module with a viewing angle of 120° or 160°.
|
Uploading a precompiled version of the firmware to the MCU is possible from either Linux or Windows OS. Since different boards use various processors and modules, it is not possible to create a single universal guide. Therefore, it is necessary to select the board you are using and then refer to the documentation on how to upload the firmware to it. Here is list with currently [supported boards](#supported_boards).
|
||||||
|
|
||||||
These are currently known or tested camera modules:
|
<a name="browser_flash"></a>
|
||||||
|
## How to flash using Chrome
|
||||||
|
It is also possible to flash firmware using ESP Tool on a WEB browser https://espressif.github.io/esptool-js/
|
||||||
|
|
||||||
| Camera chip | FOV | Resolution | Tested | Works | Description |
|
**This option is currently not supported on the Ai Thinker ESP32-cam board version.**
|
||||||
|-------------|------|------------|--------|-------|------------------------------------------|
|
|
||||||
| OV2640 | 30° | 2MP | No | N/A | |
|
|
||||||
| OV2640 | 44° | 2MP | No | N/A | |
|
|
||||||
| OV2640 | 66° | 2MP | Yes | Yes | Recommended. Standard camera module |
|
|
||||||
| OV2640 | 120° | 2MP | Yes | Yes | Recommended |
|
|
||||||
| OV2640 | 160° | 2MP | Yes | Yes | Recommended |
|
|
||||||
| OV2640 | 200° | 2MP | No | N/A | |
|
|
||||||
| OV2640 | 222° | 2MP | No | N/A | |
|
|
||||||
| OV2640IR | 160° | 2MP | Yes | Yes | |
|
|
||||||
| OV8225N | 66° | 2MP | Yes | Yes | |
|
|
||||||
| OV3360 | 66° | 3MP | Yes | Yes | |
|
|
||||||
| OV5640-AF | 72° | 5MP | Yes | Yes | Overheating, slow photo loading |
|
|
||||||
|
|
||||||
<a name="different_mcu"></a>
|
Ensure that you set the correct baud rate from the documentation for the board you are using (921600). Select the serial port your board is connected to. You can then click "Add File" and select each .bin file for your board. Make sure that you input the **correct Flash Address** from the documentation from your board. For the initial flash, click "Erase Flash", and when that is complete, click "Program." See below for a screenshot of how to configure ESP Tool for the Freenove Wrover board.
|
||||||
## Different MCU version
|
|
||||||
|
|
||||||
There are currently 2 versions of the board, but only one version is possible programming via oficial **CH340** programmer. The blue rectangle shows the differences between the HW versions.
|
<img src="doc/ESPToolConnect.jpg" width=50% height=50%>
|
||||||
|
|
||||||
<img src="doc/cam_versions.jpg" width=50% height=50%>
|
<img src="doc/ESPTool.png" width=50% height=50%>
|
||||||
|
|
||||||
The red arrow points to a pin that differs between these boards. In version 1, this pin is used for **MCU RESET (GND/R)**. In version 2, this pin serves as ground **(GND)**. Version 1 can be programmed via **CH340**, whereas version 2 cannot be programmed via **CH340**. For version 2, we tested programming via **FT232RL** or **CP2102**, and the programming process worked successfully.
|
<img src="doc/ESPToolFinish.jpg" width=50% height=50%>
|
||||||
|
|
||||||
If we want to program the MCU without the original programmer with **CH340**, or if we want to program the second version of the board, then we need to follow the following instructions. We will need a USB to UART converter, such as **FT232**, **CP2102** or **CH340**. I have tested firmware uploading to the **ESP32-cam** with these converters. Uploading FW to the **second** version using **CH340** did not work for me. Uploading FW using **CH340** only worked for me for the first version of **ESP32-cam** board. For the next steps, I will use the **FT232RL** converter. We connect the **ESP32-cam** to the **FT232** according to the following diagram, where we connect:
|
|
||||||
|
|
||||||
<img src="doc/ESP32-cam prog_bb.png" width=60% height=60%>
|
|
||||||
|
|
||||||
- **VCC** from **FT232** to **5V** on the **ESP32-CAM**. **CAUTION!** It is necessary to observe the maximum supply voltage of the **ESP32-CAM**, otherwise irreversible damage to the **ESP32-CAM** module may occur.
|
|
||||||
- **GND** from **FT232** to **GND** on the **ESP32-CAM**
|
|
||||||
- **TX** from **FT232** to **U0R** on the **ESP32-CAM**
|
|
||||||
- **RX** from **FT232** to **U0T** on the **ESP32-CAM**
|
|
||||||
- **IO0** from **ESP32-CAM** to **GND** on **ESP32-CAM**. By connecting the **IO0** pin to **GND**, we switch the board to the mode in which it expects firmware uploading.
|
|
||||||
|
|
||||||
Next step is connect the **FT232** converter to the PC and install the correct driver. Then we proceed with uploading the firmware to the **ESP32-cam**, which is described [here](https://github.com/prusa3d/Prusa-Firmware-ESP32-Cam?tab=readme-ov-file#how-to-flash-binary-files-to-esp32-cam-board-from-linuxmacwindows). After successfully uploading the firmware to the **ESP32-cam**, we disconnect **IO0** from **GND**, disconnect the **FT232** converter from the **ESP32-CAM**, and connect the **ESP32-CAM** to the power supply.
|
|
||||||
|
|
||||||
The recommended version includes the MCU ESP32 (ESP32-S) with 520 KB of SRAM and external 4M PSRAM
|
|
||||||
|
|
||||||
<a name="arduino_lib"></a>
|
<a name="arduino_lib"></a>
|
||||||
## Necessary libraries in the Arduino IDE
|
## How to compile software in the Arduino IDE
|
||||||
|
|
||||||
Software compilation was done in Arduino IDE 2.3.2. To ensure proper functionality, it is necessary to install support for ESP32 boards into Arduino IDE, as well as several other libraries
|
The software can be compiled and uploaded to the MCU. Software compilation was done in Arduino IDE. To ensure proper functionality, it is necessary to install support for ESP32 boards into Arduino IDE, as well as several other libraries.
|
||||||
|
|
||||||
At the first step we need to install support for **ESP32 board**.
|
As a first step we need to install support for **ESP32 boards**.
|
||||||
|
|
||||||
**File** -> **Preferences** -> **Additional boards managers URLs**
|
**File** -> **Preferences** -> **Additional boards managers URLs**
|
||||||
|
|
||||||
|
|
@ -94,127 +77,66 @@ At the first step we need to install support for **ESP32 board**.
|
||||||
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
|
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
|
||||||
```
|
```
|
||||||
|
|
||||||
then go to **Tools** -> **Board** -> **Boards Manager...** and install module **ESP32** by **Espressif Systems**, version **2.0.15**
|
then go to **Tools** -> **Board** -> **Boards Manager...** and install module **ESP32** by **Espressif Systems**.
|
||||||
|
|
||||||
The next step is to install the necessary libraries. Go to **Sketch** -> **Include Library** -> **Manage Libraries...** or you can use **Ctrl+Shift+I**. Then you can search for the necessary libraries and install them.
|
The next step is to install the necessary libraries. Go to **Sketch** -> **Include Library** -> **Manage Libraries...** or you can use **Ctrl+Shift+I**. Here you can search for the necessary libraries and install them.
|
||||||
|
|
||||||
- Library [ESPAsyncWebSrv by dvarrel 1.2.7](https://github.com/dvarrel/ESPAsyncWebSrv)
|
For the installation of the **ESPAsyncWebServer** and **AsyncTCP** libraries, it is necessary to download the **ZIP** archive from the official **GIT** repository, and then import it using **Sketch** -> **Include Library** -> **Add .ZIP Library ...**.
|
||||||
- Library [AsyncTCP by dvarrel 1.1.4](https://github.com/dvarrel/AsyncTCP)
|
|
||||||
- Library [ArduinoJson by bblanchon 7.0.4](https://github.com/bblanchon/ArduinoJson)
|
|
||||||
- Library [UniqueID by Luiz Henrique Cassettari1.3.0](https://github.com/ricaun/ArduinoUniqueID)
|
|
||||||
|
|
||||||
<a name="arduino_cfg"></a>
|
You should now be able to build the firmware and upload it to the board. Each board requires a different Arduino IDE configuration. Therefore, it is necessary to select the board from the [supported boards](#supported_boards) and read the documentation on how to build and upload the firmware.
|
||||||
## Arduino IDE configuration
|
|
||||||
|
|
||||||
Board configuration in the Arduino IDE 2.3.2
|
**For each specific board type, it's necessary** to update the file called **mcu_cfg.h**. Below **line 16** you can find several definitions that specify the version of the board for which the software will be compiled. It is necessary to enable the version of the board that will be used:
|
||||||
- Tools -> Board -> ESP32 Arduino -> AI Thinker ESP32
|
|
||||||
- Tools -> Flash frequency -> 80MHz
|
|
||||||
- Tools -> Core Debug Level -> None
|
|
||||||
- Tools -> Erase all Flash Before Sketch Upload -> Disable **(first flash, new board = enable. otherwise = disable)**
|
|
||||||
- Tools -> Flash Mode -> DIO
|
|
||||||
- Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
|
||||||
|
|
||||||
When flashing the firmware to a new, empty ESP32-CAM device for the first time, it is necessary to use the 'Erase' function.
|
|
||||||
|
|
||||||
This can be found under **Tools** -> **Erase all Flash Before Sketch Upload** -> **Enable**.
|
|
||||||
|
|
||||||
After the initial firmware upload to the MCU, it's necessary to disable this option. If you do not disable this option, your camera configuration will continue to be erased from the flash memory after uploading new firmware from the Arduino IDE.
|
|
||||||
|
|
||||||
<a name="flash_fw"></a>
|
|
||||||
## How to flash binary files to ESP32-cam board from Linux/MAC/Windows
|
|
||||||
|
|
||||||
#### Linux/MAC
|
|
||||||
|
|
||||||
You must use the console to upload the firmware on the MAC or Linux platform. First, ensure you have installed esptool for Python. You can find it on the manufacturer's website, ESPRESSIF, [here](https://docs.espressif.com/projects/esp-at/en/latest/esp32/Get_Started/Downloading_guide.html#linux-or-macos).
|
|
||||||
|
|
||||||
And command for FLASH FW is here, where **/dev/ttya0** is your serial interface for communication with the ESP32-cam board. This is the command for the first flash FW to MCU.
|
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define AI_THINKER_ESP32_CAM false
|
||||||
|
#define ESP32_WROVER_DEV true
|
||||||
|
#define CAMERA_MODEL_ESP32_S3_DEV_CAM false
|
||||||
|
#define CAMERA_MODEL_ESP32_S3_EYE_2_2 false
|
||||||
|
#define CAMERA_MODEL_XIAO_ESP32_S3_CAM false
|
||||||
|
#define CAMERA_MODEL_ESP32_S3_CAM false
|
||||||
```
|
```
|
||||||
./esptool -p /dev/ttya0 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --erase-all --flash_mode dio --flash_size 4MB --flash_freq 80m 0x1000 ESP32_PrusaConnectCam.ino.bootloader.bin 0x8000 ESP32_PrusaConnectCam.ino.partitions.bin 0x10000 ESP32_PrusaConnectCam.ino.bin
|
|
||||||
```
|
|
||||||
|
|
||||||
This command contains the parameter **--eras-all**, which erases the entire flash in the MCU. So, for just updating the firmware, it is necessary to remove the parameter **--eras-all**; otherwise, the MCU configuration will also be deleted. The basic command list can be found [here](https://docs.espressif.com/projects/esptool/en/latest/esp32s3/esptool/basic-commands.html)
|
|
||||||
|
|
||||||
Here is the command for updating the firmware in the MCU without erasing the MCU configuration
|
|
||||||
|
|
||||||
```
|
|
||||||
./esptool -p /dev/ttya0 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size 4MB --flash_freq 80m 0x1000 ESP32_PrusaConnectCam.ino.bootloader.bin 0x8000 ESP32_PrusaConnectCam.ino.partitions.bin 0x10000 ESP32_PrusaConnectCam.ino.bin
|
|
||||||
```
|
|
||||||
|
|
||||||
Launching the esptool application may be different in different operating systems
|
|
||||||
|
|
||||||
#### Windows
|
|
||||||
|
|
||||||
Here is the tool and configuration for [windows platform](https://www.espressif.com/en/support/download/other-tools)
|
|
||||||
|
|
||||||
You can find the driver for CH340 for Windows for example [here](https://www.wch-ic.com/search?q=CH340&t=downloads) . An older version of the driver is for example [here](https://blog.laskakit.cz/wp-content/uploads/2020/03/CH341SER.zip)
|
|
||||||
|
|
||||||
<img src="doc/how to flash chip select.jpg" width=25% height=25%>
|
|
||||||
|
|
||||||
It's necessary to erase the FLASH using the **ERASE** button before the first firmware flash.
|
|
||||||
|
|
||||||
<img src="doc/how to flash.jpg" width=30% height=30%>
|
|
||||||
|
|
||||||
#### Partitions table
|
|
||||||
|
|
||||||
Here is the partitions table:
|
|
||||||
|
|
||||||
| Name | Type | SubType | Offset | Size | Flags |
|
|
||||||
|---------|---------|---------|----------|----------|-------|
|
|
||||||
| nvs | data | nvs | 0x9000 | 0x5000 | |
|
|
||||||
| otadata | data | ota | 0xe000 | 0x2000 | |
|
|
||||||
| app0 | app | ota_0 | 0x10000 | 0x1E0000 | |
|
|
||||||
| app1 | app | ota_1 | 0x1F0000 | 0x1E0000 | |
|
|
||||||
| spiffs | data | spiffs | 0x3D0000 | 0x20000 | |
|
|
||||||
| coredump| data | coredump| 0x3F0000 | 0x10000 | |
|
|
||||||
|
|
||||||
However, for uploading the firmware, it's important to use this configuration of addresses and files:
|
|
||||||
|
|
||||||
- address **0x1000** - **ESP32_PrusaConnectCam.ino.bootloader.bin**
|
|
||||||
- address **0x8000** - **ESP32_PrusaConnectCam.ino.partitions.bin**
|
|
||||||
- address **0x10000** - **ESP32_PrusaConnectCam.ino.bin**
|
|
||||||
|
|
||||||
<a name="prusa_connect"></a>
|
<a name="prusa_connect"></a>
|
||||||
## How to connect ESP32-cam to Prusa Connect
|
## How to connect camera board to Prusa Connect
|
||||||
|
|
||||||
- Open up the **Prusa Connect** webpage [connect.prusa3D.com](https://connect.prusa3D.com)
|
- Go to the **Prusa Connect** webpage [https://connect.prusa3D.com](https://connect.prusa3D.com).
|
||||||
- Log in
|
- Log in.
|
||||||
- Select a printer you wish to use the camera for.
|
- Select a printer you wish to use the camera for.
|
||||||
- Navigate to the **Camera** tab.
|
- Navigate to the **Camera** tab.
|
||||||
- Click **Add new other camera**
|
- Click **Add new other camera**.
|
||||||
- **A new camera will appear** in the list. Here, you can give the camera a name.
|
- **A new camera will appear** in the list. Here, you can give the camera a name.
|
||||||
- This is the most important part: Copy the **TOKEN** for the given camera and save it for later use.
|
- This is the most important part: Copy the **TOKEN** for the given camera and save it for later use.
|
||||||
|
|
||||||
<img src="doc/connect_1.jpg" width=50% height=50%>
|
<img src="doc/connect_1.jpg" width=50% height=50%>
|
||||||
<img src="doc/connect_2.jpg" width=50% height=50%>
|
<img src="doc/connect_2.jpg" width=50% height=50%>
|
||||||
|
|
||||||
- Connect the Cam to the **USB Power supply**
|
- Connect the Cam to the **USB Power supply**.
|
||||||
- After a brief moment, the camera will start in a **Wi-Fi AP mode**. Essentially, it starts it's own Wi-Fi network. The network name (SSID) is **ESP32_camera_UID**, where **UID** is the first three numbers from the **MCU ID**.
|
- After a brief moment, the camera will start in a **Wi-Fi AP mode**. Essentially, it starts its own Wi-Fi network. The network name (SSID) is **ESP32_camera_UID**, where **UID** is the first three numbers from the **MCU ID**.
|
||||||
- Find the camera in the Wi-Fi list on your computer.
|
- Find the camera in the Wi-Fi list on your computer.
|
||||||
- Enter the default password: **12345678** and connect to it. After establishing a successful connection, your computer might complain about having "No Internet" on the given network. That is OK.
|
- Enter the default password: **12345678** and connect to it. After establishing a successful connection, your computer might complain about having "No Internet" on the given network. That is OK.
|
||||||
- Open up a new web browser.
|
- Open up a new web browser.
|
||||||
- Open up the **192.168.0.1** IP Address as a webpage. Alternatively, you can also use the http://prusa-esp32cam.local hostname (mDNS) instead of the IP Address.
|
- Enter [http://192.168.0.1](http://192.168.0.1) as the URL. Alternatively, you can also try to use the http://prusa-esp32cam.local hostname (mDNS) instead of the IP address.
|
||||||
- The camera's configuration interface should appear.
|
- The camera's configuration interface should appear.
|
||||||
- In the **Wi-Fi configuration tab** It's necessary to set the SSID of the WiFi network and the password of the WiFi network to which the camera should connect in order to be able to upload images to Prusa Connect. And click to **Save & Connect** button
|
- In the **Wi-Fi configuration tab** it's necessary to set the SSID of the WiFi network and the password of the WiFi network to which the camera should connect in order to be able to upload images to Prusa Connect. Make sure to click the **Save & Connect** button when you're done.
|
||||||
|
|
||||||
<img src="doc/connect_4.jpg" width=50% height=50%>
|
<img src="doc/connect_4.jpg" width=50% height=50%>
|
||||||
|
|
||||||
- In the **Camera configuration tab**, insert the **Token** into the marked field. Click **Save**. **This is the Prusa Connect camera token we have obtained in an earlier step.** Wait until the token has been save successfully.
|
- In the **Camera configuration tab**, insert the **Token** you have obtained earlier into the marked field. Click **Save**. Wait until the token has been saved successfully.
|
||||||
|
|
||||||
<img src="doc/connect_3.jpg" width=50% height=50%>
|
<img src="doc/connect_3.jpg" width=50% height=50%>
|
||||||
|
|
||||||
- Since we're in the camera configuration tab already, we can set up the image options:
|
In this same tab you should also configure a few image settings:
|
||||||
- Set up the **resolution**. This will improve the image quality significantly, as the resolution is set to the lowest possible by default.
|
- Set up the **resolution**. This will improve the image quality significantly, as the resolution is set to the lowest possible by default.
|
||||||
- Set up the **Trigger interval** and click **Save**.
|
- Set up the **Trigger interval** and click **Save**.
|
||||||
- Clicking **Refresh snapshot** will refresh the image you see on the page.
|
- Clicking **Refresh snapshot** will refresh the image you see on the page.
|
||||||
- We should now have completed setting up the camera.
|
- We should now have completed setting up the camera.
|
||||||
|
|
||||||
While we are on the ESP camera's configuration page, let's take a quick look at the other options it offers.
|
While we are on the ESP camera's configuration page, let's take a quick look at the other options it offers:
|
||||||
- Camera configuration tab contain
|
- Camera configuration tab contains
|
||||||
- Camera cip settings
|
- Camera cip settings
|
||||||
- Authentication token setting
|
- Authentication token setting
|
||||||
- Camera flash settings
|
- Camera flash settings
|
||||||
- Wi-Fi configuration tab contain
|
- Wi-Fi configuration tab contains
|
||||||
- Setting the wifi network to which the camera can connect
|
- Setting the wifi network to which the camera can connect
|
||||||
- The possibility of turning off the service AP
|
- The possibility of turning off the service AP
|
||||||
- Option to set static IP addresses for WiFi networks to which the camera connects
|
- Option to set static IP addresses for WiFi networks to which the camera connects
|
||||||
|
|
@ -223,8 +145,8 @@ While we are on the ESP camera's configuration page, let's take a quick look at
|
||||||
- Setting a Hostname (mDNS record) for easier future access to the configuration page over the local network.
|
- Setting a Hostname (mDNS record) for easier future access to the configuration page over the local network.
|
||||||
- For a manual firmware update, select the firmware file **ESP32_PrusaConnectCam.ino.bin** and click **Upload file & Update**. Afterwards, reboot the camera.
|
- For a manual firmware update, select the firmware file **ESP32_PrusaConnectCam.ino.bin** and click **Upload file & Update**. Afterwards, reboot the camera.
|
||||||
- Update from cloud. To check for firmware updates, select **Check Update from cloud**. If a newer version is available, click **Update from cloud**. Note that the camera has to be connected to the Internet, before using these functions.
|
- Update from cloud. To check for firmware updates, select **Check Update from cloud**. If a newer version is available, click **Update from cloud**. Note that the camera has to be connected to the Internet, before using these functions.
|
||||||
- Setting **log level** and getting logs from the camera. To get the logos, it is necessary to have a micro SD card formatted to **FAT32** inserted in the camera!
|
- Setting **log level** and getting logs from the camera. To get the logs, it is necessary to have a micro SD card formatted to **FAT32** inserted in the camera!
|
||||||
- Check the status of uploading the image to Prusa Connect using the **PrusaConnect Status:** variable
|
- Check the status of uploading the image to Prusa Connect using the **PrusaConnect Status:** variable.
|
||||||
|
|
||||||
**Interesting improvements.** There is a protective film on the camera module. The protective film needs to be removed from the lens.
|
**Interesting improvements.** There is a protective film on the camera module. The protective film needs to be removed from the lens.
|
||||||
|
|
||||||
|
|
@ -237,103 +159,52 @@ The second problem is that the camera module is not usually attached to the micr
|
||||||
<a name="service_ap"></a>
|
<a name="service_ap"></a>
|
||||||
## Service AP
|
## Service AP
|
||||||
|
|
||||||
After powering on and booting up the camera, it enters **AP mode**, which serves as a configuration mode for the camera. Essentially, it starts its own Wi-Fi network. The network name (SSID) is **ESP32_camera_UID**, where **UID** is the first three numbers from the **MCU ID**, serving as a unique identifier for the camera. The password for connecting to the AP is **12345678**. The camera's IP address is **192.168.0.1**. To configure the camera via **AP mode**, you need to connect to this IP address using a web browser: **http://192.168.0.1**. Alternatively, you can also use the **http://prusa-esp32cam.local** hostname (**mDNS**) instead of the IP Address.
|
After powering on and booting up the camera, it enters **AP mode**, which serves as a configuration mode for the camera. Essentially, it starts its own Wi-Fi network. The network name (SSID) is **ESP32_camera_UID**, where **UID** is the first three numbers from the **MCU ID**, serving as a unique identifier for the camera. The password for connecting to the AP is **12345678**. The camera's IP address is **192.168.0.1**. To configure the camera via **AP mode**, you need to connect to this IP address using a web browser: **http://192.168.0.1**. Alternatively, you can also use the **http://prusa-esp32cam.local** hostname (**mDNS**) instead of the IP address.
|
||||||
|
|
||||||
After establishing a successful connection, your computer might display a "**No Internet**" warning for the given network. **This is normal**.
|
After establishing a successful connection, your computer might display a "**No Internet**" warning for the given network. **This is normal**.
|
||||||
|
|
||||||
If you have set up a Wi-Fi network name (SSID) and password in the camera for it to connect to, then upon powering on, the camera will automatically connect to the configured Wi-Fi network and simultaneously activate AP mode for **5 minutes**. AP mode is always enabled after powering on and booting up the camera for **5 minutes**. The service Wi-Fi AP is **automatically deactivates** itself after **5 minutes** following each camera startup if no device is connected to the camera.
|
If you have set up a Wi-Fi network name (SSID) and password in the camera for it to connect to, then upon powering on, the camera will automatically connect to the configured Wi-Fi network and simultaneously activate AP mode for **5 minutes**. AP mode is always enabled after powering on and booting up the camera for **5 minutes**. The service Wi-Fi AP **automatically deactivates** itself after **5 minutes** following each camera startup if no device is connected to the camera.
|
||||||
|
|
||||||
Service AP is for for the first camera configuration. If the camera is connected to a WiFi network, it is possible to configure it from the local network.
|
Service AP is for the first camera configuration. If the camera is connected to a WiFi network, it is possible to configure it from the local network.
|
||||||
|
|
||||||
<a name="factory_cfg"></a>
|
<a name="factory_cfg"></a>
|
||||||
## How to reset configuration to factory settings
|
## How to reset configuration to factory settings
|
||||||
To reset the settings to factory defaults, follow these instructions:
|
Each version of the [supported boards](#supported_boards) uses a different pin for camera reset. Therefore, it is necessary to refer to the documentation of the specific board to determine which pin is used to reset the camera configuration to factory defaults.
|
||||||
|
|
||||||
<img src="doc/factory_cfg.jpg" width=30% height=30%>
|
The procedure is the same for each board:
|
||||||
|
- Ground the pin for camera reset configuration.
|
||||||
- Connect PIN **IO12** to **ground**.
|
- Connect the power supply.
|
||||||
- **Plug in** the power supply.
|
- Wait for 10 seconds.
|
||||||
- Wait for **10 seconds**.
|
- An LED will start blinking (refer to the board's documentation).
|
||||||
- After 10 seconds, the **FLASH LED will start flashing**.
|
- Disconnect the ground from the camera reset configuration pin.
|
||||||
- **Disconnect** PIN **IO12** from **ground** (but don't disconnect the power supply).
|
- The LED will stop blinking.
|
||||||
- After disconnecting **IO12** from **ground**, the **FLASH LED** will **stop flashing**, and the MCU will **automatically reboot**.
|
- The camera configuration will be reset to factory defaults.
|
||||||
- Now the MCU is in the factory settings.
|
|
||||||
|
|
||||||
<a name="status_led"></a>
|
<a name="status_led"></a>
|
||||||
## Status LED
|
## Status LED
|
||||||
|
|
||||||
On the board, there is a status LED that provides a visual indicator of the module's current status
|
On the board, there is a status LED that provides a visual indicator of the module's current status through blinking at defined intervals. Each [supported board](#supported_boards) has the STATUS LED located in a different place. It is necessary to refer to the documentation to locate the STATUS LED on the board.
|
||||||
through blinking at defined intervals.
|
|
||||||
|
|
||||||
<img src="doc/status_led.jpg" width=25% height=25%>
|
Upon module activation, the LED illuminates. After processor initialization, the LED exhibits different blinking intervals based on the current mode of the module:
|
||||||
|
|
||||||
Upon module activation, the LED illuminates. After processor initialization, the LED exhibits different blinking intervals based on the current mode of the module
|
|
||||||
|
|
||||||
- **Service AP Mode only:** The LED blinks every **400 ms**, indicating the module's availability in service AP mode.
|
- **Service AP Mode only:** The LED blinks every **400 ms**, indicating the module's availability in service AP mode.
|
||||||
- **Connecting to WiFi AP:** While connecting to a WiFi Access Point, the LED blinks at intervals of **800 ms**.
|
- **Connecting to WiFi AP:** While connecting to a WiFi Access Point, the LED blinks at an interval of **800 ms**.
|
||||||
- **Connected to WiFi Network:** Upon successful connection to a WiFi network, the LED blinks at intervals of **4000 ms**, signaling a stable connection.
|
- **Connected to WiFi Network:** Upon successful connection to a WiFi network, the LED blinks at an interval of **4000 ms**, signaling a stable connection.
|
||||||
- **Problematic State:** If an issue or error occurs, the LED accelerates its blinking to every **100 ms**.
|
- **Problematic State:** If an issue or error occurs, the LED accelerates its blinking to every **100 ms**.
|
||||||
|
|
||||||
The approximate boot time of the device is 15-20 seconds.
|
The approximate boot time of the device is 15-20 seconds.
|
||||||
|
|
||||||
<a name="schematic"></a>
|
|
||||||
## Schematic for ESP32-cam board
|
|
||||||
|
|
||||||
<img src="doc/ESP32-CAM-AI-Thinker-schematic-diagram.png" width=70% height=70%>
|
|
||||||
|
|
||||||
Board description
|
|
||||||
|
|
||||||
<img src="doc/esp32-cam_parts.jpg" width=50% height=50%>
|
|
||||||
|
|
||||||
Pinout
|
|
||||||
|
|
||||||
<img src="doc/pinout.png" width=50% height=50%>
|
|
||||||
|
|
||||||
<a name="led_issue"></a>
|
|
||||||
## FLASH LED issue
|
|
||||||
The board has a problem with the FLASH LED, as it lacks any current limitation for the LED. Consequently, frequent use of the FLASH LED can lead to malfunction, due to excessive current flow.
|
|
||||||
|
|
||||||
One simple solution is to connect an external LED via a relay, transistor, or MOSFET to the board, as shown in the next picture. Using a relay is not ideal, but it provides a simple solution.
|
|
||||||
|
|
||||||
<img src="doc/relay_flash_bb.png" width=40% height=40%>
|
|
||||||
|
|
||||||
Another solution is to use an LED COB or a USB LED lamp. I utilized a board from a simple USB LED lamp. The transistor has a current limitation of 500mA, and my USB lamp has a current consumption of approximately 180mA. The original LED has a current consumption of 60-80mA. After calculation, the total current consumption is approximately 260mA, which falls within the current limitation of the transistor. Therefore, it is possible to solder the negative wire from the COB LED or the USB LED lamp to the transistor. The positive wire needs to be soldered to +5V.
|
|
||||||
|
|
||||||
This is my USB LED lamp
|
|
||||||
|
|
||||||
<img src="doc/usb_lamp.jpg" width=40% height=40%>
|
|
||||||
|
|
||||||
The next step is to solder the negative wire from the LED lamp to the transistor collector, and the positive wire from the LED lamp to the +5V on the board.
|
|
||||||
|
|
||||||
<img src="doc/esp32-cam_with_led_lamp.jpg" width=40% height=40%>
|
|
||||||
|
|
||||||
The third option is to solder a resistor between the collector of the transistor and the PCB. I used a 10-ohm resistor in a 0603 package. This option is more complicated for users with limited soldering experience.
|
|
||||||
|
|
||||||
<img src="doc/esp32-cam_flash_led_resistor.jpg" width=40% height=40%>
|
|
||||||
|
|
||||||
<a name="ext_wifi"></a>
|
|
||||||
## External/internal WiFi antenna
|
|
||||||
|
|
||||||
The standard ESP32-CAM board utilizes an internal antenna on the PCB. However, this antenna can sometimes cause issues with the quality of the WiFi signal, leading to slow photo uploads to PrusaConnect or connectivity problems. Fortunately, there is an option to connect an external antenna. This requires changing the resistor position, as shown in the picture below. Then, you can use a 2.4GHz Wi-Fi cable with a U.FL to RP-SMA connector and a standard 2.4GHz WiFi antenna
|
|
||||||
|
|
||||||
<img src="doc/esp32-cam_ext_ant.png" width=40% height=40%>
|
|
||||||
|
|
||||||
<a name="power_supply"></a>
|
|
||||||
## Power Supply
|
|
||||||
|
|
||||||
The device requires a 5V power supply, with a maximum current consumption of 2A. Power is supplied via a micro USB connector when using the original programmer.
|
|
||||||
|
|
||||||
<a name="logs"></a>
|
<a name="logs"></a>
|
||||||
## Debug logs
|
## Debug logs
|
||||||
|
|
||||||
It is possible to save debug logs to a microSD card, but the card must be formatted to FAT32. Currently, the maximum tested capacity for a microSD card is 16GB. If a microSD card is inserted into the camera, it is necessary to reboot the camera. When a microSD card is inserted into the camera before boot, logging to the microSD card is automatically enabled. If no microSD card is inserted, the saving of debug logs to the microSD card is automatically disabled. Enabling the saving of debug logs to a microSD card is only possible during camera boot, so it is necessary to restart the camera after inserting the microSD card. Debug logs are saved as plain text in the file Syslog.log
|
It is possible to save debug logs to a microSD card, but the card must be formatted to FAT32. Currently, the maximum tested capacity for a microSD card is 16GB. If a microSD card is inserted into the camera, it is necessary to reboot the camera. When a microSD card is inserted into the camera before boot, logging to the microSD card is automatically enabled. If no microSD card is inserted, logging to the microSD card is automatically disabled. Enabling the saving of debug logs to a microSD card is only possible during camera boot, so it is necessary to restart the camera after inserting the microSD card. Debug logs are saved as plain text in the file `SysLog.log`.
|
||||||
|
|
||||||
<a name="serial_cfg"></a>
|
<a name="serial_cfg"></a>
|
||||||
## Serial console configuration
|
## Serial console configuration
|
||||||
|
|
||||||
Currently, it is possible to set the basic camera configuration using the serial console. Baud speed for communication with MCU is **115200 8N1**
|
It is possible to set the basic camera configuration using the serial console. Serial port settings for communication with the MCU need to be set to **115200 8N1**.
|
||||||
|
|
||||||
Commands for configuration have simple syntax
|
Commands for configuration have a simple syntax:
|
||||||
|
|
||||||
| command | separator | variable | termination | line terminator |
|
| command | separator | variable | termination | line terminator |
|
||||||
|--------------|-----------|-----------|-------------|--------------------------|
|
|--------------|-----------|-----------|-------------|--------------------------|
|
||||||
|
|
@ -349,15 +220,16 @@ Currently, available commands are listed in the table below:
|
||||||
| mcureboot | Rebooting the MCU |
|
| mcureboot | Rebooting the MCU |
|
||||||
| commandslist | Listing currently supported commands via serial console |
|
| commandslist | Listing currently supported commands via serial console |
|
||||||
| getwifimode | Print current WiFi mode. STA/AP/AP+STA |
|
| getwifimode | Print current WiFi mode. STA/AP/AP+STA |
|
||||||
| getwifistastatus | Print WiFi STA status. Connected/Disconnected/Connecting.... |
|
| getwifistastatus | Print WiFi STA status. Connected/Disconnected/Connecting... |
|
||||||
| getwifistaip | Print IP address for WiFi STA |
|
| getwifistaip | Print IP address for WiFi STA |
|
||||||
| getserviceapssid | Print service AP SSID name |
|
| getserviceapssid | Print service AP SSID name |
|
||||||
| setauthtoken | Set authentication token for Prusa Connect |
|
| setauthtoken | Set authentication token for Prusa Connect |
|
||||||
| otaupdate | Start OTA update process |
|
| otaupdate | Start OTA update process |
|
||||||
| resolution | Set photo resolution |
|
| resolution | Set photo resolution |
|
||||||
| photoquality | Set photo quality |
|
| photoquality | Set photo quality |
|
||||||
| setflash | enable/disable LED flash |
|
| setflash | Enable/disable LED flash |
|
||||||
| setlight | enable/disable LED light |
|
| setlight | Enable/disable LED light |
|
||||||
|
| loglevel | Set log level. 0=Error, 1=Warning, 2=Info, 3=Verbose |
|
||||||
|
|
||||||
The standard command sequence for camera basic settings is
|
The standard command sequence for camera basic settings is
|
||||||
|
|
||||||
|
|
@ -367,15 +239,34 @@ The standard command sequence for camera basic settings is
|
||||||
- setauthtoken:TOKEN;
|
- setauthtoken:TOKEN;
|
||||||
- mcureboot;
|
- mcureboot;
|
||||||
|
|
||||||
|
<a name="rest"></a>
|
||||||
|
## WEB API
|
||||||
|
|
||||||
|
The camera offers a web API, allowing several operations to be performed through the web interface:
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------------------------|--------------------------------------------------|
|
||||||
|
| http://IP/action_capture | Capture snapshot |
|
||||||
|
| http://IP/action_send | Capture snapshot, and send to Prusa Connect |
|
||||||
|
| http://IP/light?on | Light ON |
|
||||||
|
| http://IP/light?off | Light OFF |
|
||||||
|
| http://IP/flash?on | FLASH ON |
|
||||||
|
| http://IP/flash?off | FLASH OFF |
|
||||||
|
| http://IP/action_reboot | Reboot MCU |
|
||||||
|
| http://IP/get_logs | Get logs from micro SD card |
|
||||||
|
| http://IP/saved-photo.jpg | Get last captured photo |
|
||||||
|
| http://IP/get_temp | Get temperature from external sensor |
|
||||||
|
| http://IP/get_hum | Get humidity from external sensor |
|
||||||
|
|
||||||
<a name="stream"></a>
|
<a name="stream"></a>
|
||||||
## Video stream
|
## Video stream
|
||||||
|
|
||||||
The video stream is available on the WEB page **http://IP/stream.mjpg**
|
The video stream is available at **http://IP/stream.mjpg**.
|
||||||
|
|
||||||
<a name="man_focus"></a>
|
<a name="man_focus"></a>
|
||||||
## Manual camera focus
|
## Manual camera focus
|
||||||
|
|
||||||
Usually, the camera module is properly focused. However, the camera module can be manually focused. There are several types of lenses for camera modules. I have created several [Tools](https://www.printables.com/cs/model/877739-esp32-cam-ov2640-focus-adjustment-wrench) for manually focusing the camera module.
|
Usually, the camera module is properly focused. However, the camera module can be manually focused. There are several types of lenses for camera modules. I have created several [tools](https://www.printables.com/cs/model/877739-esp32-cam-ov2640-focus-adjustment-wrench) for manually focusing the camera module.
|
||||||
|
|
||||||
<img src="doc/focus_2.jpg" width=40% height=40%>
|
<img src="doc/focus_2.jpg" width=40% height=40%>
|
||||||
|
|
||||||
|
|
@ -383,8 +274,33 @@ First, it is necessary to hold the camera with a holder and then put the wrench
|
||||||
|
|
||||||
**WARNING! Manual focusing can permanently damage the camera module!**
|
**WARNING! Manual focusing can permanently damage the camera module!**
|
||||||
|
|
||||||
|
<a name="ext_temp"></a>
|
||||||
|
## External temperature sensor
|
||||||
|
|
||||||
|
The software supports an external temperature sensor **DHT22** or **DHT11**. The sensor needs to be connected according to the manual for the specific version of the board. The temperature and humidity are automatically read every 30 seconds once the sensor has been enabled.
|
||||||
|
|
||||||
|
<img src="doc/Sensori-DHT11-e-DHT22.jpg" width=40% height=40%>
|
||||||
|
|
||||||
|
Information about sensors:
|
||||||
|
|
||||||
|
| | DHT11 | DHT22 |
|
||||||
|
|-------------------|--------------|------------------|
|
||||||
|
| Operating voltage | 3-5V | 3-5V |
|
||||||
|
| Max current | 2.5 mA | 2.5mA |
|
||||||
|
| Temperature range | 0-50°C ± 2°C | -40-80°C ± 0.5°C |
|
||||||
|
| Humidity range | 20-80% / 5% | 0-100% / 2-5% |
|
||||||
|
| Sampling rate | 1Hz | 0.5Hz |
|
||||||
|
|
||||||
|
It is necessary to use the **module**, **not the sensor**! The module with the sensor has a **4.7kOhm** resistor soldered onto the PCB, which is necessary for the **one-wire bus** to operate properly. If you use the sensor, it is necessary to connect a 4.7kOhm resistor to the one-wire bus as shown in the schematic below. **The module must be powered with 3.3V VCC, otherwise it may damage the camera board**.
|
||||||
|
|
||||||
|
Here is a typical schematic for the DHT22 or DHT11 sensor:
|
||||||
|
|
||||||
|
<img src="doc/DHT22-Schematic.png" width=40% height=40%>
|
||||||
|
|
||||||
<a name="issue"></a>
|
<a name="issue"></a>
|
||||||
## Potential issue
|
## Troubleshooting
|
||||||
|
|
||||||
- A potential issue may arise with connecting to the service AP. If the connection fails and an authentication error occurs, it is necessary to clear the FLASH memory of the processor, and FLASH FW again. This can be done either through the Arduino IDE or using official software.
|
- A potential issue may arise with connecting to the service AP. If the connection fails and an authentication error occurs, it is necessary to clear the FLASH memory of the processor, and FLASH FW again. This can be done either through the Arduino IDE or using official software.
|
||||||
- After the initial firmware upload to the new camera, there may be an issue when connecting to the IP address, where the camera prompts for a username and password to access the web page. Even when entering the username "admin" and the password "admin", the login still doesn't work. In such cases, it's necessary to reset the camera configuration to factory settings. The procedure is outlined in the readme file [here](#factory_cfg)
|
- After the initial firmware upload to a new camera, there may be an issue when connecting to the IP address, where the camera prompts for a username and password to access the web page. Even when entering the username "admin" and the password "admin", the login still doesn't work. In such cases, it's necessary to reset the camera configuration to factory settings. The procedure is outlined in the readme file [here](#factory_cfg).
|
||||||
|
- If you are getting a 400 return code from Prusa Connect, then you need to create another camera in Prusa Connect and enter a new token into the ESP32 camera.
|
||||||
|
- If you are getting a 404 return code from Prusa Connect, it may indicate that the printer is powered off. The printer must be powered on in order for images to be uploaded.
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
|
@ -0,0 +1,254 @@
|
||||||
|
# Ai Thinker ESP32-CAM
|
||||||
|
|
||||||
|
What we need for functionality
|
||||||
|
- ESP32-CAM AI-thinker board with OV2640 camera module [ here ](#esp32)
|
||||||
|
- Supported camera modules [here](#cam_modules)
|
||||||
|
- Module board version [here](#different_mcu)
|
||||||
|
- How to flash binary files to board from Linux/MAC/Windows [ here ](#flash_fw)
|
||||||
|
- How to compile software in the Arduino IDE [ here ](#arduino_cfg)
|
||||||
|
- How to reset the configuration to factory settings [here](#factory_cfg)
|
||||||
|
- Status LED [ here ](#status_led)
|
||||||
|
- Schematic main board is [here](#schematic)
|
||||||
|
- Issue with FLASH LED on the main board [here](#led_issue)
|
||||||
|
- External WiFi antenna [here](#ext_wifi)
|
||||||
|
- Power supply [here](#power_supply)
|
||||||
|
- External temperature sensor DHT22/DHT11 [here](#ext_sens)
|
||||||
|
- Potential issue [here](#issue)
|
||||||
|
|
||||||
|
<a name="esp32"></a>
|
||||||
|
## ESP32-CAM AI-thinker board
|
||||||
|
|
||||||
|
Basic information:
|
||||||
|
- Low cost version
|
||||||
|
- FLASH LED on the board
|
||||||
|
- Option connecting external FLASH LED
|
||||||
|
- Micro SD card slot
|
||||||
|
- Internal WiFi antenna, after HW modification it's possible connecting external antenna
|
||||||
|
- Additional HW must be purchased for programming
|
||||||
|
- 4MB FLASH and 4MB external PSRAM
|
||||||
|
- 520 KB SRAM
|
||||||
|
|
||||||
|
It's a few dollars board with **ESP32** MCU and Camera. It's necessary to buy a board with **camera module OV2640**. The board is sold without a programmer by default. It is possible to program it using the FTDI USB to UART converter, or purchase an official programmer for the board. We recommend purchasing an official programmer. It can save a lot of trouble with connecting and programming the board. There are currently [2 different board versions](#different_mcu), but only one is compatible with the official programmer.
|
||||||
|
|
||||||
|
<img src="esp32-cam.jpg" width=30% height=30%>
|
||||||
|
|
||||||
|
In the following picture, we can see the **ESP32-CAM** board and the programmer for the board.
|
||||||
|
|
||||||
|
<img src="esp32_and_prog.jpg" width=30% height=30%>
|
||||||
|
|
||||||
|
<a name="cam_modules"></a>
|
||||||
|
## Supported camera modules
|
||||||
|
|
||||||
|
It's necessary to use a camera version **OV2640**. If using a different camera, modification of the camera's pinout can be needed, or some camera settings may not work correctly. We recommend to use a camera module with a viewing angle of 120° or 160°.
|
||||||
|
|
||||||
|
|
||||||
|
These are currently known or tested camera modules:
|
||||||
|
|
||||||
|
| Camera chip | FOV | Resolution | Tested | Works | Description |
|
||||||
|
|-------------|------|------------|--------|-------|------------------------------------------|
|
||||||
|
| OV2640 | 30° | 2MP | No | N/A | |
|
||||||
|
| OV2640 | 44° | 2MP | No | N/A | |
|
||||||
|
| OV2640 | 66° | 2MP | Yes | Yes | Recommended. Standard camera module |
|
||||||
|
| OV2640 | 120° | 2MP | Yes | Yes | Recommended |
|
||||||
|
| OV2640 | 160° | 2MP | Yes | Yes | Recommended |
|
||||||
|
| OV2640 | 200° | 2MP | No | N/A | |
|
||||||
|
| OV2640 | 222° | 2MP | No | N/A | |
|
||||||
|
| OV2640IR | 160° | 2MP | Yes | Yes | |
|
||||||
|
| OV8225N | 66° | 2MP | Yes | Yes | |
|
||||||
|
| OV3360 | 66° | 3MP | Yes | Yes | |
|
||||||
|
| OV5640-AF | 72° | 5MP | Yes | Yes | Overheating, slow photo loading |
|
||||||
|
|
||||||
|
<a name="different_mcu"></a>
|
||||||
|
## Different MCU version
|
||||||
|
|
||||||
|
There are currently 2 versions of the board, but only one version is possible programming via oficial **CH340** programmer. The blue rectangle shows the differences between the HW versions.
|
||||||
|
|
||||||
|
<img src="cam_versions.jpg" width=50% height=50%>
|
||||||
|
|
||||||
|
The red arrow points to a pin that differs between these boards. In version 1, this pin is used for **MCU RESET (GND/R)**. In version 2, this pin serves as ground **(GND)**. Version 1 can be programmed via **CH340**, whereas version 2 cannot be programmed via **CH340**. For version 2, we tested programming via **FT232RL** or **CP2102**, and the programming process worked successfully.
|
||||||
|
|
||||||
|
If we want to program the MCU without the original programmer with **CH340**, or if we want to program the second version of the board, then we need to follow the following instructions. We will need a USB to UART converter, such as **FT232**, **CP2102** or **CH340**. I have tested firmware uploading to the **ESP32-cam** with these converters. Uploading FW to the **second** version using **CH340** did not work for me. Uploading FW using **CH340** only worked for me for the first version of **ESP32-cam** board. For the next steps, I will use the **FT232RL** converter. We connect the **ESP32-cam** to the **FT232** according to the following diagram, where we connect:
|
||||||
|
|
||||||
|
<img src="ESP32-cam prog_bb.png" width=60% height=60%>
|
||||||
|
|
||||||
|
- **VCC** from **FT232** to **5V** on the **ESP32-CAM**. **CAUTION!** It is necessary to observe the maximum supply voltage of the **ESP32-CAM**, otherwise irreversible damage to the **ESP32-CAM** module may occur.
|
||||||
|
- **GND** from **FT232** to **GND** on the **ESP32-CAM**
|
||||||
|
- **TX** from **FT232** to **U0R** on the **ESP32-CAM**
|
||||||
|
- **RX** from **FT232** to **U0T** on the **ESP32-CAM**
|
||||||
|
- **IO0** from **ESP32-CAM** to **GND** on **ESP32-CAM**. By connecting the **IO0** pin to **GND**, we switch the board to the mode in which it expects firmware uploading.
|
||||||
|
|
||||||
|
Next step is connect the **FT232** converter to the PC and install the correct driver. Then we proceed with uploading the firmware to the **ESP32-cam**, which is described [here](https://github.com/prusa3d/Prusa-Firmware-ESP32-Cam?tab=readme-ov-file#how-to-flash-binary-files-to-esp32-cam-board-from-linuxmacwindows). After successfully uploading the firmware to the **ESP32-cam**, we disconnect **IO0** from **GND**, disconnect the **FT232** converter from the **ESP32-CAM**, and connect the **ESP32-CAM** to the power supply.
|
||||||
|
|
||||||
|
The recommended version includes the MCU ESP32 (ESP32-S) with 520 KB of SRAM and external 4M PSRAM
|
||||||
|
|
||||||
|
<a name="flash_fw"></a>
|
||||||
|
## How to flash binary files to board from Linux/MAC/Windows
|
||||||
|
|
||||||
|
#### Partitions table for flashing FW
|
||||||
|
|
||||||
|
Here is the partitions table:
|
||||||
|
|
||||||
|
| Name | Type | SubType | Offset | Size | Flags |
|
||||||
|
|---------|---------|---------|----------|----------|-------|
|
||||||
|
| nvs | data | nvs | 0x9000 | 0x5000 | |
|
||||||
|
| otadata | data | ota | 0xe000 | 0x2000 | |
|
||||||
|
| app0 | app | ota_0 | 0x10000 | 0x1E0000 | |
|
||||||
|
| app1 | app | ota_1 | 0x1F0000 | 0x1E0000 | |
|
||||||
|
| spiffs | data | spiffs | 0x3D0000 | 0x20000 | |
|
||||||
|
| coredump| data | coredump| 0x3F0000 | 0x10000 | |
|
||||||
|
|
||||||
|
However, for uploading the firmware, it's important to use this configuration of addresses and files:
|
||||||
|
|
||||||
|
ZIP file with build binary files: **esp32-cam.zip**
|
||||||
|
|
||||||
|
- address **0x1000** - **ESP32_PrusaConnectCam.ino.bootloader.bin**
|
||||||
|
- address **0x8000** - **ESP32_PrusaConnectCam.ino.partitions.bin**
|
||||||
|
- address **0x10000** - **ESP32_PrusaConnectCam.ino.bin**
|
||||||
|
|
||||||
|
**It is important to download the correct binary files! Each type of camera has its own ZIP archive with files for uploading the firmware.**
|
||||||
|
|
||||||
|
#### Linux/MAC
|
||||||
|
|
||||||
|
You must use the console to upload the firmware on the MAC or Linux platform. First, ensure you have installed esptool for Python. You can find it on the manufacturer's website, ESPRESSIF, [here](https://docs.espressif.com/projects/esp-at/en/latest/esp32/Get_Started/Downloading_guide.html#linux-or-macos).
|
||||||
|
|
||||||
|
And command for FLASH FW is here, where **/dev/ttya0** is your serial interface for communication with the ESP32-cam board. This is the command for the first flash FW to MCU.
|
||||||
|
|
||||||
|
```
|
||||||
|
./esptool -p /dev/ttya0 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --erase-all --flash_mode dio --flash_size 4MB --flash_freq 80m 0x1000 ESP32_PrusaConnectCam.ino.bootloader.bin 0x8000 ESP32_PrusaConnectCam.ino.partitions.bin 0x10000 ESP32_PrusaConnectCam.ino.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
This command contains the parameter **--erase-all**, which erases the entire flash in the MCU. So, for just updating the firmware, it is necessary to remove the parameter **--erase-all**; otherwise, the MCU configuration will also be deleted. The basic command list can be found [here](https://docs.espressif.com/projects/esptool/en/latest/esp32s3/esptool/basic-commands.html)
|
||||||
|
|
||||||
|
Here is the command for updating the firmware in the MCU without erasing the MCU configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
./esptool -p /dev/ttya0 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size 4MB --flash_freq 80m 0x1000 ESP32_PrusaConnectCam.ino.bootloader.bin 0x8000 ESP32_PrusaConnectCam.ino.partitions.bin 0x10000 ESP32_PrusaConnectCam.ino.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
Launching the esptool application may be different in different operating systems
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
Driver for CH340 USB to UART convert for Windows is for example [here](https://www.wch-ic.com/search?q=CH340&t=downloads) . An older version of the driver is for example [here](https://blog.laskakit.cz/wp-content/uploads/2020/03/CH341SER.zip). SW for FW flash (Flash Download Tools) is [here](https://www.espressif.com/en/support/download/other-tools)
|
||||||
|
|
||||||
|
<img src="how to flash chip select.jpg" width=25% height=25%>
|
||||||
|
|
||||||
|
It's necessary to erase the FLASH using the **ERASE** button before the first firmware flash.
|
||||||
|
|
||||||
|
<img src="how to flash.jpg" width=30% height=30%>
|
||||||
|
|
||||||
|
<a name="arduino_cfg"></a>
|
||||||
|
## How to compile software in the Arduino IDE
|
||||||
|
|
||||||
|
Board configuration in the Arduino IDE 2.3.2
|
||||||
|
- Tools -> Board -> ESP32 Arduino -> AI Thinker ESP32
|
||||||
|
- Tools -> Flash frequency -> 80MHz
|
||||||
|
- Tools -> Core Debug Level -> None
|
||||||
|
- Tools -> Erase all Flash Before Sketch Upload -> Disable **(first flash, new board = enable. otherwise = disable)**
|
||||||
|
- Tools -> Flash Mode -> DIO
|
||||||
|
- Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
||||||
|
|
||||||
|
When flashing the firmware to a new, empty ESP32-CAM device for the first time, it is necessary to use the 'Erase' function.
|
||||||
|
|
||||||
|
This can be found under **Tools** -> **Erase all Flash Before Sketch Upload** -> **Enable**.
|
||||||
|
|
||||||
|
After the initial firmware upload to the MCU, it's necessary to disable this option. If you do not disable this option, your camera configuration will continue to be erased from the flash memory after uploading new firmware from the Arduino IDE.
|
||||||
|
|
||||||
|
It is necessary to enable support for the correct board version in the file **mcu_cfg.h** after line 16.
|
||||||
|
|
||||||
|
<a name="factory_cfg"></a>
|
||||||
|
## How to reset configuration to factory settings
|
||||||
|
To reset the settings to factory defaults, follow these instructions:
|
||||||
|
|
||||||
|
<img src="factory_cfg.jpg" width=30% height=30%>
|
||||||
|
|
||||||
|
- Connect PIN **IO12** to **ground**.
|
||||||
|
- **Plug in** the power supply.
|
||||||
|
- Wait for **10 seconds**.
|
||||||
|
- After 10 seconds, the **FLASH LED will start flashing**.
|
||||||
|
- **Disconnect** PIN **IO12** from **ground** (but don't disconnect the power supply).
|
||||||
|
- After disconnecting **IO12** from **ground**, the **FLASH LED** will **stop flashing**, and the MCU will **automatically reboot**.
|
||||||
|
- Now the MCU is in the factory settings.
|
||||||
|
|
||||||
|
<a name="status_led"></a>
|
||||||
|
## Status LED
|
||||||
|
|
||||||
|
On the board, there is a status LED that provides a visual indicator of the module's current status
|
||||||
|
through blinking at defined intervals.
|
||||||
|
|
||||||
|
<img src="status_led.jpg" width=25% height=25%>
|
||||||
|
|
||||||
|
Upon module activation, the LED illuminates. After processor initialization, the LED exhibits different blinking intervals based on the current mode of the module
|
||||||
|
|
||||||
|
- **Service AP Mode only:** The LED blinks every **400 ms**, indicating the module's availability in service AP mode.
|
||||||
|
- **Connecting to WiFi AP:** While connecting to a WiFi Access Point, the LED blinks at intervals of **800 ms**.
|
||||||
|
- **Connected to WiFi Network:** Upon successful connection to a WiFi network, the LED blinks at intervals of **4000 ms**, signaling a stable connection.
|
||||||
|
- **Problematic State:** If an issue or error occurs, the LED accelerates its blinking to every **100 ms**.
|
||||||
|
|
||||||
|
The approximate boot time of the device is 15-20 seconds.
|
||||||
|
|
||||||
|
<a name="schematic"></a>
|
||||||
|
## Schematic for ESP32-cam board
|
||||||
|
|
||||||
|
<img src="ESP32-CAM-AI-Thinker-schematic-diagram.png" width=70% height=70%>
|
||||||
|
|
||||||
|
Board description
|
||||||
|
|
||||||
|
<img src="esp32-cam_parts.jpg" width=50% height=50%>
|
||||||
|
|
||||||
|
Pinout
|
||||||
|
|
||||||
|
<img src="pinout.png" width=50% height=50%>
|
||||||
|
|
||||||
|
<a name="led_issue"></a>
|
||||||
|
## FLASH LED issue
|
||||||
|
The board has a problem with the FLASH LED, as it lacks any current limitation for the LED. Consequently, frequent use of the FLASH LED can lead to malfunction, due to excessive current flow.
|
||||||
|
|
||||||
|
One simple solution is to connect an external LED via a relay, transistor, or MOSFET to the board, as shown in the next picture. Using a relay is not ideal, but it provides a simple solution.
|
||||||
|
|
||||||
|
<img src="relay_flash_bb.png" width=40% height=40%>
|
||||||
|
|
||||||
|
Another solution is to use an LED COB or a USB LED lamp. I utilized a board from a simple USB LED lamp. The transistor has a current limitation of 500mA, and my USB lamp has a current consumption of approximately 180mA. The original LED has a current consumption of 60-80mA. After calculation, the total current consumption is approximately 260mA, which falls within the current limitation of the transistor. Therefore, it is possible to solder the negative wire from the COB LED or the USB LED lamp to the transistor. The positive wire needs to be soldered to +5V.
|
||||||
|
|
||||||
|
This is my USB LED lamp
|
||||||
|
|
||||||
|
<img src="usb_lamp.jpg" width=40% height=40%>
|
||||||
|
|
||||||
|
The next step is to solder the negative wire from the LED lamp to the transistor collector, and the positive wire from the LED lamp to the +5V on the board.
|
||||||
|
|
||||||
|
<img src="esp32-cam_with_led_lamp.jpg" width=40% height=40%>
|
||||||
|
|
||||||
|
The third option is to solder a resistor between the collector of the transistor and the PCB. I used a 10-ohm resistor in a 0603 package. This option is more complicated for users with limited soldering experience.
|
||||||
|
|
||||||
|
<img src="esp32-cam_flash_led_resistor.jpg" width=40% height=40%>
|
||||||
|
|
||||||
|
<a name="ext_wifi"></a>
|
||||||
|
## External/internal WiFi antenna
|
||||||
|
|
||||||
|
The standard ESP32-CAM board utilizes an internal antenna on the PCB. However, this antenna can sometimes cause issues with the quality of the WiFi signal, leading to slow photo uploads to PrusaConnect or connectivity problems. Fortunately, there is an option to connect an external antenna. This requires changing the resistor position, as shown in the picture below. Then, you can use a 2.4GHz Wi-Fi cable with a U.FL to RP-SMA connector and a standard 2.4GHz WiFi antenna
|
||||||
|
|
||||||
|
<img src="esp32-cam_ext_ant.png" width=40% height=40%>
|
||||||
|
|
||||||
|
<a name="power_supply"></a>
|
||||||
|
## Power Supply
|
||||||
|
|
||||||
|
The device requires a 5V power supply, with a maximum current consumption of 2A. Power is supplied via a micro USB connector when using the original programmer.
|
||||||
|
|
||||||
|
<a name="ext_sens"></a>
|
||||||
|
## External temperature sensor DHT22/DHT11
|
||||||
|
|
||||||
|
Below you will find the wiring diagram for the DHT22 or DHT11 sensor.
|
||||||
|
|
||||||
|
| Camera board | DHT22/DHT11 |
|
||||||
|
|--------------|-------------|
|
||||||
|
| 3.3V | VCC |
|
||||||
|
| GND | GND |
|
||||||
|
| IO13 | Data |
|
||||||
|
|
||||||
|
<img src="ESP32-cam dht22_bb.png" width=40% height=40%>
|
||||||
|
|
||||||
|
<a name="issue"></a>
|
||||||
|
## Potential issue with this board
|
||||||
|
|
||||||
|
- The flash LED may fail after some time due to the absence of a current-limiting resistor.
|
||||||
|
- The WiFi signal quality on this board may be weaker compared to other boards and may degrade over time.
|
||||||
|
Before Width: | Height: | Size: 461 KiB After Width: | Height: | Size: 461 KiB |
|
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 260 KiB |
|
Before Width: | Height: | Size: 553 KiB After Width: | Height: | Size: 553 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 309 KiB After Width: | Height: | Size: 309 KiB |
|
Before Width: | Height: | Size: 572 KiB After Width: | Height: | Size: 572 KiB |
|
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 264 KiB |
|
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 440 KiB |
|
Before Width: | Height: | Size: 507 KiB After Width: | Height: | Size: 507 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 639 KiB After Width: | Height: | Size: 639 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 365 KiB After Width: | Height: | Size: 365 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
|
@ -0,0 +1,157 @@
|
||||||
|
#include "esp_camera.h"
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
|
||||||
|
// Ensure ESP32 Wrover Module or other board with PSRAM is selected
|
||||||
|
// Partial images will be transmitted if image exceeds buffer size
|
||||||
|
//
|
||||||
|
// You must select partition scheme from the board menu that has at least 3MB APP space.
|
||||||
|
// Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15
|
||||||
|
// seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Select camera model
|
||||||
|
// ===================
|
||||||
|
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
|
||||||
|
#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
|
||||||
|
//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
|
||||||
|
//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM
|
||||||
|
// ** Espressif Internal Boards **
|
||||||
|
//#define CAMERA_MODEL_ESP32_CAM_BOARD
|
||||||
|
//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
|
||||||
|
//#define CAMERA_MODEL_ESP32S3_CAM_LCD
|
||||||
|
//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM
|
||||||
|
#include "camera_pins.h"
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Enter your WiFi credentials
|
||||||
|
// ===========================
|
||||||
|
const char* ssid = "sparkleiot";
|
||||||
|
const char* password = "12345678";
|
||||||
|
|
||||||
|
void startCameraServer();
|
||||||
|
void setupLedFlash(int pin);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.setDebugOutput(true);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
camera_config_t config;
|
||||||
|
config.ledc_channel = LEDC_CHANNEL_0;
|
||||||
|
config.ledc_timer = LEDC_TIMER_0;
|
||||||
|
config.pin_d0 = Y2_GPIO_NUM;
|
||||||
|
config.pin_d1 = Y3_GPIO_NUM;
|
||||||
|
config.pin_d2 = Y4_GPIO_NUM;
|
||||||
|
config.pin_d3 = Y5_GPIO_NUM;
|
||||||
|
config.pin_d4 = Y6_GPIO_NUM;
|
||||||
|
config.pin_d5 = Y7_GPIO_NUM;
|
||||||
|
config.pin_d6 = Y8_GPIO_NUM;
|
||||||
|
config.pin_d7 = Y9_GPIO_NUM;
|
||||||
|
config.pin_xclk = XCLK_GPIO_NUM;
|
||||||
|
config.pin_pclk = PCLK_GPIO_NUM;
|
||||||
|
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||||
|
config.pin_href = HREF_GPIO_NUM;
|
||||||
|
config.pin_sccb_sda = SIOD_GPIO_NUM;
|
||||||
|
config.pin_sccb_scl = SIOC_GPIO_NUM;
|
||||||
|
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||||
|
config.pin_reset = RESET_GPIO_NUM;
|
||||||
|
config.xclk_freq_hz = 20000000;
|
||||||
|
config.frame_size = FRAMESIZE_QVGA;
|
||||||
|
//config.pixel_format = PIXFORMAT_JPEG; // for streaming
|
||||||
|
config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
|
||||||
|
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
|
||||||
|
config.fb_location = CAMERA_FB_IN_PSRAM;
|
||||||
|
config.jpeg_quality = 12;
|
||||||
|
config.fb_count = 1;
|
||||||
|
|
||||||
|
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
|
||||||
|
// for larger pre-allocated frame buffer.
|
||||||
|
if(config.pixel_format == PIXFORMAT_JPEG){
|
||||||
|
if(psramFound()){
|
||||||
|
config.jpeg_quality = 10;
|
||||||
|
config.fb_count = 2;
|
||||||
|
config.grab_mode = CAMERA_GRAB_LATEST;
|
||||||
|
} else {
|
||||||
|
// Limit the frame size when PSRAM is not available
|
||||||
|
config.frame_size = FRAMESIZE_SVGA;
|
||||||
|
config.fb_location = CAMERA_FB_IN_DRAM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Best option for face detection/recognition
|
||||||
|
config.frame_size = FRAMESIZE_QVGA;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
config.fb_count = 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_ESP_EYE)
|
||||||
|
pinMode(13, INPUT_PULLUP);
|
||||||
|
pinMode(14, INPUT_PULLUP);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// camera init
|
||||||
|
esp_err_t err = esp_camera_init(&config);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
Serial.printf("Camera init failed with error 0x%x", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_t * s = esp_camera_sensor_get();
|
||||||
|
// initial sensors are flipped vertically and colors are a bit saturated
|
||||||
|
if (s->id.PID == OV3660_PID) {
|
||||||
|
s->set_vflip(s, 1); // flip it back
|
||||||
|
s->set_brightness(s, 1); // up the brightness just a bit
|
||||||
|
s->set_saturation(s, -2); // lower the saturation
|
||||||
|
}
|
||||||
|
// drop down frame size for higher initial frame rate
|
||||||
|
if(config.pixel_format == PIXFORMAT_JPEG){
|
||||||
|
s->set_framesize(s, FRAMESIZE_QVGA);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||||
|
s->set_vflip(s, 1);
|
||||||
|
s->set_hmirror(s, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||||
|
s->set_vflip(s, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Setup LED FLash if LED pin is defined in camera_pins.h
|
||||||
|
#if defined(LED_GPIO_NUM)
|
||||||
|
setupLedFlash(LED_GPIO_NUM);
|
||||||
|
#endif
|
||||||
|
Serial.println("The device needs to be linked to a 2.4G router........");
|
||||||
|
Serial.println("SSSID:sparkleiot");
|
||||||
|
Serial.println("Password:12345678");
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
WiFi.setSleep(false);
|
||||||
|
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("WiFi connected");
|
||||||
|
|
||||||
|
startCameraServer();
|
||||||
|
|
||||||
|
Serial.print("Camera Ready! Use 'http://");
|
||||||
|
Serial.print(WiFi.localIP());
|
||||||
|
Serial.println("' to connect");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Do nothing. Everything is done in another task by the web server
|
||||||
|
delay(10000);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,318 @@
|
||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 21
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 19
|
||||||
|
#define Y4_GPIO_NUM 18
|
||||||
|
#define Y3_GPIO_NUM 5
|
||||||
|
#define Y2_GPIO_NUM 4
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP_EYE)
|
||||||
|
#define PWDN_GPIO_NUM 32
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 0
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 21
|
||||||
|
#define Y4_GPIO_NUM 19
|
||||||
|
#define Y3_GPIO_NUM 18
|
||||||
|
#define Y2_GPIO_NUM 5
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
// 4 for flash led or 33 for normal led
|
||||||
|
#define LED_GPIO_NUM 4
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 22
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 22
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#define LED_GPIO_NUM 2
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 17
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_UNITCAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||||
|
#define PWDN_GPIO_NUM 32
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 0
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 21
|
||||||
|
#define Y4_GPIO_NUM 19
|
||||||
|
#define Y3_GPIO_NUM 18
|
||||||
|
#define Y2_GPIO_NUM 5
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
// 4 for flash led or 33 for normal led
|
||||||
|
#define LED_GPIO_NUM 4
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL)
|
||||||
|
#define PWDN_GPIO_NUM 0
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 17
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_XIAO_ESP32S3)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 10
|
||||||
|
#define SIOD_GPIO_NUM 40
|
||||||
|
#define SIOC_GPIO_NUM 39
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 48
|
||||||
|
#define Y8_GPIO_NUM 11
|
||||||
|
#define Y7_GPIO_NUM 12
|
||||||
|
#define Y6_GPIO_NUM 14
|
||||||
|
#define Y5_GPIO_NUM 16
|
||||||
|
#define Y4_GPIO_NUM 18
|
||||||
|
#define Y3_GPIO_NUM 17
|
||||||
|
#define Y2_GPIO_NUM 15
|
||||||
|
#define VSYNC_GPIO_NUM 38
|
||||||
|
#define HREF_GPIO_NUM 47
|
||||||
|
#define PCLK_GPIO_NUM 13
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD)
|
||||||
|
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||||
|
#define USE_BOARD_HEADER 0
|
||||||
|
#define PWDN_GPIO_NUM 32
|
||||||
|
#define RESET_GPIO_NUM 33
|
||||||
|
#define XCLK_GPIO_NUM 4
|
||||||
|
#define SIOD_GPIO_NUM 18
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 36
|
||||||
|
#define Y8_GPIO_NUM 19
|
||||||
|
#define Y7_GPIO_NUM 21
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#if USE_BOARD_HEADER
|
||||||
|
#define Y5_GPIO_NUM 13
|
||||||
|
#else
|
||||||
|
#define Y5_GPIO_NUM 35
|
||||||
|
#endif
|
||||||
|
#define Y4_GPIO_NUM 14
|
||||||
|
#if USE_BOARD_HEADER
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#else
|
||||||
|
#define Y3_GPIO_NUM 13
|
||||||
|
#endif
|
||||||
|
#define Y2_GPIO_NUM 34
|
||||||
|
#define VSYNC_GPIO_NUM 5
|
||||||
|
#define HREF_GPIO_NUM 27
|
||||||
|
#define PCLK_GPIO_NUM 25
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 40
|
||||||
|
#define SIOD_GPIO_NUM 17
|
||||||
|
#define SIOC_GPIO_NUM 18
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 39
|
||||||
|
#define Y8_GPIO_NUM 41
|
||||||
|
#define Y7_GPIO_NUM 42
|
||||||
|
#define Y6_GPIO_NUM 12
|
||||||
|
#define Y5_GPIO_NUM 3
|
||||||
|
#define Y4_GPIO_NUM 14
|
||||||
|
#define Y3_GPIO_NUM 47
|
||||||
|
#define Y2_GPIO_NUM 13
|
||||||
|
#define VSYNC_GPIO_NUM 21
|
||||||
|
#define HREF_GPIO_NUM 38
|
||||||
|
#define PCLK_GPIO_NUM 11
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD)
|
||||||
|
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||||
|
#define USE_BOARD_HEADER 0
|
||||||
|
#define PWDN_GPIO_NUM 1
|
||||||
|
#define RESET_GPIO_NUM 2
|
||||||
|
#define XCLK_GPIO_NUM 42
|
||||||
|
#define SIOD_GPIO_NUM 41
|
||||||
|
#define SIOC_GPIO_NUM 18
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 16
|
||||||
|
#define Y8_GPIO_NUM 39
|
||||||
|
#define Y7_GPIO_NUM 40
|
||||||
|
#define Y6_GPIO_NUM 15
|
||||||
|
#if USE_BOARD_HEADER
|
||||||
|
#define Y5_GPIO_NUM 12
|
||||||
|
#else
|
||||||
|
#define Y5_GPIO_NUM 13
|
||||||
|
#endif
|
||||||
|
#define Y4_GPIO_NUM 5
|
||||||
|
#if USE_BOARD_HEADER
|
||||||
|
#define Y3_GPIO_NUM 13
|
||||||
|
#else
|
||||||
|
#define Y3_GPIO_NUM 12
|
||||||
|
#endif
|
||||||
|
#define Y2_GPIO_NUM 14
|
||||||
|
#define VSYNC_GPIO_NUM 38
|
||||||
|
#define HREF_GPIO_NUM 4
|
||||||
|
#define PCLK_GPIO_NUM 3
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 15
|
||||||
|
#define SIOD_GPIO_NUM 4
|
||||||
|
#define SIOC_GPIO_NUM 5
|
||||||
|
|
||||||
|
#define Y2_GPIO_NUM 11
|
||||||
|
#define Y3_GPIO_NUM 9
|
||||||
|
#define Y4_GPIO_NUM 8
|
||||||
|
#define Y5_GPIO_NUM 10
|
||||||
|
#define Y6_GPIO_NUM 12
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y8_GPIO_NUM 17
|
||||||
|
#define Y9_GPIO_NUM 16
|
||||||
|
|
||||||
|
#define VSYNC_GPIO_NUM 6
|
||||||
|
#define HREF_GPIO_NUM 7
|
||||||
|
#define PCLK_GPIO_NUM 13
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3) || defined(CAMERA_MODEL_DFRobot_Romeo_ESP32S3)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 45
|
||||||
|
#define SIOD_GPIO_NUM 1
|
||||||
|
#define SIOC_GPIO_NUM 2
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 48
|
||||||
|
#define Y8_GPIO_NUM 46
|
||||||
|
#define Y7_GPIO_NUM 8
|
||||||
|
#define Y6_GPIO_NUM 7
|
||||||
|
#define Y5_GPIO_NUM 4
|
||||||
|
#define Y4_GPIO_NUM 41
|
||||||
|
#define Y3_GPIO_NUM 40
|
||||||
|
#define Y2_GPIO_NUM 39
|
||||||
|
#define VSYNC_GPIO_NUM 6
|
||||||
|
#define HREF_GPIO_NUM 42
|
||||||
|
#define PCLK_GPIO_NUM 5
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Camera model not selected"
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x5000,
|
||||||
|
otadata, data, ota, 0xe000, 0x2000,
|
||||||
|
app0, app, ota_0, 0x10000, 0x3d0000,
|
||||||
|
fr, data, , 0x3e0000, 0x20000,
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
#include "esp_camera.h"
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
|
||||||
|
// Ensure ESP32 Wrover Module or other board with PSRAM is selected
|
||||||
|
// Partial images will be transmitted if image exceeds buffer size
|
||||||
|
//
|
||||||
|
// You must select partition scheme from the board menu that has at least 3MB APP space.
|
||||||
|
// Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15
|
||||||
|
// seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Select camera model
|
||||||
|
// ===================
|
||||||
|
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
|
||||||
|
//define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
|
||||||
|
#define CAMERA_MODEL_AI_THINKER // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
|
||||||
|
//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM
|
||||||
|
// ** Espressif Internal Boards **
|
||||||
|
//#define CAMERA_MODEL_ESP32_CAM_BOARD
|
||||||
|
//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
|
||||||
|
//#define CAMERA_MODEL_ESP32S3_CAM_LCD
|
||||||
|
//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM
|
||||||
|
#include "camera_pins.h"
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Enter your WiFi credentials
|
||||||
|
// ===========================
|
||||||
|
const char* ssid = "sparkleiot";
|
||||||
|
const char* password = "12345678";
|
||||||
|
|
||||||
|
void startCameraServer();
|
||||||
|
void setupLedFlash(int pin);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.setDebugOutput(true);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
camera_config_t config;
|
||||||
|
config.ledc_channel = LEDC_CHANNEL_0;
|
||||||
|
config.ledc_timer = LEDC_TIMER_0;
|
||||||
|
config.pin_d0 = Y2_GPIO_NUM;
|
||||||
|
config.pin_d1 = Y3_GPIO_NUM;
|
||||||
|
config.pin_d2 = Y4_GPIO_NUM;
|
||||||
|
config.pin_d3 = Y5_GPIO_NUM;
|
||||||
|
config.pin_d4 = Y6_GPIO_NUM;
|
||||||
|
config.pin_d5 = Y7_GPIO_NUM;
|
||||||
|
config.pin_d6 = Y8_GPIO_NUM;
|
||||||
|
config.pin_d7 = Y9_GPIO_NUM;
|
||||||
|
config.pin_xclk = XCLK_GPIO_NUM;
|
||||||
|
config.pin_pclk = PCLK_GPIO_NUM;
|
||||||
|
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||||
|
config.pin_href = HREF_GPIO_NUM;
|
||||||
|
config.pin_sccb_sda = SIOD_GPIO_NUM;
|
||||||
|
config.pin_sccb_scl = SIOC_GPIO_NUM;
|
||||||
|
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||||
|
config.pin_reset = RESET_GPIO_NUM;
|
||||||
|
config.xclk_freq_hz = 20000000;
|
||||||
|
config.frame_size = FRAMESIZE_QVGA;
|
||||||
|
//config.pixel_format = PIXFORMAT_JPEG; // for streaming
|
||||||
|
config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
|
||||||
|
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
|
||||||
|
config.fb_location = CAMERA_FB_IN_PSRAM;
|
||||||
|
config.jpeg_quality = 12;
|
||||||
|
config.fb_count = 1;
|
||||||
|
|
||||||
|
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
|
||||||
|
// for larger pre-allocated frame buffer.
|
||||||
|
if(config.pixel_format == PIXFORMAT_JPEG){
|
||||||
|
if(psramFound()){
|
||||||
|
config.jpeg_quality = 10;
|
||||||
|
config.fb_count = 2;
|
||||||
|
config.grab_mode = CAMERA_GRAB_LATEST;
|
||||||
|
} else {
|
||||||
|
// Limit the frame size when PSRAM is not available
|
||||||
|
config.frame_size = FRAMESIZE_SVGA;
|
||||||
|
config.fb_location = CAMERA_FB_IN_DRAM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Best option for face detection/recognition
|
||||||
|
config.frame_size = FRAMESIZE_QVGA;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
config.fb_count = 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_ESP_EYE)
|
||||||
|
pinMode(13, INPUT_PULLUP);
|
||||||
|
pinMode(14, INPUT_PULLUP);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// camera init
|
||||||
|
esp_err_t err = esp_camera_init(&config);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
Serial.printf("Camera init failed with error 0x%x", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_t * s = esp_camera_sensor_get();
|
||||||
|
// initial sensors are flipped vertically and colors are a bit saturated
|
||||||
|
if (s->id.PID == OV3660_PID) {
|
||||||
|
s->set_vflip(s, 1); // flip it back
|
||||||
|
s->set_brightness(s, 1); // up the brightness just a bit
|
||||||
|
s->set_saturation(s, -2); // lower the saturation
|
||||||
|
}
|
||||||
|
// drop down frame size for higher initial frame rate
|
||||||
|
if(config.pixel_format == PIXFORMAT_JPEG){
|
||||||
|
s->set_framesize(s, FRAMESIZE_QVGA);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||||
|
s->set_vflip(s, 1);
|
||||||
|
s->set_hmirror(s, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||||
|
s->set_vflip(s, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Setup LED FLash if LED pin is defined in camera_pins.h
|
||||||
|
#if defined(LED_GPIO_NUM)
|
||||||
|
setupLedFlash(LED_GPIO_NUM);
|
||||||
|
#endif
|
||||||
|
Serial.println("The device needs to be linked to a 2.4G router........");
|
||||||
|
Serial.println("SSSID:sparkleiot");
|
||||||
|
Serial.println("Password:12345678");
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
WiFi.setSleep(false);
|
||||||
|
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("WiFi connected");
|
||||||
|
|
||||||
|
startCameraServer();
|
||||||
|
|
||||||
|
Serial.print("Camera Ready! Use 'http://");
|
||||||
|
Serial.print(WiFi.localIP());
|
||||||
|
Serial.println("' to connect");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Do nothing. Everything is done in another task by the web server
|
||||||
|
delay(10000);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,318 @@
|
||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 21
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 19
|
||||||
|
#define Y4_GPIO_NUM 18
|
||||||
|
#define Y3_GPIO_NUM 5
|
||||||
|
#define Y2_GPIO_NUM 4
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP_EYE)
|
||||||
|
#define PWDN_GPIO_NUM 32
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 0
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 21
|
||||||
|
#define Y4_GPIO_NUM 19
|
||||||
|
#define Y3_GPIO_NUM 18
|
||||||
|
#define Y2_GPIO_NUM 5
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
// 4 for flash led or 33 for normal led
|
||||||
|
#define LED_GPIO_NUM 4
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 22
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 22
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#define LED_GPIO_NUM 2
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 17
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_UNITCAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||||
|
#define PWDN_GPIO_NUM 32
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 0
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 21
|
||||||
|
#define Y4_GPIO_NUM 19
|
||||||
|
#define Y3_GPIO_NUM 18
|
||||||
|
#define Y2_GPIO_NUM 5
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
// 4 for flash led or 33 for normal led
|
||||||
|
#define LED_GPIO_NUM 4
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL)
|
||||||
|
#define PWDN_GPIO_NUM 0
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 17
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_XIAO_ESP32S3)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 10
|
||||||
|
#define SIOD_GPIO_NUM 40
|
||||||
|
#define SIOC_GPIO_NUM 39
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 48
|
||||||
|
#define Y8_GPIO_NUM 11
|
||||||
|
#define Y7_GPIO_NUM 12
|
||||||
|
#define Y6_GPIO_NUM 14
|
||||||
|
#define Y5_GPIO_NUM 16
|
||||||
|
#define Y4_GPIO_NUM 18
|
||||||
|
#define Y3_GPIO_NUM 17
|
||||||
|
#define Y2_GPIO_NUM 15
|
||||||
|
#define VSYNC_GPIO_NUM 38
|
||||||
|
#define HREF_GPIO_NUM 47
|
||||||
|
#define PCLK_GPIO_NUM 13
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD)
|
||||||
|
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||||
|
#define USE_BOARD_HEADER 0
|
||||||
|
#define PWDN_GPIO_NUM 32
|
||||||
|
#define RESET_GPIO_NUM 33
|
||||||
|
#define XCLK_GPIO_NUM 4
|
||||||
|
#define SIOD_GPIO_NUM 18
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 36
|
||||||
|
#define Y8_GPIO_NUM 19
|
||||||
|
#define Y7_GPIO_NUM 21
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#if USE_BOARD_HEADER
|
||||||
|
#define Y5_GPIO_NUM 13
|
||||||
|
#else
|
||||||
|
#define Y5_GPIO_NUM 35
|
||||||
|
#endif
|
||||||
|
#define Y4_GPIO_NUM 14
|
||||||
|
#if USE_BOARD_HEADER
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#else
|
||||||
|
#define Y3_GPIO_NUM 13
|
||||||
|
#endif
|
||||||
|
#define Y2_GPIO_NUM 34
|
||||||
|
#define VSYNC_GPIO_NUM 5
|
||||||
|
#define HREF_GPIO_NUM 27
|
||||||
|
#define PCLK_GPIO_NUM 25
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 40
|
||||||
|
#define SIOD_GPIO_NUM 17
|
||||||
|
#define SIOC_GPIO_NUM 18
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 39
|
||||||
|
#define Y8_GPIO_NUM 41
|
||||||
|
#define Y7_GPIO_NUM 42
|
||||||
|
#define Y6_GPIO_NUM 12
|
||||||
|
#define Y5_GPIO_NUM 3
|
||||||
|
#define Y4_GPIO_NUM 14
|
||||||
|
#define Y3_GPIO_NUM 47
|
||||||
|
#define Y2_GPIO_NUM 13
|
||||||
|
#define VSYNC_GPIO_NUM 21
|
||||||
|
#define HREF_GPIO_NUM 38
|
||||||
|
#define PCLK_GPIO_NUM 11
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD)
|
||||||
|
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||||
|
#define USE_BOARD_HEADER 0
|
||||||
|
#define PWDN_GPIO_NUM 1
|
||||||
|
#define RESET_GPIO_NUM 2
|
||||||
|
#define XCLK_GPIO_NUM 42
|
||||||
|
#define SIOD_GPIO_NUM 41
|
||||||
|
#define SIOC_GPIO_NUM 18
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 16
|
||||||
|
#define Y8_GPIO_NUM 39
|
||||||
|
#define Y7_GPIO_NUM 40
|
||||||
|
#define Y6_GPIO_NUM 15
|
||||||
|
#if USE_BOARD_HEADER
|
||||||
|
#define Y5_GPIO_NUM 12
|
||||||
|
#else
|
||||||
|
#define Y5_GPIO_NUM 13
|
||||||
|
#endif
|
||||||
|
#define Y4_GPIO_NUM 5
|
||||||
|
#if USE_BOARD_HEADER
|
||||||
|
#define Y3_GPIO_NUM 13
|
||||||
|
#else
|
||||||
|
#define Y3_GPIO_NUM 12
|
||||||
|
#endif
|
||||||
|
#define Y2_GPIO_NUM 14
|
||||||
|
#define VSYNC_GPIO_NUM 38
|
||||||
|
#define HREF_GPIO_NUM 4
|
||||||
|
#define PCLK_GPIO_NUM 3
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 15
|
||||||
|
#define SIOD_GPIO_NUM 4
|
||||||
|
#define SIOC_GPIO_NUM 5
|
||||||
|
|
||||||
|
#define Y2_GPIO_NUM 11
|
||||||
|
#define Y3_GPIO_NUM 9
|
||||||
|
#define Y4_GPIO_NUM 8
|
||||||
|
#define Y5_GPIO_NUM 10
|
||||||
|
#define Y6_GPIO_NUM 12
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y8_GPIO_NUM 17
|
||||||
|
#define Y9_GPIO_NUM 16
|
||||||
|
|
||||||
|
#define VSYNC_GPIO_NUM 6
|
||||||
|
#define HREF_GPIO_NUM 7
|
||||||
|
#define PCLK_GPIO_NUM 13
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3) || defined(CAMERA_MODEL_DFRobot_Romeo_ESP32S3)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 45
|
||||||
|
#define SIOD_GPIO_NUM 1
|
||||||
|
#define SIOC_GPIO_NUM 2
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 48
|
||||||
|
#define Y8_GPIO_NUM 46
|
||||||
|
#define Y7_GPIO_NUM 8
|
||||||
|
#define Y6_GPIO_NUM 7
|
||||||
|
#define Y5_GPIO_NUM 4
|
||||||
|
#define Y4_GPIO_NUM 41
|
||||||
|
#define Y3_GPIO_NUM 40
|
||||||
|
#define Y2_GPIO_NUM 39
|
||||||
|
#define VSYNC_GPIO_NUM 6
|
||||||
|
#define HREF_GPIO_NUM 42
|
||||||
|
#define PCLK_GPIO_NUM 5
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Camera model not selected"
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x5000,
|
||||||
|
otadata, data, ota, 0xe000, 0x2000,
|
||||||
|
app0, app, ota_0, 0x10000, 0x3d0000,
|
||||||
|
fr, data, , 0x3e0000, 0x20000,
|
||||||
|
|
After Width: | Height: | Size: 60 KiB |
|
|
@ -0,0 +1,200 @@
|
||||||
|
# ESP32-S3-CAM
|
||||||
|
|
||||||
|
What we need for functionality
|
||||||
|
- ESP32-S3-CAM board with OV2640 camera module [ here ](#esp32)
|
||||||
|
- Supported camera modules [here](#cam_modules)
|
||||||
|
- Module board version [here](#different_mcu)
|
||||||
|
- How to flash binary files to board from Linux/MAC/Windows [ here ](#flash_fw)
|
||||||
|
- How to compile software in the Arduino IDE [ here ](#arduino_cfg)
|
||||||
|
- How to reset the configuration to factory settings [here](#factory_cfg)
|
||||||
|
- Status LED [ here ](#status_led)
|
||||||
|
- Schematic main board is [here](#schematic)
|
||||||
|
- External FLASH LED [here](#led_issue)
|
||||||
|
- Power supply [here](#power_supply)
|
||||||
|
- External temperature sensor DHT22/DHT11 [here](#ext_sens)
|
||||||
|
- Potential issue [here](#issue)
|
||||||
|
|
||||||
|
<a name="esp32"></a>
|
||||||
|
## ESP32-S3-CAM
|
||||||
|
|
||||||
|
Basic information:
|
||||||
|
- Onboard RGB LED (most likely ws2812b)
|
||||||
|
- Option connecting external FLASH LED
|
||||||
|
- Micro SD card slot
|
||||||
|
- Internal or External WiFi antenna
|
||||||
|
- 16MB FLASH and 8MB external PSRAM
|
||||||
|
- 520 KB SRAM
|
||||||
|
- Excellent WiFi signal
|
||||||
|
- There is no official documentation for this module.
|
||||||
|
- Additional HW must be purchased for programming
|
||||||
|
|
||||||
|
This is a module with an ESP32-S3 processor. It is a dimensional copy of the ESP32-CAM board by AiThinker. The board has the same dimensions but features a more powerful ESP32-S3 processor and an RGB LED for illumination. The LED for illumination is likely of the WS2812B type. There is no official documentation or circuit diagram available for this board. The camera module consists of two boards: the main board with the WiFi MCU, camera, micro SD card slot, and LED for illumination, and a second board used for programming that has a micro USB connector. Board pineout it's not same as on the AiThinker ESP32-CAM.
|
||||||
|
|
||||||
|
<img src="board2.png" width=30% height=30%>
|
||||||
|
|
||||||
|
<a name="cam_modules"></a>
|
||||||
|
## Supported camera modules
|
||||||
|
|
||||||
|
It's necessary to use a camera version **OV2640**. If using a different camera, modification of the camera's pinout can be needed, or some camera settings may not work correctly. We recommend to use a camera module with a viewing angle of 120° or 160°.
|
||||||
|
|
||||||
|
These are currently known or tested camera modules:
|
||||||
|
|
||||||
|
| Camera chip | FOV | Resolution | Tested | Works | Description |
|
||||||
|
|-------------|------|------------|--------|-------|------------------------------------------|
|
||||||
|
| OV2640 | 66° | 2MP | Yes | Yes | Recommended. Standard camera module |
|
||||||
|
| OV2640 | 120° | 2MP | Yes | Yes | Recommended |
|
||||||
|
| OV2640 | 160° | 2MP | Yes | Yes | Recommended |
|
||||||
|
|
||||||
|
<a name="flash_fw"></a>
|
||||||
|
## How to flash binary files to board from Linux/MAC/Windows
|
||||||
|
|
||||||
|
#### Partitions table for flashing FW
|
||||||
|
|
||||||
|
However, for uploading the firmware, it's important to use this configuration of addresses and files:
|
||||||
|
|
||||||
|
ZIP file with build binary files: **esp32-s3-cam.zip**
|
||||||
|
|
||||||
|
- address 0x0 - ESP32_PrusaConnectCam.ino.bootloader.bin
|
||||||
|
- address 0x8000 - ESP32_PrusaConnectCam.ino.partitions.bin
|
||||||
|
- address 0x10000 - ESP32_PrusaConnectCam.ino.bin
|
||||||
|
|
||||||
|
**It is important to download the correct binary files! Each type of camera has its own ZIP archive with files for uploading the firmware.**
|
||||||
|
|
||||||
|
#### Linux/MAC
|
||||||
|
|
||||||
|
You must use the console to upload the firmware on the MAC or Linux platform. First, ensure you have installed esptool for Python. You can find it on the manufacturer's website, ESPRESSIF, [here](https://docs.espressif.com/projects/esp-at/en/latest/esp32/Get_Started/Downloading_guide.html#linux-or-macos).
|
||||||
|
|
||||||
|
And command for FLASH FW is here, where **/dev/ttya0** is your serial interface for communication with the ESP32-cam board. This is the command for the first flash FW to MCU.
|
||||||
|
|
||||||
|
```
|
||||||
|
./esptool --chip esp32s3 -p /dev/ttya0 -b 921600 --before default_reset --after hard_reset write_flash --erase-all --flash_mode dio --flash_size 16MB --flash_freq 80m 0x0 ESP32_PrusaConnectCam.ino.bootloader.bin 0x8000 ESP32_PrusaConnectCam.ino.partitions.bin 0x10000 ESP32_PrusaConnectCam.ino.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
This command contains the parameter **--erase-all**, which erases the entire flash in the MCU. So, for just updating the firmware, it is necessary to remove the parameter **--erase-all**; otherwise, the MCU configuration will also be deleted. The basic command list can be found [here](https://docs.espressif.com/projects/esptool/en/latest/esp32s3/esptool/basic-commands.html)
|
||||||
|
|
||||||
|
Here is the command for updating the firmware in the MCU without erasing the MCU configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
./esptool --chip esp32s3 -p /dev/ttya0 -b 921600 --before default_reset --after hard_reset write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m 0x0 ESP32_PrusaConnectCam.ino.bootloader.bin 0x8000 ESP32_PrusaConnectCam.ino.partitions.bin 0x10000 ESP32_PrusaConnectCam.ino.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
Launching the esptool application may be different in different operating systems
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
The driver should be installed automatically by Windows. SW for FW flash (Flash Download Tools) is [here](https://www.espressif.com/en/support/download/other-tools)
|
||||||
|
|
||||||
|
In the first step, you need to open the application **flash download tool**, and select MCU version
|
||||||
|
|
||||||
|
<img src="chip_select.jpg" width=25% height=25%>
|
||||||
|
|
||||||
|
Then, select the communication port. It's necessary to erase the FLASH using the **ERASE** button before the first firmware flash.
|
||||||
|
|
||||||
|
<img src="fw_flash.jpg" width=30% height=30%>
|
||||||
|
|
||||||
|
<a name="arduino_cfg"></a>
|
||||||
|
## How to compile software in the Arduino IDE
|
||||||
|
|
||||||
|
Board configuration in the Arduino IDE 2.3.2
|
||||||
|
- Tools -> Board -> ESP32 Arduino -> ESP32S3 Dev Module
|
||||||
|
- Tools -> USB CDC on BOOT -> Disable
|
||||||
|
- Tools -> CPU Frequency -> 240MHz (WiFi/BT)
|
||||||
|
- Tools -> Core debug level -> None
|
||||||
|
- Tools -> USB DFU on BOOT -> Disable
|
||||||
|
- Tools -> Erase all Flash Before Sketch Upload -> Disable (first flash, new board = enable. otherwise = disable)
|
||||||
|
- Tools -> Events Run On -> Core 1
|
||||||
|
- Tools -> Flash Mode -> DIO 80MHz
|
||||||
|
- Tools -> Flash Size -> 16MB
|
||||||
|
- Tools -> Jtag Adapter -> Disable
|
||||||
|
- Tools -> Arduino Runs On -> Core 1
|
||||||
|
- Tools -> USB Firmware MSC On Boot -> Disable
|
||||||
|
- Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
|
||||||
|
- Tools -> PSRAM -> OPI PSRAM
|
||||||
|
- Tools -> Upload Mode -> UART0 / Hardware CDC
|
||||||
|
- Tools -> Upload Speed -> 921600
|
||||||
|
- Tools -> USB Mode -> Hardware CDC and JTAG
|
||||||
|
- Tools -> Zigbee mode -> Disable
|
||||||
|
|
||||||
|
When flashing the firmware to a new, empty ESP32-S3-CAM Sense device for the first time, it is necessary to use the 'Erase' function.
|
||||||
|
|
||||||
|
This can be found under **Tools** -> **Erase all Flash Before Sketch Upload** -> **Enable**.
|
||||||
|
|
||||||
|
After the initial firmware upload to the MCU, it's necessary to disable this option. If you do not disable this option, your camera configuration will continue to be erased from the flash memory after uploading new firmware from the Arduino IDE.
|
||||||
|
|
||||||
|
It is necessary to enable support for the correct board version in the file **mcu_cfg.h** after line 16.
|
||||||
|
|
||||||
|
<a name="factory_cfg"></a>
|
||||||
|
## How to reset configuration to factory settings
|
||||||
|
To reset the settings to factory defaults, follow these instructions:
|
||||||
|
|
||||||
|
<img src="sw_reset.png" width=30% height=30%>
|
||||||
|
|
||||||
|
- Connect PIN **GPIO14** to **ground**.
|
||||||
|
- **Plug in** the power supply.
|
||||||
|
- Wait for **10 seconds**.
|
||||||
|
- After 10 seconds, the **FLASH LED will start flashing**.
|
||||||
|
- **Disconnect** PIN **GPIO14** from **ground** (but don't disconnect the power supply).
|
||||||
|
- After disconnecting **GPIO14** from **ground**, the **FLASH LED** will **stop flashing**, and the MCU will **automatically reboot**.
|
||||||
|
- Now the MCU is in the factory settings.
|
||||||
|
|
||||||
|
<a name="status_led"></a>
|
||||||
|
## Status LED
|
||||||
|
|
||||||
|
On the board, there is a status LED that provides a visual indicator of the module's current status
|
||||||
|
through blinking at defined intervals.
|
||||||
|
|
||||||
|
<img src="status_led.png" width=25% height=25%>
|
||||||
|
|
||||||
|
Upon module activation, the LED illuminates. After processor initialization, the LED exhibits different blinking intervals based on the current mode of the module
|
||||||
|
|
||||||
|
- **Service AP Mode only:** The LED blinks every **400 ms**, indicating the module's availability in service AP mode.
|
||||||
|
- **Connecting to WiFi AP:** While connecting to a WiFi Access Point, the LED blinks at intervals of **800 ms**.
|
||||||
|
- **Connected to WiFi Network:** Upon successful connection to a WiFi network, the LED blinks at intervals of **4000 ms**, signaling a stable connection.
|
||||||
|
- **Problematic State:** If an issue or error occurs, the LED accelerates its blinking to every **100 ms**.
|
||||||
|
|
||||||
|
The approximate boot time of the device is 15-20 seconds.
|
||||||
|
|
||||||
|
<a name="schematic"></a>
|
||||||
|
## Schematic for ESP32-S3-CAM
|
||||||
|
|
||||||
|
For this board, I was unable to find any official documentation or pinout. The following pinout was determined from PCB analysis.
|
||||||
|
|
||||||
|
Pinout
|
||||||
|
|
||||||
|
<img src="pinout.drawio.png" width=50% height=50%>
|
||||||
|
|
||||||
|
<a name="led_issue"></a>
|
||||||
|
## FLASH LED
|
||||||
|
|
||||||
|
This board version have RGB **FLASH LED** on the board (most likely ws2812b). It is still possible to connect an external LED for illumination. The wiring is shown in the image below.
|
||||||
|
|
||||||
|
<img src="relay_flash_bb.png" width=30% height=30%>
|
||||||
|
|
||||||
|
For the external LED is in the SW used **GPIO pin 47**.
|
||||||
|
|
||||||
|
<img src="ext_led_pins.png" width=30% height=30%>
|
||||||
|
|
||||||
|
However, a 5mm LED can also be connected directly. **CAUTION**: The digital GPIO output from the ESP32-S3-CAM board has a current limitation of a **maximum of 40mA**! Therefore, it is recommended to switch the LED using a **transistor** rather than directly through the GPIO pin. Improper use of the GPIO pin can lead to permanent damage.
|
||||||
|
|
||||||
|
<a name="power_supply"></a>
|
||||||
|
## Power Supply
|
||||||
|
|
||||||
|
The device requires a 5V power supply, with a maximum current consumption of 2A. Power is supplied via a micro USB connector when using the original programmer.
|
||||||
|
|
||||||
|
<a name="ext_sens"></a>
|
||||||
|
## External temperature sensor DHT22/DHT11
|
||||||
|
|
||||||
|
Below you will find the wiring diagram for the DHT22 or DHT11 sensor.
|
||||||
|
|
||||||
|
| Camera board | DHT22/DHT11 |
|
||||||
|
|--------------|-------------|
|
||||||
|
| 3.3V | VCC |
|
||||||
|
| GND | GND |
|
||||||
|
| GPIO20 | Data |
|
||||||
|
|
||||||
|
<img src="ESP32-cam dht22_bb.png" width=40% height=40%>
|
||||||
|
|
||||||
|
<a name="issue"></a>
|
||||||
|
## Potential issue with this board
|
||||||
|
|
||||||
|
- Slow WEB page loading during first 1 minutes after MCU start
|
||||||
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 538 KiB |
|
After Width: | Height: | Size: 675 KiB |
|
After Width: | Height: | Size: 297 KiB |