ESP32 之 esp32-cam wifi拍照传图系统

ESP32 之 esp32-cam wifi拍照传图系统

1.效果演示

在这里插入图片描述在这里插入图片描述

2.材料准备

  1. ESP32-cam
  2. USB转TTL
  3. 按钮x2 开关x2

3.原理图接线

GND - GND
TX - RX
RX - TX
VCC - 5V
GPIO_0 - GND 下载模式
GPIO_0 不接线 运行模式

4.下载代码

  1. 需要提前搭建Arduino环境,在这就不多说,在这里要注意安装好程序相关的库
    在这里插入图片描述
    代码下载,主函数代码如下
#include "camera_pins.h"

// 你的wifi账号密码
const char* ssid     = "DY";
const char* password = "1403119048";

// 在端口80上创建AsyncWebServer对象
AsyncWebServer server(80);

boolean takeNewPhoto = false;
bool LED_flag = false;

void setup() {
  Serial.begin(115200);         //串口初始化
  
  pinMode(LED_1, OUTPUT);       //初始化 LED
  pinMode(KEY_1, INPUT);        //按键1初始化
  pinMode(KEY_2, INPUT);        //按键2初始化
  
  WiFi.begin(ssid, password);   //连接wifi
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  
  if (!SPIFFS.begin(true)) {   //初始化SPIFFS
    Serial.println("An Error has occurred while mounting SPIFFS");
    ESP.restart();}
  else {
    delay(500);
    Serial.println("SPIFFS mounted successfully");
  }

  //Turn-off the 'brownout detector'
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

  // Camera initOV2640 camera module
  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;
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    ESP.restart();
  }

  // 路由主页   
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });
  //路由抓拍
  server.on("/capture", HTTP_GET, [](AsyncWebServerRequest * request) {
    takeNewPhoto = true;
    request->send_P(200, "text/plain", "Taking Photo");
  });
  //
  server.on("/saved-photo", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, FILE_PHOTO, "image/jpg", false);
  });
  //路由控制LED开关
  server.on("/LED", HTTP_GET, [](AsyncWebServerRequest * request) {
    LED_flag =!LED_flag;
    digitalWrite(LED_1, LED_flag);
  });
  // 启动服务器
  server.begin();
  Serial.print("IP Address: http://");  //打印IP地址用于服务器连接
  Serial.println(WiFi.localIP());
}

void loop() {
  //判断是否抓拍
  if (takeNewPhoto) {
    capturePhotoSaveSpiffs();
    takeNewPhoto = false;
  }
  
 //串口接收指令
  while(Serial.available()){
    char c=Serial.read();
    if(c=='1'){//开关LED
      LED_flag =!LED_flag;
      digitalWrite(LED_1, LED_flag);
      Serial.write("1\n");//返回到调试程序上
    }
    else if(c=='2') {//拍照
      takeNewPhoto = true;
      Serial.write("2\n");//返回到调试程序上
    }
  }

  //=====按键扫描=====
  int key_val = KEY_Scan();
  
  if(key_val == 1){       //按键1按下
    digitalWrite(LED_1, HIGH);
    takeNewPhoto = true;
    delay(500);
    digitalWrite(LED_1, LOW);                                             
  }
  if(key_val == 2){       //按键2按下
    LED_flag =!LED_flag;
    digitalWrite(LED_1, LED_flag);                                           
  }
  
  delay(1);
}

// 检查照片捕获是否成功
bool checkPhoto( fs::FS &fs ) {
  File f_pic = fs.open( FILE_PHOTO );
  unsigned int pic_sz = f_pic.size();
  return ( pic_sz > 100 );
}

// 捕捉照片并保存到SPIFFS
void capturePhotoSaveSpiffs( void ) {
  camera_fb_t * fb = NULL; // pointer
  bool ok = 0; // 布尔值指示图片是否被正确拍摄
  do {
    // 用照相机拍照
    Serial.println("Taking a photo...");
    fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Camera capture failed");
      return;
    }
      
    //照片文件名称
    Serial.printf("Picture file name: %s\n", FILE_PHOTO);
    File file = SPIFFS.open(FILE_PHOTO, 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.print("The picture has been saved in ");
      Serial.print(FILE_PHOTO);
      Serial.print(" - Size: ");
      Serial.print(file.size());
      Serial.println(" bytes");
    }
    // 关闭文件
    file.close();
    esp_camera_fb_return(fb);

    // 检查文件是否正确地保存在SPIFFS中
    ok = checkPhoto(SPIFFS);
  } while ( !ok );
  //将文件保存到SD卡当中
}
//按键扫描
int KEY_Scan(void)
{   
  static int key_up = 1;//按键按松开标志   
  if(key_up && (digitalRead(KEY_1) == 0 || digitalRead(KEY_2) == 0 ))
  {
    delay(10);//去抖动 
    key_up=0;
    if(digitalRead(KEY_1) == 0)return 1;
    if(digitalRead(KEY_2) == 0)return 2;
  }else if( digitalRead(KEY_1) == 1 || digitalRead(KEY_2) == 1)key_up=1;       
  return 0; // 无按键按下
}
发布了23 篇原创文章 · 获赞 8 · 访问量 2009

猜你喜欢

转载自blog.csdn.net/qq_39610398/article/details/103596759