Arduino 当PIR传感器触发时,ESP32 cam保持重新启动

Arduino 当PIR传感器触发时,ESP32 cam保持重新启动,arduino,camera,esp32,Arduino,Camera,Esp32,所以一些背景-我有一个带PIR传感器的esp32摄像头。esp处于深度睡眠状态,然后被PIR传感器(GPIO 13)唤醒,esp拍摄图像。我想让它做的是再监视15秒的移动。如果有运动,它应该再拍一张照片等等。15秒后,esp应将照片发送到服务器(尚未到达此部分) 问题是,当唤醒后检测到运动时,摄像头无法初始化,esp自动重新启动 代码是 #include "esp_camera.h" #include "Arduino.h" #include "

所以一些背景-我有一个带PIR传感器的esp32摄像头。esp处于深度睡眠状态,然后被PIR传感器(GPIO 13)唤醒,esp拍摄图像。我想让它做的是再监视15秒的移动。如果有运动,它应该再拍一张照片等等。15秒后,esp应将照片发送到服务器(尚未到达此部分)

问题是,当唤醒后检测到运动时,摄像头无法初始化,esp自动重新启动

代码是

#include "esp_camera.h"
#include "Arduino.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memory
#include "DHT.h"               //Vir temperatuur sensor
#include <WiFi.h>"
#define EEPROM_SIZE 1
 
RTC_DATA_ATTR int bootCount = 0;

// Pin definition for 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
 
int pictureNumber = 0;

void initSDCard( void ) {

  if( !SD_MMC.begin() ) { // fast 4bit mode
    if( !SD_MMC.begin( "/sdcard", true ) ) { // slow 1bit mode
  Serial.println( "SD card init failed" );
    return;
    }
  }
}

void captureImage(void){
   Serial.setDebugOutput(true);
 
  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_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_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;
  
  pinMode(4, INPUT);
  digitalWrite(4, LOW);
  rtc_gpio_hold_dis(GPIO_NUM_4);
 
  if(psramFound()){
    config.frame_size = FRAMESIZE_VGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
 
  // Init Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
 
  Serial.println("Starting SD Card");
 
  delay(500);
 
  initSDCard(); //initialise SD card
   
  camera_fb_t * fb = NULL;
 
  // Take Picture with Camera
  fb = esp_camera_fb_get();  
  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }
  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureNumber = EEPROM.read(0) + 1;    //keeps count of picture number
 
  // Path where new picture will be saved in SD Card
  String path = "/picture" + String(pictureNumber) +".jpg";
 
  fs::FS &fs = SD_MMC;
  Serial.printf("Picture file name: %s\n", path.c_str());
 
  File file = fs.open(path.c_str(), FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file in writing mode");
  }
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
    EEPROM.write(0, pictureNumber);
    EEPROM.commit();
  }
  file.close();
  esp_camera_fb_return(fb);
  
  delay(1000);
  
  // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  rtc_gpio_hold_en(GPIO_NUM_4);
  }

void setup() {

WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);

 captureImage();

 int start = millis();
 int endtime = start;

 while(endtime - start <= 15000){
  
  int motion = digitalRead(13);

  if(motion == HIGH){
    Serial.println("Detected");

    captureImage();

    }
    
    else{
     Serial.println("No motion Detected");
     endtime = millis();
    }
  }

   esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, HIGH); //PIR sensor will trigger wake up from deep sleep.
  
   Serial.print("going to sleep");
  
   esp_deep_sleep_start();

   
}
 

