一、装ArduCam库和ESPAsyncWebServer库


二、参考代码
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#define CAM_CS 32 // modify according to your own wiring
#define OV2640_CHIPID_HIGH 0x0A
#define OV2640_CHIPID_LOW 0x0B
ArduCAM myCAM(OV2640, CAM_CS);
// Set your access point's SSID and password
const char* ssid = "...";  //wifi名 
const char* password = "....."; // 密码
AsyncWebServer server(80); // Create an instance of the server
// This function sends the live video frames to the client
void serverStream(AsyncWebServerRequest *request){
  AsyncWebServerResponse *response = request->beginResponse("multipart/x-mixed-replace;boundary=frame", HTTP_ANY, [](uint8_t *buffer, size_t maxLen, size_t alreadySent) -> size_t {
    if(myCAM.get_bit(ARDUCHIP_TRIG , CAP_DONE_MASK)){
	    size_t len = myCAM.read_fifo_length();
	    uint8_t * buf = (uint8_t *)malloc(len);
	    myCAM.CS_LOW();
	    myCAM.set_fifo_burst();
	    myCAM.spi_trans(0xFF);
	    myCAM.transferBytes(myCAM.camera_model,BUF,buf,len);
	    myCAM.CS_HIGH();
	    size_t available_len = len - (alreadySent ? 32 : 0);
	    size_t will_send =(available_len > maxLen) ? maxLen : available_len;
	    if (!alreadySent){ // First chunk
	      memcpy_P(buffer, buf, will_send);
	    } else { // Consequent chunks
	      buffer = buf + 32;
	    }
	    free(buf);
	    if (!alreadySent) {
	      return will_send;
	    } else if (alreadySent + will_send < len) {
	      return will_send;
	    } else {
	      myCAM.clear_fifo_flag();
	      return 0; // Last chunk sent, signaling end of response by returning 0 bytes left
	    }
	  }
	  return 0; // If there's nothing in the buffer, return 0 bytes left
  });
  response->addHeader("Connection", "close");
  request->send(response);
}
void setup() {
  Wire.begin(21, 22); // SDA, SCL
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
  myCAM.set_format(JPEG);
  myCAM.InitCAM();
  myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);   // VSYNC is active HIGH
  myCAM.clear_fifo_flag();
  myCAM.write_reg(ARDUCHIP_FRAMES, 0x00);
  
  server.on("/stream", HTTP_GET, serverStream); // Route for live video stream
  server.begin();
}
void loop() {
  // You can put other code here
}
 
三、硬件接线
OV2640 VCC(电源) --> ESP32 3.3V
OV2640 GND(地线) --> ESP32 GND
OV2640 SDA(数据线) --> ESP32 IO21(I2C数据线SDA)
OV2640 SCL(时钟线) --> ESP32 IO22(I2C时钟线SCL)
OV2640 VSNC(帧同步) --> ESP32 IO25
OV2640 HREF(行同步) --> ESP32 IO23
OV2640 PCLK(像素时钟) --> ESP32 IO19
OV2640 XCLK(系统时钟) --> ESP32 IO18
OV2640 D0~D7(数据线) --> ESP32 IO5~IO13(8位并行数据线)
四、反思
这个时候可能有细心的小伙伴发现了,一块ESP-WROOM-32开发板25元,一个OV2640模块23元,总计48元;而一块自带摄像头的ESP32CAM开发板只要41元。也就是说“ESP-WROOM-32+模块”的方案不仅难调通而且还亏损7元,那为什么不直接买一块ESP32CAM开发板呢?不要问我,因为我也才发现......




















