diff --git a/examples/Camera/motion-snapshot-capture/camera_pins.h b/examples/Camera/motion-snapshot-capture/camera_pins.h new file mode 100644 index 0000000..dbb01e3 --- /dev/null +++ b/examples/Camera/motion-snapshot-capture/camera_pins.h @@ -0,0 +1,563 @@ + +#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 -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 37 +#define Y7_GPIO_NUM 38 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 35 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 13 +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#define LED_GPIO_NUM 22 + +#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_M5STACK_CAMS3_UNIT) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 21 +#define XCLK_GPIO_NUM 11 +#define SIOD_GPIO_NUM 17 +#define SIOC_GPIO_NUM 41 + +#define Y9_GPIO_NUM 13 +#define Y8_GPIO_NUM 4 +#define Y7_GPIO_NUM 10 +#define Y6_GPIO_NUM 5 +#define Y5_GPIO_NUM 7 +#define Y4_GPIO_NUM 16 +#define Y3_GPIO_NUM 15 +#define Y2_GPIO_NUM 6 +#define VSYNC_GPIO_NUM 42 +#define HREF_GPIO_NUM 18 +#define PCLK_GPIO_NUM 12 + +#define LED_GPIO_NUM 14 + +#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_TTGO_T_V16_VERSION) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 15 +#define Y7_GPIO_NUM 12 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 35 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 13 +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#define AS312_PIN 19 +#define BUTTON_1 0 + +#define I2C_SDA 21 +#define I2C_SCL 22 + +#define SSD130_MODLE_TYPE 0 // 0 : GEOMETRY_128_64 // 1: GEOMETRY_128_32 + +#define IIS_SCK 26 +#define IIS_WS 32 +#define IIS_DOUT 33 + +#elif defined(CAMERA_MODEL_TTGO_T_V05_VERSION) + +#define PWDN_GPIO_NUM 26 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 32 +#define SIOD_GPIO_NUM 13 +#define SIOC_GPIO_NUM 12 + +#define Y9_GPIO_NUM 39 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 23 +#define Y6_GPIO_NUM 18 +#define Y5_GPIO_NUM 15 +#define Y4_GPIO_NUM 4 +#define Y3_GPIO_NUM 14 +#define Y2_GPIO_NUM 5 + +#define VSYNC_GPIO_NUM 27 +#define HREF_GPIO_NUM 25 +#define PCLK_GPIO_NUM 19 + +#define AS312_PIN 33 +#define BUTTON_1 34 + +#define I2C_SDA 21 +#define I2C_SCL 22 + +#define SSD130_MODLE_TYPE 0 // 0 : GEOMETRY_128_64 // 1: GEOMETRY_128_32 + + +#elif defined(CAMERA_MODEL_TTGO_T_JORNAL_VERSION) + +#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 + +#define I2C_SDA 14 +#define I2C_SCL 13 + +#define BUTTON_1 32 + +#define SSD130_MODLE_TYPE 1 // 0 : GEOMETRY_128_64 // 1: GEOMETRY_128_32 + +#elif defined(CAMERA_MODEL_TTGO_T_PLUS_VERSION) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 37 +#define Y7_GPIO_NUM 38 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 35 +#define Y4_GPIO_NUM 26 +#define Y3_GPIO_NUM 13 +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#define I2C_SDA 18 +#define I2C_SCL 23 + +#define IIS_SCK 14 +#define IIS_WS 32 +#define IIS_DOUT 33 + +#define TFT_CS_PIN 12 +#define TFT_DC_PIN 15 +#define TFT_MOSI_PIN 19 +#define TFT_MISO_PIN 22 +#define TFT_SCLK_PIN 21 +#define TFT_BL_PIN 2 + +#define SDCARD_CS_PIN 0 + +#define ENABLE_IP5306 +#define ENABLE_TFT + +#elif defined(CAMERA_MODEL_TTGO_T_V162_VERSION) + +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 37 +#define Y7_GPIO_NUM 38 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 35 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 13 +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#define I2C_SDA 21 +#define I2C_SCL 22 + +#define BUTTON_1 15 + +#define SSD130_MODLE_TYPE 0 // 0 : GEOMETRY_128_64 // 1: GEOMETRY_128_32 + +#define AS312_PIN 19 //not rtc io ,can't form deepsleep wakeup + +#define IIS_SCK 26 +#define IIS_WS 32 +#define IIS_DOUT 33 + +#define ENABLE_IP5306 + +#elif defined(CAMERA_MODEL_TTGO_T_MINI_VERSION) + +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 32 +#define SIOD_GPIO_NUM 13 +#define SIOC_GPIO_NUM 12 + +#define Y9_GPIO_NUM 39 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 38 +#define Y6_GPIO_NUM 37 +#define Y5_GPIO_NUM 15 +#define Y4_GPIO_NUM 4 +#define Y3_GPIO_NUM 14 +#define Y2_GPIO_NUM 5 + +#define VSYNC_GPIO_NUM 27 +#define HREF_GPIO_NUM 25 +#define PCLK_GPIO_NUM 19 +#define CAMERA_PWR_PIN 26 + +#define I2C_SDA 21 +#define I2C_SCL 22 + +#define BUTTON_1 33 + +#define POWER_CONTROL_PIN 26 + +#define ENABLE_AXP192 + +#elif defined(CAMERA_MODEL_TTGO_T_V17_VERSION) + +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 32 +#define SIOD_GPIO_NUM 13 +#define SIOC_GPIO_NUM 12 + +#define Y9_GPIO_NUM 39 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 23 +#define Y6_GPIO_NUM 18 +#define Y5_GPIO_NUM 15 +#define Y4_GPIO_NUM 4 +#define Y3_GPIO_NUM 14 +#define Y2_GPIO_NUM 5 + +#define VSYNC_GPIO_NUM 27 +#define HREF_GPIO_NUM 25 +#define PCLK_GPIO_NUM 19 + +#define I2C_SDA 21 +#define I2C_SCL 22 + +#define BUTTON_1 34 + +#define SSD130_MODLE_TYPE 0 // 0 : GEOMETRY_128_64 // 1: GEOMETRY_128_32 + +#define AS312_PIN 33 + +#define ENABLE_IP5306 + +#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 \ No newline at end of file diff --git a/examples/Camera/motion-snapshot-capture/motion-snapshot-capture.ino b/examples/Camera/motion-snapshot-capture/motion-snapshot-capture.ino new file mode 100644 index 0000000..2b1e52e --- /dev/null +++ b/examples/Camera/motion-snapshot-capture/motion-snapshot-capture.ino @@ -0,0 +1,300 @@ +/* + * Example for how to use SinricPro Camera device: + * - Create a ESP32 Camera device from portal. + * - Copy the secrets below. + * + * If you encounter any issues: + * - check the readme.md at https://github.com/sinricpro/esp8266-esp32-sdk/blob/master/README.md + * - ensure all dependent libraries are installed + * - see https://github.com/sinricpro/esp8266-esp32-sdk/blob/master/README.md#arduinoide + * - see https://github.com/sinricpro/esp8266-esp32-sdk/blob/master/README.md#dependencies + * - open serial monitor and check whats happening + * - check full user documentation at https://sinricpro.github.io/esp8266-esp32-sdk + * - visit https://github.com/sinricpro/esp8266-esp32-sdk/issues and check for existing issues or open a new one + */ + +// Uncomment the following line to enable serial debug output +#define ENABLE_DEBUG +#define SINRICPRO_CAMERA_URL "testcamera.sinric.pro" + +#include +#include +#include +#include +#include +#include + +// =================== +// 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_M5STACK_CAMS3_UNIT // Has PSRAM +// #define CAMERA_MODEL_AI_THINKER // Has PSRAM +// #define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM +// #define CAMERA_MODEL_TTGO_T_V16_VERSION +// #define CAMERA_MODEL_TTGO_T_V05_VERSION +// #define CAMERA_MODEL_TTGO_T_PLUS_VERSION +// #define CAMERA_MODEL_TTGO_T_V162_VERSION +// #define CAMERA_MODEL_TTGO_T_MINI_VERSION +// #define CAMERA_MODEL_TTGO_T_V17_VERSION + #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" +#include "motion_detector.h" + +#define WIFI_SSID "June" +#define WIFI_PASS "wifipassword" + +#define APP_KEY "7c7f0312-502e-4eba-a377-80fd599e79e7" // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx" +#define APP_SECRET "4bdc2144-f17b-463a-be32-600e6835b922-63bc1698-7c52-41f0-bcb5-a444528ba781" // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx" +#define CAMERA_ID "673bce6823cdb5c141975952" // Should look like "5dc1564130xxxxxxxxxxxxxx" + +// More sensitive to large moving objects +// #define BLOCK_THRESHOLD 40 // Require stronger pixel changes +// #define MOTION_THRESHOLD 15 // Require more blocks to change + +// More sensitive to mid moving objects +#define BLOCK_THRESHOLD 30 // Accept subtler pixel changes +#define MOTION_THRESHOLD 10 // Accept mid changed blocks + +// More sensitive to small moving objects +// #define BLOCK_THRESHOLD 20 // Accept subtler pixel changes +// #define MOTION_THRESHOLD 5 // Accept fewer changed blocks + +MotionDetector *motionDetector = nullptr; +bool motionDetected = false; + +// File to save the MJPEG +const char* motionFileName = "/motion.mjpeg"; +// Number of frames and delay between captures +#define NUM_FRAMES 5 +#define FRAME_DELAY 200 // in milliseconds + +bool onPowerState(const String &deviceId, bool &state) { + return true; +} + +// setup function for WiFi connection +void setupWiFi() { + Serial.printf("\r\n[Wifi]: Connecting"); + + WiFi.begin(WIFI_SSID, WIFI_PASS); + WiFi.setSleep(false); + + while (WiFi.status() != WL_CONNECTED) { + Serial.printf("."); + delay(250); + } + Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str()); +} + +void setupSinricPro() { + SinricProCamera &myCamera = SinricPro[CAMERA_ID]; + myCamera.onPowerState(onPowerState); + + SinricPro.onConnected([]() { + Serial.printf("Connected to SinricPro\r\n"); + }); + SinricPro.onDisconnected([]() { + Serial.printf("Disconnected from SinricPro\r\n"); + }); + + SinricPro.begin(APP_KEY, APP_SECRET, "testws.sinric.pro"); +} + +void setupCamera() { + Serial.printf("Setup Camera..\r\n"); + + camera_config_t config; + config.ledc_channel = LEDC_CHANNEL_0; + config.ledc_timer = LEDC_TIMER_0; + config.pin_d0 = Y2_GPIO_NUM; + config.pin_d1 = Y3_GPIO_NUM; + config.pin_d2 = Y4_GPIO_NUM; + config.pin_d3 = Y5_GPIO_NUM; + config.pin_d4 = Y6_GPIO_NUM; + config.pin_d5 = Y7_GPIO_NUM; + config.pin_d6 = Y8_GPIO_NUM; + config.pin_d7 = Y9_GPIO_NUM; + config.pin_xclk = XCLK_GPIO_NUM; + config.pin_pclk = PCLK_GPIO_NUM; + config.pin_vsync = VSYNC_GPIO_NUM; + config.pin_href = HREF_GPIO_NUM; + config.pin_sccb_sda = SIOD_GPIO_NUM; + config.pin_sccb_scl = SIOC_GPIO_NUM; + config.pin_pwdn = PWDN_GPIO_NUM; + config.pin_reset = RESET_GPIO_NUM; + config.xclk_freq_hz = 20000000; + config.pixel_format = PIXFORMAT_JPEG; + config.frame_size = FRAMESIZE_VGA; // https://github.com/espressif/esp32-camera/blob/master/driver/include/sensor.h#L98C5-L98C18 + config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; + config.fb_location = CAMERA_FB_IN_PSRAM; + config.jpeg_quality = 12; + config.fb_count = 1; + + if (psramFound()) { + config.fb_count = 2; + config.grab_mode = CAMERA_GRAB_LATEST; + } else { + Serial.println("Warnning! PSRAM not found!!!!"); + // Limit the frame size when PSRAM is not available + config.frame_size = FRAMESIZE_SVGA; + config.fb_location = CAMERA_FB_IN_DRAM; + } + + esp_err_t err = esp_camera_init(&config); + if (err != ESP_OK) { + Serial.printf("Camera init failed with error 0x%x", err); + return; + } + + Serial.printf("Camera Setup done!..\r\n"); +} + +void setupMotionDetection() { + MotionDetector::Config mdConfig = { + .width = 640, // VGA width + .height = 480, // VGA height + .blockSize = 16, // 16x16 pixel blocks + .blockThreshold = BLOCK_THRESHOLD, // Sensitivity to changes within blocks + .motionThreshold = MOTION_THRESHOLD, // Number of blocks that must change + .jpegQuality = 12 // JPEG quality setting + }; + + motionDetector = new MotionDetector(mdConfig); + if (!motionDetector->init()) { + Serial.println("Motion detector initialization failed!"); + return; + } +} + +void setup() { + Serial.begin(115200); + + // Initialize SPIFFS + if (!SPIFFS.begin(true)) { + Serial.println("Failed to mount SPIFFS"); + return; + } + + setupCamera(); + setupMotionDetection(); + setupWiFi(); + setupSinricPro(); +} + +std::vector createMJPEG(std::vector& frames) { + std::vector mjpegData; + + // MJPEG header + const char* mjpegHeader = "--boundary\r\nContent-Type: image/jpeg\r\n\r\n"; + + for (auto frame : frames) { + // Add boundary and headers + mjpegData.insert(mjpegData.end(), mjpegHeader, mjpegHeader + strlen(mjpegHeader)); + + // Add JPEG data + mjpegData.insert(mjpegData.end(), frame->buf, frame->buf + frame->len); + + Serial.printf("frame->len size: %d\r\n", frame->len); + + // Add newline + mjpegData.push_back('\r'); + mjpegData.push_back('\n'); + } + + return mjpegData; +} + +void captureAndSendFrames() { + std::vector frames; + + // Capture 5 frames + for (int i = 0; i < 5; i++) { + camera_fb_t* fb = esp_camera_fb_get(); + if (!fb) { + Serial.println("Camera capture failed"); + continue; + } + frames.push_back(fb); + delay(200); // Small delay between captures + } + + if (frames.size() > 0) { + // Create MJPEG data + std::vector mjpegData = createMJPEG(frames); + + Serial.printf("mjpegData size: %d\r\n", mjpegData.size()); + + SinricProCamera &myCamera = SinricPro[CAMERA_ID]; + int result = myCamera.sendMotion(mjpegData.data(), mjpegData.size()); + Serial.printf("Snapshot %s\r\n", result == 200 ? "sent!" : "send failed!"); + } + + // Free the frames + for (auto frame : frames) { + esp_camera_fb_return(frame); + } +} + +// void sendMotion() { +// SinricProCamera &myCamera = SinricPro[CAMERA_ID]; +// int result = myCamera.sendMotion(motionFileName); +// // 200 = Success +// // 429 = Too many requests +// // 400 = Format error +// // 500 = internal error +// Serial.printf("Motion %s\r\n", result == 200 ? "sent!" : "send failed!"); +// } + +void sendSnapshot(camera_fb_t *fb) { + SinricProCamera &myCamera = SinricPro[CAMERA_ID]; + int result = myCamera.sendSnapshot(fb->buf, fb->len); + // 200 = Success + // 429 = Too many requests + // 400 = Format error + // 500 = internal error + Serial.printf("Snapshot %s\r\n", result == 200 ? "sent!" : "send failed!"); +} + +void loop() { + SinricPro.handle(); + + camera_fb_t *fb = esp_camera_fb_get(); + if (!fb) { + Serial.println("Camera capture failed"); + return; + } + + if (motionDetector->detectMotion(fb)) { + if (!motionDetected) { + Serial.println("Motion detected!"); + motionDetected = true; + } + } else { + motionDetected = false; + } + + if (motionDetected) { + // sendSnapshot(fb); + + esp_camera_fb_return(fb); + captureAndSendFrames(); + } + + esp_camera_fb_return(fb); + + delay(100); +} \ No newline at end of file diff --git a/examples/Camera/motion-snapshot-capture/motion_detector.cpp b/examples/Camera/motion-snapshot-capture/motion_detector.cpp new file mode 100644 index 0000000..dcd14b4 --- /dev/null +++ b/examples/Camera/motion-snapshot-capture/motion_detector.cpp @@ -0,0 +1,139 @@ +#include "motion_detector.h" + +MotionDetector::MotionDetector(const Config& config) + : config_(config), + prevFrame_(nullptr), + currentFrame_(nullptr), + isInitialized_(false) { +} + +MotionDetector::~MotionDetector() { + if (isInitialized_) { + freeFrameBuffers(); + } +} + +bool MotionDetector::init() { + if (isInitialized_) { + return true; + } + + if (!allocateFrameBuffers()) { + Serial.println("Failed to allocate frame buffers"); + return false; + } + + isInitialized_ = true; + return true; +} + +void MotionDetector::reset() { + if (!isInitialized_) return; + + size_t frameSize = config_.width * config_.height * 2; // RGB565 = 2 bytes per pixel + if (prevFrame_) { + memset(prevFrame_, 0, frameSize); + } + if (currentFrame_) { + memset(currentFrame_, 0, frameSize); + } +} + +bool MotionDetector::allocateFrameBuffers() { + size_t frameSize = config_.width * config_.height * 2; // RGB565 = 2 bytes per pixel + + // Free any existing buffers first + freeFrameBuffers(); + + // Use MALLOC_CAP_SPIRAM for external RAM if available + prevFrame_ = (uint8_t*)heap_caps_malloc(frameSize, MALLOC_CAP_8BIT); + currentFrame_ = (uint8_t*)heap_caps_malloc(frameSize, MALLOC_CAP_8BIT); + + if (!prevFrame_ || !currentFrame_) { + freeFrameBuffers(); + return false; + } + + memset(prevFrame_, 0, frameSize); + memset(currentFrame_, 0, frameSize); + + return true; +} + +void MotionDetector::freeFrameBuffers() { + if (prevFrame_) { + heap_caps_free(prevFrame_); + prevFrame_ = nullptr; + } + if (currentFrame_) { + heap_caps_free(currentFrame_); + currentFrame_ = nullptr; + } +} + +bool MotionDetector::compareFrames() { + if (!isInitialized_ || !prevFrame_ || !currentFrame_) { + return false; + } + + int changedBlocks = 0; + int bytesPerPixel = 2; // RGB565 uses 2 bytes per pixel + + for (int y = 0; y < config_.height; y += config_.blockSize) { + for (int x = 0; x < config_.width; x += config_.blockSize) { + int diffSum = 0; + + // Compare blocks + for (int by = 0; by < config_.blockSize && (y + by) < config_.height; by++) { + for (int bx = 0; bx < config_.blockSize && (x + bx) < config_.width; bx++) { + int pos = ((y + by) * config_.width + (x + bx)) * bytesPerPixel; + + // Get RGB565 values + uint16_t current = (currentFrame_[pos + 1] << 8) | currentFrame_[pos]; + uint16_t prev = (prevFrame_[pos + 1] << 8) | prevFrame_[pos]; + + // Extract RGB components + uint8_t currentR = (current >> 11) & 0x1F; + uint8_t currentG = (current >> 5) & 0x3F; + uint8_t currentB = current & 0x1F; + + uint8_t prevR = (prev >> 11) & 0x1F; + uint8_t prevG = (prev >> 5) & 0x3F; + uint8_t prevB = prev & 0x1F; + + diffSum += abs(currentR - prevR); + diffSum += abs(currentG - prevG); + diffSum += abs(currentB - prevB); + } + } + + if (diffSum / (config_.blockSize * config_.blockSize) > config_.blockThreshold) { + changedBlocks++; + } + } + } + + if (changedBlocks > 0) { Serial.print(changedBlocks); Serial.println(" blocks changed!"); } + return changedBlocks > config_.motionThreshold; +} + +bool MotionDetector::jpegToRgb565(const uint8_t* jpegData, size_t jpegLen, uint8_t* outBuffer) { + return jpg2rgb565(jpegData, jpegLen, outBuffer, JPG_SCALE_NONE); +} + +bool MotionDetector::detectMotion(camera_fb_t* frame) { + if (!isInitialized_ || !frame || frame->format != PIXFORMAT_JPEG) { + return false; + } + + // Copy current frame to previous frame + memcpy(prevFrame_, currentFrame_, config_.width * config_.height * 2); + + // Convert new frame to RGB565 + if (!jpegToRgb565(frame->buf, frame->len, currentFrame_)) { + Serial.println("Failed to convert JPEG to RGB565"); + return false; + } + + return compareFrames(); +} \ No newline at end of file diff --git a/examples/Camera/motion-snapshot-capture/motion_detector.h b/examples/Camera/motion-snapshot-capture/motion_detector.h new file mode 100644 index 0000000..24c5c13 --- /dev/null +++ b/examples/Camera/motion-snapshot-capture/motion_detector.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include "esp_camera.h" +#include "img_converters.h" + +class MotionDetector { +public: + struct Config { + uint16_t width; + uint16_t height; + uint8_t blockSize; + uint8_t blockThreshold; + uint8_t motionThreshold; + uint8_t jpegQuality; + }; + + MotionDetector(const Config& config); + ~MotionDetector(); + + bool init(); + bool detectMotion(camera_fb_t* frame); + void reset(); + +private: + Config config_; + uint8_t* prevFrame_; // Previous frame in RGB565 format + uint8_t* currentFrame_; // Current frame in RGB565 format + bool isInitialized_; + + bool allocateFrameBuffers(); + void freeFrameBuffers(); + bool compareFrames(); + bool jpegToRgb565(const uint8_t* jpegData, size_t jpegLen, uint8_t* outBuffer); +}; diff --git a/examples/Camera/snapshot-camera/snapshot-camera.ino b/examples/Camera/snapshot-camera/snapshot-camera.ino index d457c69..c63325f 100644 --- a/examples/Camera/snapshot-camera/snapshot-camera.ino +++ b/examples/Camera/snapshot-camera/snapshot-camera.ino @@ -194,7 +194,6 @@ void setupCamera() { void setup() { Serial.begin(BAUD_RATE); - setupCamera(); setupWiFi(); setupSinricPro(); @@ -202,4 +201,4 @@ void setup() { void loop() { SinricPro.handle(); -} \ No newline at end of file +}