void loop() {}
#包括“esp_camera.h”
#包括“Arduino.h”
#包括“FS.h”//SD卡ESP32
#包括“SDU MMC.h”//SD卡ESP32
#包括“soc/soc.h”//禁用断电问题
#包括“soc/rtc\u cntl\u reg.h”//禁用断电问题
#包括“驱动程序/rtc_io.h”
#包括//从闪存读取和写入
#包括“DHT.h”//Vir温度传感器
#包括“
#定义EEPROM_大小1
RTC_DATA_ATTR int bootCount=0;
//摄像头的针脚定义\u型号\u AI\u
#定义PWDN\u GPIO\u NUM 32
#定义RESET\u GPIO\u NUM-1
#定义XCLK\u GPIO\u NUM 0
#定义SIOD_GPIO_NUM 26
#定义SIOC_GPIO_数量27
#定义Y9_GPIO_数量35
#定义Y8_GPIO_数量34
#定义Y7_GPIO_数量39
#定义Y6_GPIO_数量36
#定义Y5_GPIO_NUM 21
#定义Y4_GPIO_数量19
#定义Y3_GPIO_数量18
#定义Y2\u GPIO\u数量5
#定义VSYNC\u GPIO\u NUM 25
#定义HREF\u GPIO\u NUM 23
#定义PCLK\U GPIO\U编号22
int pictureNumber=0;
无效初始化卡(无效){
如果(!SD_MMC.begin()){//快速4位模式
如果(!SD_MMC.begin(“/sdcard”,true)){//slow 1bit模式
Serial.println(“SD卡初始化失败”);
返回;
}
}
}
无效捕获图像(无效){
Serial.setDebugOutput(true);
摄像机配置;
config.ledc_channel=ledc_channel_0;
config.ledc_timer=ledc_timer_0;
config.pin\u d0=Y2\u GPIO\u 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\u xclk=xclk\u GPIO\u NUM;
config.pin\u pclk=pclk\u GPIO\u NUM;
config.pin\u vsync=vsync\u GPIO\u NUM;
config.pin_href=href_GPIO_NUM;
config.pin_sscb_sda=SIOD_GPIO_NUM;
config.pin_sscb_scl=SIOC_GPIO_NUM;
config.pin\u pwdn=pwdn\u GPIO\u NUM;
config.pin\u reset=reset\u GPIO\u NUM;
config.xclk_freq_hz=20000000;
config.pixel_format=PIXFORMAT_JPEG;
pinMode(4,输入);
数字写入(4,低);
rtc_gpio_hold_dis(gpio_NUM_4);
if(psramFound()){
config.frame_size=FRAMESIZE_VGA;//FRAMESIZE_+QVGA | CIF | VGA | SVGA | XGA | SXGA | UXGA
config.jpeg_quality=10;
config.fb_count=2;
}否则{
config.frame\u size=FRAMESIZE\u SVGA;
config.jpeg_quality=12;
config.fb_count=1;
}
//初始化照相机
esp_err_t err=esp_camera_init(&config);
如果(错误!=ESP_正常){
Serial.printf(“摄影机初始化失败,错误0x%x”,错误);
返回;
}
Serial.println(“启动SD卡”);
延迟(500);
initSDCard();//初始化SD卡
摄像头_fb_t*fb=NULL;
//照相
fb=esp_摄像头_fb_get();
如果(!fb){
Serial.println(“摄像头捕获失败”);
返回;
}
//使用预定义的大小初始化EEPROM
EEPROM.begin(EEPROM_大小);
pictureNumber=EEPROM.read(0)+1;//保持图片编号的计数
//新图片将保存在SD卡中的路径
String path=“/picture”+字符串(pictureNumber)+“.jpg”;
fs::fs&fs=SD\u MMC;
Serial.printf(“图片文件名:%s\n”,path.c_str());
File File=fs.open(path.c_str(),File_WRITE);
如果(!文件){
Serial.println(“未能以写入模式打开文件”);
}
否则{
file.write(fb->buf,fb->len);//有效载荷(image),有效载荷长度
Serial.printf(“将文件保存到路径:%s\n”,path.c_str());
EEPROM写入(0,PictureEnumber);
提交();
}
file.close();
esp_摄像头_fb_返回(fb);
延迟(1000);
//关闭连接到GPIO 4的ESP32-CAM白色车载LED(闪存)
pinMode(4,输出);
数字写入(4,低);
rtc_gpio_hold_en(gpio_NUM_4);
}
无效设置(){
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG,0);//禁用断电检测器
序列号开始(115200);
captureImage();
int start=millis();
int endtime=开始;

while(endtime-start根据头文件定义

  • 当前此函数只能调用一次,并且存在
  • 无法取消初始化此模块
esp_err_t esp_camera_init(const camera_config_t*config)

问题是摄像头芯片已经初始化,需要在唤醒后首先复位。并非所有型号都有复位引脚(摄像头模块)。
解决方案可以是

  • 如果存在重置引脚,则重置摄像头并再次初始化
  • 不要沉睡,只有光线
问题是,在运动检测和开始捕捉之间,您希望达到哪个延迟
如果短延迟很重要,则使用轻睡眠,如果不是,则可以使用上述解决方案或在写入EEPROM标志的情况下手动重新启动ESP。启动后,您可以立即根据头文件定义根据EEPROM标志开始捕获

  • 当前此函数只能调用一次,并且存在
  • 无法取消初始化此模块
esp_err_t esp_camera_init(const camera_config_t*config)

问题是摄像头芯片已经初始化,需要在唤醒后首先复位。并非所有型号都有复位引脚(摄像头模块)。
解决方案可以是

  • 如果存在重置引脚,则重置摄像头并再次初始化
  • 不要沉睡,只有光线
问题是,在运动检测和开始捕捉之间,您希望达到哪个延迟 如果短延迟很重要,则使用轻睡眠,如果不是,则1-2秒为acc