一、装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开发板呢?不要问我,因为我也才发现......